]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genattrtab.c
aclocal.m4 (libiberty_AC_FUNC_C_ALLOCA): New.
[thirdparty/gcc.git] / gcc / genattrtab.c
CommitLineData
41299f41 1/* Generate code from machine description to compute values of attributes.
d050d723
JL
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
9e1b6503 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
41299f41
TW
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 2, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
a35311b0
RK
20the Free Software Foundation, 59 Temple Place - Suite 330,
21Boston, MA 02111-1307, USA. */
41299f41 22
6dc42e49 23/* This program handles insn attributes and the DEFINE_DELAY and
41299f41
TW
24 DEFINE_FUNCTION_UNIT definitions.
25
3e7b5313 26 It produces a series of functions named `get_attr_...', one for each insn
41299f41
TW
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
29
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
34 expression).
35
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
0eadeb15 38 an operand is found, `extract_insn' is called.
41299f41 39
c9541287 40 The special attribute `length' is also recognized. For this operand,
41299f41
TW
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
47 `get_attr_length'.
48
3e7b5313
TW
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
54 used.
c9541287 55
41299f41
TW
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
58
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
62
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
67
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
72
73 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
74 definitions is to create arbitrarily complex expressions and have the
75 optimization simplify them.
76
77 Once optimization is complete, any required routines and definitions
3e7b5313
TW
78 will be written.
79
80 An optimization that is not yet implemented is to hoist the constant
81 expressions entirely out of the routines and definitions that are written.
82 A way to do this is to iterate over all possible combinations of values
83 for constant attributes and generate a set of functions for that given
84 combination. An initialization function would be written that evaluates
85 the attributes and installs the corresponding set of routines and
3715a518
RS
86 definitions (each would be accessed through a pointer).
87
88 We use the flags in an RTX as follows:
89 `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified
90 independent of the insn code.
91 `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
92 for the insn code currently being processed (see optimize_attrs).
93 `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
72f1215c
TW
94 (see attr_rtx).
95 `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
96 EQ_ATTR rtx is true if !volatil and false if volatil. */
3715a518 97
0d64891c 98#include "hconfig.h"
0b93b64e 99#include "system.h"
41299f41 100#include "rtl.h"
a3770a81 101#include "ggc.h"
c88c0d42 102#include "gensupport.h"
41299f41 103
956d6950
JL
104#ifdef HAVE_SYS_RESOURCE_H
105# include <sys/resource.h>
f0cdf2b2
RK
106#endif
107
31f0534c
RS
108/* We must include obstack.h after <sys/time.h>, to avoid lossage with
109 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
110#include "obstack.h"
f8b6598e 111#include "errors.h"
31f0534c 112
3916d6d8 113static struct obstack obstack1, obstack2;
7339c88d 114struct obstack *hash_obstack = &obstack1;
81fd4c6e 115struct obstack *temp_obstack = &obstack2;
41299f41
TW
116
117#define obstack_chunk_alloc xmalloc
118#define obstack_chunk_free free
119
0e9414fd
MM
120/* enough space to reserve for printing out ints */
121#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
122
41299f41
TW
123/* Define structures used to record attributes and values. */
124
125/* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
126 encountered, we store all the relevant information into a
127 `struct insn_def'. This is done to allow attribute definitions to occur
128 anywhere in the file. */
129
130struct insn_def
131{
0f41302f
MS
132 struct insn_def *next; /* Next insn in chain. */
133 rtx def; /* The DEFINE_... */
a4cad544
RH
134 int insn_code; /* Instruction number. */
135 int insn_index; /* Expression numer in file, for errors. */
136 int lineno; /* Line number. */
41299f41 137 int num_alternatives; /* Number of alternatives. */
0f41302f 138 int vec_idx; /* Index of attribute vector in `def'. */
41299f41
TW
139};
140
141/* Once everything has been read in, we store in each attribute value a list
142 of insn codes that have that value. Here is the structure used for the
143 list. */
144
145struct insn_ent
146{
a4cad544 147 struct insn_ent *next; /* Next in chain. */
41299f41
TW
148 int insn_code; /* Instruction number. */
149 int insn_index; /* Index of definition in file */
a4cad544 150 int lineno; /* Line number. */
41299f41
TW
151};
152
153/* Each value of an attribute (either constant or computed) is assigned a
154 structure which is used as the listhead of the insns that have that
155 value. */
156
157struct attr_value
158{
159 rtx value; /* Value of attribute. */
160 struct attr_value *next; /* Next attribute value in chain. */
161 struct insn_ent *first_insn; /* First insn with this value. */
162 int num_insns; /* Number of insns with this value. */
163 int has_asm_insn; /* True if this value used for `asm' insns */
164};
165
166/* Structure for each attribute. */
167
168struct attr_desc
169{
0f41302f
MS
170 char *name; /* Name of attribute. */
171 struct attr_desc *next; /* Next attribute. */
6f6074ea
MM
172 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
173 unsigned negative_ok : 1; /* Allow negative numeric values. */
174 unsigned unsigned_p : 1; /* Make the output function unsigned int. */
175 unsigned is_const : 1; /* Attribute value constant for each run. */
176 unsigned is_special : 1; /* Don't call `write_attr_set'. */
177 unsigned func_units_p : 1; /* this is the function_units attribute */
178 unsigned blockage_p : 1; /* this is the blockage range function */
0f41302f
MS
179 struct attr_value *first_value; /* First value of this attribute. */
180 struct attr_value *default_val; /* Default value for this attribute. */
a4cad544 181 int lineno; /* Line number. */
41299f41
TW
182};
183
3d678dca
RS
184#define NULL_ATTR (struct attr_desc *) NULL
185
bee757e1
TW
186/* A range of values. */
187
188struct range
189{
190 int min;
191 int max;
192};
193
41299f41
TW
194/* Structure for each DEFINE_DELAY. */
195
196struct delay_desc
197{
198 rtx def; /* DEFINE_DELAY expression. */
0f41302f 199 struct delay_desc *next; /* Next DEFINE_DELAY. */
41299f41 200 int num; /* Number of DEFINE_DELAY, starting at 1. */
a4cad544 201 int lineno; /* Line number. */
41299f41
TW
202};
203
204/* Record information about each DEFINE_FUNCTION_UNIT. */
205
206struct function_unit_op
207{
208 rtx condexp; /* Expression TRUE for applicable insn. */
209 struct function_unit_op *next; /* Next operation for this function unit. */
210 int num; /* Ordinal for this operation type in unit. */
211 int ready; /* Cost until data is ready. */
bee757e1
TW
212 int issue_delay; /* Cost until unit can accept another insn. */
213 rtx conflict_exp; /* Expression TRUE for insns incurring issue delay. */
214 rtx issue_exp; /* Expression computing issue delay. */
a4cad544 215 int lineno; /* Line number. */
41299f41
TW
216};
217
218/* Record information about each function unit mentioned in a
219 DEFINE_FUNCTION_UNIT. */
220
221struct function_unit
222{
3cce094d 223 const char *name; /* Function unit name. */
41299f41
TW
224 struct function_unit *next; /* Next function unit. */
225 int num; /* Ordinal of this unit type. */
226 int multiplicity; /* Number of units of this type. */
227 int simultaneity; /* Maximum number of simultaneous insns
228 on this function unit or 0 if unlimited. */
0f41302f 229 rtx condexp; /* Expression TRUE for insn needing unit. */
41299f41
TW
230 int num_opclasses; /* Number of different operation types. */
231 struct function_unit_op *ops; /* Pointer to first operation type. */
232 int needs_conflict_function; /* Nonzero if a conflict function required. */
bee757e1 233 int needs_blockage_function; /* Nonzero if a blockage function required. */
f75d38a7 234 int needs_range_function; /* Nonzero if blockage range function needed.*/
41299f41 235 rtx default_cost; /* Conflict cost, if constant. */
bee757e1
TW
236 struct range issue_delay; /* Range of issue delay values. */
237 int max_blockage; /* Maximum time an insn blocks the unit. */
a4cad544 238 int first_lineno; /* First seen line number. */
41299f41
TW
239};
240
241/* Listheads of above structures. */
242
3715a518
RS
243/* This one is indexed by the first character of the attribute name. */
244#define MAX_ATTRS_INDEX 256
245static struct attr_desc *attrs[MAX_ATTRS_INDEX];
41299f41
TW
246static struct insn_def *defs;
247static struct delay_desc *delays;
248static struct function_unit *units;
249
f75d38a7
RK
250/* An expression where all the unknown terms are EQ_ATTR tests can be
251 rearranged into a COND provided we can enumerate all possible
252 combinations of the unknown values. The set of combinations become the
253 tests of the COND; the value of the expression given that combination is
254 computed and becomes the corresponding value. To do this, we must be
255 able to enumerate all values for each attribute used in the expression
256 (currently, we give up if we find a numeric attribute).
c9541287 257
f75d38a7
RK
258 If the set of EQ_ATTR tests used in an expression tests the value of N
259 different attributes, the list of all possible combinations can be made
260 by walking the N-dimensional attribute space defined by those
261 attributes. We record each of these as a struct dimension.
262
263 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
264 expression are the same, the will also have the same address. We find
265 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
266 represents the value of an EQ_ATTR node, so once all nodes are marked,
267 they are also given an initial value of FALSE.
268
269 We then separate the set of EQ_ATTR nodes into dimensions for each
270 attribute and put them on the VALUES list. Terms are added as needed by
271 `add_values_to_cover' so that all possible values of the attribute are
272 tested.
273
274 Each dimension also has a current value. This is the node that is
275 currently considered to be TRUE. If this is one of the nodes added by
276 `add_values_to_cover', all the EQ_ATTR tests in the original expression
277 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
278
279 NUM_VALUES is simply the length of the VALUES list and is there for
280 convenience.
281
282 Once the dimensions are created, the algorithm enumerates all possible
283 values and computes the current value of the given expression. */
284
c9541287 285struct dimension
f75d38a7
RK
286{
287 struct attr_desc *attr; /* Attribute for this dimension. */
288 rtx values; /* List of attribute values used. */
289 rtx current_value; /* Position in the list for the TRUE value. */
290 int num_values; /* Length of the values list. */
291};
292
0f41302f 293/* Other variables. */
41299f41
TW
294
295static int insn_code_number;
296static int insn_index_number;
297static int got_define_asm_attributes;
298static int must_extract;
299static int must_constrain;
300static int address_used;
d7c665bf 301static int length_used;
41299f41
TW
302static int num_delays;
303static int have_annul_true, have_annul_false;
71d9b493 304static int num_units, num_unit_opclasses;
1c69865d 305static int num_insn_ents;
41299f41
TW
306
307/* Used as operand to `operate_exp': */
308
71d9b493 309enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
41299f41 310
3715a518
RS
311/* Stores, for each insn code, the number of constraint alternatives. */
312
313static int *insn_n_alternatives;
314
41299f41
TW
315/* Stores, for each insn code, a bitmap that has bits on for each possible
316 alternative. */
317
318static int *insn_alternatives;
319
3715a518
RS
320/* If nonzero, assume that the `alternative' attr has this value.
321 This is the hashed, unique string for the numeral
322 whose value is chosen alternative. */
323
3cce094d 324static const char *current_alternative_string;
3715a518 325
41299f41
TW
326/* Used to simplify expressions. */
327
328static rtx true_rtx, false_rtx;
329
330/* Used to reduce calls to `strcmp' */
331
81fd4c6e 332static char *alternative_name;
41299f41 333
21ca87b8
MS
334/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
335 called. */
336
337int reload_completed = 0;
338
9ec36da5
JL
339/* Some machines test `optimize' in macros called from rtlanal.c, so we need
340 to define it here. */
341
c5afbb49
JL
342int optimize = 0;
343
41299f41
TW
344/* Simplify an expression. Only call the routine if there is something to
345 simplify. */
346#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
3715a518 347 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
41299f41 348 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
c9541287 349
3715a518
RS
350/* Simplify (eq_attr ("alternative") ...)
351 when we are working with a particular alternative. */
352#define SIMPLIFY_ALTERNATIVE(EXP) \
353 if (current_alternative_string \
354 && GET_CODE ((EXP)) == EQ_ATTR \
355 && XSTR ((EXP), 0) == alternative_name) \
356 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
357 ? true_rtx : false_rtx);
358
41299f41
TW
359/* These are referenced by rtlanal.c and hence need to be defined somewhere.
360 They won't actually be used. */
361
5da077de 362rtx global_rtl[GR_MAX];
e5e809f4 363rtx pic_offset_table_rtx;
41299f41 364
a94ae8f5
KG
365static void attr_hash_add_rtx PARAMS ((int, rtx));
366static void attr_hash_add_string PARAMS ((int, char *));
367static rtx attr_rtx PARAMS ((enum rtx_code, ...));
368static char *attr_printf PARAMS ((int, const char *, ...))
85fda1eb 369 ATTRIBUTE_PRINTF_2;
a94ae8f5 370static char *attr_string PARAMS ((const char *, int));
a4cad544 371static rtx check_attr_test PARAMS ((rtx, int, int));
a94ae8f5 372static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
a4cad544
RH
373static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
374static rtx convert_set_attr PARAMS ((rtx, struct insn_def *));
a94ae8f5 375static void check_defs PARAMS ((void));
71d9b493 376#if 0
a94ae8f5 377static rtx convert_const_symbol_ref PARAMS ((rtx, struct attr_desc *));
71d9b493 378#endif
a94ae8f5
KG
379static rtx make_canonical PARAMS ((struct attr_desc *, rtx));
380static struct attr_value *get_attr_value PARAMS ((rtx, struct attr_desc *, int));
381static rtx copy_rtx_unchanging PARAMS ((rtx));
382static rtx copy_boolean PARAMS ((rtx));
383static void expand_delays PARAMS ((void));
384static rtx operate_exp PARAMS ((enum operator, rtx, rtx));
385static void expand_units PARAMS ((void));
386static rtx simplify_knowing PARAMS ((rtx, rtx));
387static rtx encode_units_mask PARAMS ((rtx));
388static void fill_attr PARAMS ((struct attr_desc *));
5836dc64 389/* dpx2 compiler chokes if we specify the arg types of the args. */
a94ae8f5
KG
390static rtx substitute_address PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
391static void make_length_attrs PARAMS ((void));
392static rtx identity_fn PARAMS ((rtx));
393static rtx zero_fn PARAMS ((rtx));
394static rtx one_fn PARAMS ((rtx));
395static rtx max_fn PARAMS ((rtx));
396static void write_length_unit_log PARAMS ((void));
397static rtx simplify_cond PARAMS ((rtx, int, int));
e9a25f70 398#if 0
a94ae8f5 399static rtx simplify_by_alternatives PARAMS ((rtx, int, int));
e9a25f70 400#endif
a94ae8f5
KG
401static rtx simplify_by_exploding PARAMS ((rtx));
402static int find_and_mark_used_attributes PARAMS ((rtx, rtx *, int *));
403static void unmark_used_attributes PARAMS ((rtx, struct dimension *, int));
404static int add_values_to_cover PARAMS ((struct dimension *));
405static int increment_current_value PARAMS ((struct dimension *, int));
406static rtx test_for_current_value PARAMS ((struct dimension *, int));
407static rtx simplify_with_current_value PARAMS ((rtx, struct dimension *, int));
408static rtx simplify_with_current_value_aux PARAMS ((rtx));
409static void clear_struct_flag PARAMS ((rtx));
410static int count_sub_rtxs PARAMS ((rtx, int));
411static void remove_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
412static void insert_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
413static rtx insert_right_side PARAMS ((enum rtx_code, rtx, rtx, int, int));
414static rtx make_alternative_compare PARAMS ((int));
415static int compute_alternative_mask PARAMS ((rtx, enum rtx_code));
416static rtx evaluate_eq_attr PARAMS ((rtx, rtx, int, int));
417static rtx simplify_and_tree PARAMS ((rtx, rtx *, int, int));
418static rtx simplify_or_tree PARAMS ((rtx, rtx *, int, int));
419static rtx simplify_test_exp PARAMS ((rtx, int, int));
420static void optimize_attrs PARAMS ((void));
a4cad544 421static void gen_attr PARAMS ((rtx, int));
a94ae8f5
KG
422static int count_alternatives PARAMS ((rtx));
423static int compares_alternatives_p PARAMS ((rtx));
424static int contained_in_p PARAMS ((rtx, rtx));
a4cad544
RH
425static void gen_insn PARAMS ((rtx, int));
426static void gen_delay PARAMS ((rtx, int));
427static void gen_unit PARAMS ((rtx, int));
a94ae8f5
KG
428static void write_test_expr PARAMS ((rtx, int));
429static int max_attr_value PARAMS ((rtx, int*));
430static int or_attr_value PARAMS ((rtx, int*));
431static void walk_attr_value PARAMS ((rtx));
432static void write_attr_get PARAMS ((struct attr_desc *));
433static rtx eliminate_known_true PARAMS ((rtx, rtx, int, int));
434static void write_attr_set PARAMS ((struct attr_desc *, int, rtx,
85fda1eb
KG
435 const char *, const char *, rtx,
436 int, int));
a94ae8f5 437static void write_attr_case PARAMS ((struct attr_desc *, struct attr_value *,
85fda1eb 438 int, const char *, const char *, int, rtx));
a94ae8f5 439static void write_unit_name PARAMS ((const char *, int, const char *));
3cce094d 440static void write_attr_valueq PARAMS ((struct attr_desc *, const char *));
a94ae8f5
KG
441static void write_attr_value PARAMS ((struct attr_desc *, rtx));
442static void write_upcase PARAMS ((const char *));
443static void write_indent PARAMS ((int));
444static void write_eligible_delay PARAMS ((const char *));
445static void write_function_unit_info PARAMS ((void));
446static void write_complex_function PARAMS ((struct function_unit *, const char *,
85fda1eb 447 const char *));
a94ae8f5
KG
448static int write_expr_attr_cache PARAMS ((rtx, struct attr_desc *));
449static void write_toplevel_expr PARAMS ((rtx));
450static void write_const_num_delay_slots PARAMS ((void));
3cce094d
KG
451static int n_comma_elts PARAMS ((const char *));
452static char *next_comma_elt PARAMS ((const char **));
a94ae8f5
KG
453static struct attr_desc *find_attr PARAMS ((const char *, int));
454static void make_internal_attr PARAMS ((const char *, rtx, int));
455static struct attr_value *find_most_used PARAMS ((struct attr_desc *));
456static rtx find_single_value PARAMS ((struct attr_desc *));
457static rtx make_numeric_value PARAMS ((int));
458static void extend_range PARAMS ((struct range *, int, int));
3cce094d
KG
459static rtx attr_eq PARAMS ((const char *, const char *));
460static const char *attr_numeral PARAMS ((int));
a94ae8f5
KG
461static int attr_equal_p PARAMS ((rtx, rtx));
462static rtx attr_copy_rtx PARAMS ((rtx));
2bed3391 463static int attr_rtx_cost PARAMS ((rtx));
0e9414fd
MM
464
465#define oballoc(size) obstack_alloc (hash_obstack, size)
41299f41 466\f
3e7b5313
TW
467/* Hash table for sharing RTL and strings. */
468
469/* Each hash table slot is a bucket containing a chain of these structures.
470 Strings are given negative hash codes; RTL expressions are given positive
471 hash codes. */
472
473struct attr_hash
474{
475 struct attr_hash *next; /* Next structure in the bucket. */
476 int hashcode; /* Hash code of this rtx or string. */
477 union
478 {
479 char *str; /* The string (negative hash codes) */
480 rtx rtl; /* or the RTL recorded here. */
481 } u;
482};
483
484/* Now here is the hash table. When recording an RTL, it is added to
485 the slot whose index is the hash code mod the table size. Note
486 that the hash table is used for several kinds of RTL (see attr_rtx)
487 and for strings. While all these live in the same table, they are
488 completely independent, and the hash code is computed differently
489 for each. */
490
491#define RTL_HASH_SIZE 4093
492struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
493
494/* Here is how primitive or already-shared RTL's hash
495 codes are made. */
2e0dd623 496#define RTL_HASH(RTL) ((long) (RTL) & 0777777)
3e7b5313
TW
497
498/* Add an entry to the hash table for RTL with hash code HASHCODE. */
499
500static void
501attr_hash_add_rtx (hashcode, rtl)
502 int hashcode;
503 rtx rtl;
504{
505 register struct attr_hash *h;
506
7339c88d
RS
507 h = (struct attr_hash *) obstack_alloc (hash_obstack,
508 sizeof (struct attr_hash));
3e7b5313
TW
509 h->hashcode = hashcode;
510 h->u.rtl = rtl;
511 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
512 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
513}
514
515/* Add an entry to the hash table for STRING with hash code HASHCODE. */
516
517static void
518attr_hash_add_string (hashcode, str)
519 int hashcode;
520 char *str;
521{
522 register struct attr_hash *h;
523
7339c88d
RS
524 h = (struct attr_hash *) obstack_alloc (hash_obstack,
525 sizeof (struct attr_hash));
3e7b5313
TW
526 h->hashcode = -hashcode;
527 h->u.str = str;
528 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
529 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
530}
531
81fd4c6e
RS
532/* Generate an RTL expression, but avoid duplicates.
533 Set the RTX_INTEGRATED_P flag for these permanent objects.
534
535 In some cases we cannot uniquify; then we return an ordinary
536 impermanent rtx with RTX_INTEGRATED_P clear.
537
538 Args are like gen_rtx, but without the mode:
3e7b5313
TW
539
540 rtx attr_rtx (code, [element1, ..., elementn]) */
541
3e7b5313 542static rtx
a94ae8f5 543attr_rtx VPARAMS ((enum rtx_code code, ...))
3e7b5313 544{
5148a72b 545#ifndef ANSI_PROTOTYPES
3e7b5313 546 enum rtx_code code;
9e1b6503
RK
547#endif
548 va_list p;
3e7b5313 549 register int i; /* Array indices... */
a544cfd2
KG
550 register const char *fmt; /* Current rtx's format... */
551 register rtx rt_val = NULL_RTX;/* RTX to return to caller... */
3e7b5313
TW
552 int hashcode;
553 register struct attr_hash *h;
7339c88d 554 struct obstack *old_obstack = rtl_obstack;
3e7b5313 555
9e1b6503
RK
556 VA_START (p, code);
557
5148a72b 558#ifndef ANSI_PROTOTYPES
3e7b5313 559 code = va_arg (p, enum rtx_code);
9e1b6503 560#endif
3e7b5313
TW
561
562 /* For each of several cases, search the hash table for an existing entry.
563 Use that entry if one is found; otherwise create a new RTL and add it
564 to the table. */
565
566 if (GET_RTX_CLASS (code) == '1')
567 {
568 rtx arg0 = va_arg (p, rtx);
569
81fd4c6e
RS
570 /* A permanent object cannot point to impermanent ones. */
571 if (! RTX_INTEGRATED_P (arg0))
572 {
573 rt_val = rtx_alloc (code);
574 XEXP (rt_val, 0) = arg0;
575 va_end (p);
576 return rt_val;
577 }
578
d98c1e33 579 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
3e7b5313
TW
580 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
581 if (h->hashcode == hashcode
582 && GET_CODE (h->u.rtl) == code
583 && XEXP (h->u.rtl, 0) == arg0)
584 goto found;
585
586 if (h == 0)
587 {
7339c88d 588 rtl_obstack = hash_obstack;
3e7b5313
TW
589 rt_val = rtx_alloc (code);
590 XEXP (rt_val, 0) = arg0;
591 }
592 }
593 else if (GET_RTX_CLASS (code) == 'c'
594 || GET_RTX_CLASS (code) == '2'
595 || GET_RTX_CLASS (code) == '<')
596 {
597 rtx arg0 = va_arg (p, rtx);
598 rtx arg1 = va_arg (p, rtx);
599
81fd4c6e
RS
600 /* A permanent object cannot point to impermanent ones. */
601 if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
602 {
603 rt_val = rtx_alloc (code);
604 XEXP (rt_val, 0) = arg0;
605 XEXP (rt_val, 1) = arg1;
606 va_end (p);
607 return rt_val;
608 }
609
d98c1e33 610 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
3e7b5313
TW
611 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
612 if (h->hashcode == hashcode
613 && GET_CODE (h->u.rtl) == code
614 && XEXP (h->u.rtl, 0) == arg0
615 && XEXP (h->u.rtl, 1) == arg1)
616 goto found;
617
618 if (h == 0)
619 {
7339c88d 620 rtl_obstack = hash_obstack;
3e7b5313
TW
621 rt_val = rtx_alloc (code);
622 XEXP (rt_val, 0) = arg0;
623 XEXP (rt_val, 1) = arg1;
624 }
625 }
626 else if (GET_RTX_LENGTH (code) == 1
627 && GET_RTX_FORMAT (code)[0] == 's')
628 {
770ae6cc 629 char *arg0 = va_arg (p, char *);
3e7b5313 630
81fd4c6e
RS
631 if (code == SYMBOL_REF)
632 arg0 = attr_string (arg0, strlen (arg0));
633
d98c1e33 634 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
3e7b5313
TW
635 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
636 if (h->hashcode == hashcode
637 && GET_CODE (h->u.rtl) == code
638 && XSTR (h->u.rtl, 0) == arg0)
639 goto found;
640
641 if (h == 0)
642 {
7339c88d 643 rtl_obstack = hash_obstack;
3e7b5313
TW
644 rt_val = rtx_alloc (code);
645 XSTR (rt_val, 0) = arg0;
646 }
647 }
648 else if (GET_RTX_LENGTH (code) == 2
649 && GET_RTX_FORMAT (code)[0] == 's'
650 && GET_RTX_FORMAT (code)[1] == 's')
651 {
81fd4c6e
RS
652 char *arg0 = va_arg (p, char *);
653 char *arg1 = va_arg (p, char *);
3e7b5313 654
d98c1e33 655 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
3e7b5313
TW
656 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
657 if (h->hashcode == hashcode
658 && GET_CODE (h->u.rtl) == code
659 && XSTR (h->u.rtl, 0) == arg0
660 && XSTR (h->u.rtl, 1) == arg1)
661 goto found;
662
663 if (h == 0)
664 {
7339c88d 665 rtl_obstack = hash_obstack;
3e7b5313
TW
666 rt_val = rtx_alloc (code);
667 XSTR (rt_val, 0) = arg0;
668 XSTR (rt_val, 1) = arg1;
669 }
670 }
81fd4c6e
RS
671 else if (code == CONST_INT)
672 {
3d678dca 673 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
81fd4c6e 674 if (arg0 == 0)
f0305a2b
KG
675 {
676 va_end (p);
677 return false_rtx;
678 }
81fd4c6e 679 if (arg0 == 1)
f0305a2b
KG
680 {
681 va_end (p);
682 return true_rtx;
683 }
81fd4c6e
RS
684 goto nohash;
685 }
3e7b5313
TW
686 else
687 {
81fd4c6e 688 nohash:
3e7b5313 689 rt_val = rtx_alloc (code); /* Allocate the storage space. */
c9541287 690
3e7b5313
TW
691 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
692 for (i = 0; i < GET_RTX_LENGTH (code); i++)
693 {
694 switch (*fmt++)
695 {
696 case '0': /* Unused field. */
697 break;
698
699 case 'i': /* An integer? */
700 XINT (rt_val, i) = va_arg (p, int);
701 break;
702
3d678dca
RS
703 case 'w': /* A wide integer? */
704 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
705 break;
706
3e7b5313
TW
707 case 's': /* A string? */
708 XSTR (rt_val, i) = va_arg (p, char *);
709 break;
710
711 case 'e': /* An expression? */
712 case 'u': /* An insn? Same except when printing. */
713 XEXP (rt_val, i) = va_arg (p, rtx);
714 break;
715
716 case 'E': /* An RTX vector? */
717 XVEC (rt_val, i) = va_arg (p, rtvec);
718 break;
719
720 default:
c9541287 721 abort ();
3e7b5313
TW
722 }
723 }
724 va_end (p);
725 return rt_val;
726 }
727
7339c88d 728 rtl_obstack = old_obstack;
3e7b5313
TW
729 va_end (p);
730 attr_hash_add_rtx (hashcode, rt_val);
81fd4c6e 731 RTX_INTEGRATED_P (rt_val) = 1;
3e7b5313
TW
732 return rt_val;
733
734 found:
735 va_end (p);
736 return h->u.rtl;
737}
738
739/* Create a new string printed with the printf line arguments into a space
740 of at most LEN bytes:
741
742 rtx attr_printf (len, format, [arg1, ..., argn]) */
743
3e7b5313 744static char *
a94ae8f5 745attr_printf VPARAMS ((register int len, const char *fmt, ...))
3e7b5313 746{
5148a72b 747#ifndef ANSI_PROTOTYPES
3e7b5313 748 register int len;
85fda1eb 749 const char *fmt;
9e1b6503
RK
750#endif
751 va_list p;
b548dffb 752 char str[256];
3e7b5313 753
9e1b6503
RK
754 VA_START (p, fmt);
755
5148a72b 756#ifndef ANSI_PROTOTYPES
3e7b5313 757 len = va_arg (p, int);
85fda1eb 758 fmt = va_arg (p, const char *);
9e1b6503
RK
759#endif
760
b548dffb
ZW
761 if (len > 255) /* leave room for \0 */
762 abort ();
763
3e7b5313
TW
764 vsprintf (str, fmt, p);
765 va_end (p);
766
767 return attr_string (str, strlen (str));
768}
769
69277eec 770static rtx
81fd4c6e 771attr_eq (name, value)
3cce094d 772 const char *name, *value;
81fd4c6e
RS
773{
774 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
775 attr_string (value, strlen (value)));
776}
777
3cce094d 778static const char *
81fd4c6e
RS
779attr_numeral (n)
780 int n;
781{
782 return XSTR (make_numeric_value (n), 0);
783}
784
3e7b5313
TW
785/* Return a permanent (possibly shared) copy of a string STR (not assumed
786 to be null terminated) with LEN bytes. */
787
788static char *
789attr_string (str, len)
85fda1eb 790 const char *str;
3e7b5313
TW
791 int len;
792{
793 register struct attr_hash *h;
794 int hashcode;
795 int i;
796 register char *new_str;
797
798 /* Compute the hash code. */
c9541287 799 hashcode = (len + 1) * 613 + (unsigned) str[0];
3e7b5313 800 for (i = 1; i <= len; i += 2)
c9541287 801 hashcode = ((hashcode * 613) + (unsigned) str[i]);
3e7b5313
TW
802 if (hashcode < 0)
803 hashcode = -hashcode;
804
805 /* Search the table for the string. */
806 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
81fd4c6e 807 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
d45cf215 808 && !strncmp (h->u.str, str, len))
3e7b5313
TW
809 return h->u.str; /* <-- return if found. */
810
811 /* Not found; create a permanent copy and add it to the hash table. */
b31a5831 812 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
4e135bdd 813 memcpy (new_str, str, len);
3e7b5313
TW
814 new_str[len] = '\0';
815 attr_hash_add_string (hashcode, new_str);
816
817 return new_str; /* Return the new string. */
818}
81fd4c6e
RS
819
820/* Check two rtx's for equality of contents,
821 taking advantage of the fact that if both are hashed
822 then they can't be equal unless they are the same object. */
823
69277eec 824static int
81fd4c6e
RS
825attr_equal_p (x, y)
826 rtx x, y;
827{
828 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
829 && rtx_equal_p (x, y)));
830}
831\f
832/* Copy an attribute value expression,
833 descending to all depths, but not copying any
834 permanent hashed subexpressions. */
835
69277eec 836static rtx
81fd4c6e
RS
837attr_copy_rtx (orig)
838 register rtx orig;
839{
840 register rtx copy;
841 register int i, j;
842 register RTX_CODE code;
6f7d635c 843 register const char *format_ptr;
81fd4c6e
RS
844
845 /* No need to copy a permanent object. */
846 if (RTX_INTEGRATED_P (orig))
847 return orig;
848
849 code = GET_CODE (orig);
850
851 switch (code)
852 {
853 case REG:
854 case QUEUED:
855 case CONST_INT:
856 case CONST_DOUBLE:
857 case SYMBOL_REF:
858 case CODE_LABEL:
859 case PC:
860 case CC0:
861 return orig;
e9a25f70
JL
862
863 default:
864 break;
81fd4c6e
RS
865 }
866
867 copy = rtx_alloc (code);
868 PUT_MODE (copy, GET_MODE (orig));
869 copy->in_struct = orig->in_struct;
870 copy->volatil = orig->volatil;
871 copy->unchanging = orig->unchanging;
872 copy->integrated = orig->integrated;
c9541287 873
81fd4c6e
RS
874 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
875
876 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
877 {
878 switch (*format_ptr++)
879 {
880 case 'e':
881 XEXP (copy, i) = XEXP (orig, i);
882 if (XEXP (orig, i) != NULL)
883 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
884 break;
885
886 case 'E':
887 case 'V':
888 XVEC (copy, i) = XVEC (orig, i);
889 if (XVEC (orig, i) != NULL)
890 {
891 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
892 for (j = 0; j < XVECLEN (copy, i); j++)
893 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
894 }
895 break;
896
3d678dca
RS
897 case 'n':
898 case 'i':
81fd4c6e
RS
899 XINT (copy, i) = XINT (orig, i);
900 break;
3d678dca
RS
901
902 case 'w':
903 XWINT (copy, i) = XWINT (orig, i);
904 break;
905
906 case 's':
907 case 'S':
908 XSTR (copy, i) = XSTR (orig, i);
909 break;
910
911 default:
912 abort ();
81fd4c6e
RS
913 }
914 }
915 return copy;
916}
3e7b5313 917\f
41299f41 918/* Given a test expression for an attribute, ensure it is validly formed.
3e7b5313
TW
919 IS_CONST indicates whether the expression is constant for each compiler
920 run (a constant expression may not test any particular insn).
921
41299f41
TW
922 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
923 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
924 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
925
926 Update the string address in EQ_ATTR expression to be the same used
927 in the attribute (or `alternative_name') to speed up subsequent
928 `find_attr' calls and eliminate most `strcmp' calls.
929
930 Return the new expression, if any. */
931
932static rtx
a4cad544 933check_attr_test (exp, is_const, lineno)
41299f41 934 rtx exp;
3e7b5313 935 int is_const;
a4cad544 936 int lineno;
41299f41
TW
937{
938 struct attr_desc *attr;
939 struct attr_value *av;
3cce094d 940 const char *name_ptr, *p;
41299f41
TW
941 rtx orexp, newexp;
942
943 switch (GET_CODE (exp))
944 {
945 case EQ_ATTR:
946 /* Handle negation test. */
947 if (XSTR (exp, 1)[0] == '!')
3e7b5313 948 return check_attr_test (attr_rtx (NOT,
81fd4c6e
RS
949 attr_eq (XSTR (exp, 0),
950 &XSTR (exp, 1)[1])),
a4cad544 951 is_const, lineno);
41299f41
TW
952
953 else if (n_comma_elts (XSTR (exp, 1)) == 1)
954 {
c114787a 955 attr = find_attr (XSTR (exp, 0), 0);
41299f41
TW
956 if (attr == NULL)
957 {
958 if (! strcmp (XSTR (exp, 0), "alternative"))
959 {
960 XSTR (exp, 0) = alternative_name;
961 /* This can't be simplified any further. */
962 RTX_UNCHANGING_P (exp) = 1;
963 return exp;
964 }
7339c88d 965 else
487a6e06 966 fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
41299f41
TW
967 }
968
3e7b5313
TW
969 if (is_const && ! attr->is_const)
970 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
487a6e06 971 XSTR (exp, 0));
3e7b5313 972
81fd4c6e
RS
973 /* Copy this just to make it permanent,
974 so expressions using it can be permanent too. */
975 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
41299f41 976
f72aed24 977 /* It shouldn't be possible to simplify the value given to a
b31a5831 978 constant attribute, so don't expand this until it's time to
c9541287 979 write the test expression. */
b31a5831
RS
980 if (attr->is_const)
981 RTX_UNCHANGING_P (exp) = 1;
982
41299f41
TW
983 if (attr->is_numeric)
984 {
985 for (p = XSTR (exp, 1); *p; p++)
986 if (*p < '0' || *p > '9')
c9541287
KH
987 fatal ("Attribute `%s' takes only numeric values",
988 XSTR (exp, 0));
41299f41
TW
989 }
990 else
991 {
992 for (av = attr->first_value; av; av = av->next)
993 if (GET_CODE (av->value) == CONST_STRING
994 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
995 break;
996
997 if (av == NULL)
998 fatal ("Unknown value `%s' for `%s' attribute",
487a6e06 999 XSTR (exp, 1), XSTR (exp, 0));
41299f41
TW
1000 }
1001 }
1002 else
1003 {
1004 /* Make an IOR tree of the possible values. */
1005 orexp = false_rtx;
1006 name_ptr = XSTR (exp, 1);
1007 while ((p = next_comma_elt (&name_ptr)) != NULL)
1008 {
81fd4c6e 1009 newexp = attr_eq (XSTR (exp, 0), p);
f75d38a7 1010 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
41299f41
TW
1011 }
1012
a4cad544 1013 return check_attr_test (orexp, is_const, lineno);
41299f41
TW
1014 }
1015 break;
1016
0b0316dc
JL
1017 case ATTR_FLAG:
1018 break;
1019
41299f41
TW
1020 case CONST_INT:
1021 /* Either TRUE or FALSE. */
3d678dca 1022 if (XWINT (exp, 0))
41299f41
TW
1023 return true_rtx;
1024 else
1025 return false_rtx;
1026
1027 case IOR:
1028 case AND:
a4cad544
RH
1029 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1030 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
41299f41
TW
1031 break;
1032
1033 case NOT:
a4cad544 1034 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
41299f41
TW
1035 break;
1036
8450a694 1037 case MATCH_INSN:
41299f41 1038 case MATCH_OPERAND:
3e7b5313
TW
1039 if (is_const)
1040 fatal ("RTL operator \"%s\" not valid in constant attribute test",
8450a694 1041 GET_RTX_NAME (GET_CODE (exp)));
81fd4c6e
RS
1042 /* These cases can't be simplified. */
1043 RTX_UNCHANGING_P (exp) = 1;
1044 break;
c9541287 1045
41299f41
TW
1046 case LE: case LT: case GT: case GE:
1047 case LEU: case LTU: case GTU: case GEU:
1048 case NE: case EQ:
81fd4c6e
RS
1049 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1050 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1051 exp = attr_rtx (GET_CODE (exp),
1052 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1053 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
41299f41
TW
1054 /* These cases can't be simplified. */
1055 RTX_UNCHANGING_P (exp) = 1;
1056 break;
1057
3e7b5313
TW
1058 case SYMBOL_REF:
1059 if (is_const)
1060 {
1061 /* These cases are valid for constant attributes, but can't be
1062 simplified. */
81fd4c6e 1063 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
3e7b5313
TW
1064 RTX_UNCHANGING_P (exp) = 1;
1065 break;
1066 }
41299f41
TW
1067 default:
1068 fatal ("RTL operator \"%s\" not valid in attribute test",
1069 GET_RTX_NAME (GET_CODE (exp)));
1070 }
1071
1072 return exp;
1073}
1074\f
1075/* Given an expression, ensure that it is validly formed and that all named
1076 attribute values are valid for the given attribute. Issue a fatal error
81fd4c6e 1077 if not. If no attribute is specified, assume a numeric attribute.
41299f41 1078
81fd4c6e
RS
1079 Return a perhaps modified replacement expression for the value. */
1080
1081static rtx
41299f41
TW
1082check_attr_value (exp, attr)
1083 rtx exp;
1084 struct attr_desc *attr;
1085{
1086 struct attr_value *av;
3cce094d 1087 const char *p;
41299f41
TW
1088 int i;
1089
1090 switch (GET_CODE (exp))
1091 {
1092 case CONST_INT:
1093 if (attr && ! attr->is_numeric)
a4cad544
RH
1094 {
1095 message_with_line (attr->lineno,
1096 "CONST_INT not valid for non-numeric attribute %s",
1097 attr->name);
1098 have_error = 1;
1099 break;
1100 }
41299f41 1101
7ee37ba4 1102 if (INTVAL (exp) < 0 && ! attr->negative_ok)
a4cad544
RH
1103 {
1104 message_with_line (attr->lineno,
c9541287
KH
1105 "negative numeric value specified for attribute %s",
1106 attr->name);
a4cad544
RH
1107 have_error = 1;
1108 break;
1109 }
41299f41
TW
1110 break;
1111
1112 case CONST_STRING:
1113 if (! strcmp (XSTR (exp, 0), "*"))
1114 break;
1115
1116 if (attr == 0 || attr->is_numeric)
1117 {
72f1215c
TW
1118 p = XSTR (exp, 0);
1119 if (attr && attr->negative_ok && *p == '-')
1120 p++;
1121 for (; *p; p++)
41299f41 1122 if (*p > '9' || *p < '0')
a4cad544
RH
1123 {
1124 message_with_line (attr ? attr->lineno : 0,
1125 "non-numeric value for numeric attribute %s",
1126 attr ? attr->name : "internal");
1127 have_error = 1;
1128 break;
1129 }
41299f41
TW
1130 break;
1131 }
1132
1133 for (av = attr->first_value; av; av = av->next)
1134 if (GET_CODE (av->value) == CONST_STRING
1135 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1136 break;
1137
1138 if (av == NULL)
a4cad544
RH
1139 {
1140 message_with_line (attr->lineno,
1141 "unknown value `%s' for `%s' attribute",
1142 XSTR (exp, 0), attr ? attr->name : "internal");
1143 have_error = 1;
1144 }
81fd4c6e 1145 break;
41299f41
TW
1146
1147 case IF_THEN_ELSE:
3e7b5313 1148 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
a4cad544
RH
1149 attr ? attr->is_const : 0,
1150 attr ? attr->lineno : 0);
81fd4c6e
RS
1151 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1152 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1153 break;
41299f41 1154
7ee37ba4
RH
1155 case PLUS:
1156 case MINUS:
1157 case MULT:
1158 case DIV:
1159 case MOD:
1160 if (attr && !attr->is_numeric)
a4cad544
RH
1161 {
1162 message_with_line (attr->lineno,
c9541287
KH
1163 "invalid operation `%s' for non-numeric attribute value",
1164 GET_RTX_NAME (GET_CODE (exp)));
a4cad544
RH
1165 have_error = 1;
1166 break;
1167 }
7ee37ba4
RH
1168 /* FALLTHRU */
1169
71d9b493
RH
1170 case IOR:
1171 case AND:
1172 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1173 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1174 break;
1175
1176 case FFS:
1177 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1178 break;
1179
41299f41
TW
1180 case COND:
1181 if (XVECLEN (exp, 0) % 2 != 0)
a4cad544
RH
1182 {
1183 message_with_line (attr->lineno,
1184 "first operand of COND must have even length");
1185 have_error = 1;
1186 break;
1187 }
41299f41
TW
1188
1189 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1190 {
3e7b5313 1191 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
a4cad544
RH
1192 attr ? attr->is_const : 0,
1193 attr ? attr->lineno : 0);
81fd4c6e
RS
1194 XVECEXP (exp, 0, i + 1)
1195 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
41299f41
TW
1196 }
1197
81fd4c6e
RS
1198 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1199 break;
41299f41 1200
7ee37ba4
RH
1201 case ATTR:
1202 {
1203 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
1204 if (attr2 == NULL)
a4cad544
RH
1205 {
1206 message_with_line (attr ? attr->lineno : 0,
1207 "unknown attribute `%s' in ATTR",
1208 XSTR (exp, 0));
1209 have_error = 1;
1210 }
1211 else if (attr && attr->is_const && ! attr2->is_const)
1212 {
1213 message_with_line (attr->lineno,
1214 "non-constant attribute `%s' referenced from `%s'",
1215 XSTR (exp, 0), attr->name);
1216 have_error = 1;
1217 }
c9541287 1218 else if (attr
7ee37ba4
RH
1219 && (attr->is_numeric != attr2->is_numeric
1220 || (! attr->negative_ok && attr2->negative_ok)))
a4cad544
RH
1221 {
1222 message_with_line (attr->lineno,
1223 "numeric attribute mismatch calling `%s' from `%s'",
1224 XSTR (exp, 0), attr->name);
1225 have_error = 1;
1226 }
7ee37ba4
RH
1227 }
1228 break;
1229
3e7b5313 1230 case SYMBOL_REF:
7ee37ba4
RH
1231 /* A constant SYMBOL_REF is valid as a constant attribute test and
1232 is expanded later by make_canonical into a COND. In a non-constant
1233 attribute test, it is left be. */
1234 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
3e7b5313 1235
41299f41 1236 default:
a4cad544
RH
1237 message_with_line (attr ? attr->lineno : 0,
1238 "invalid operation `%s' for attribute value",
1239 GET_RTX_NAME (GET_CODE (exp)));
1240 have_error = 1;
1241 break;
41299f41 1242 }
81fd4c6e
RS
1243
1244 return exp;
41299f41
TW
1245}
1246\f
1247/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1248 It becomes a COND with each test being (eq_attr "alternative "n") */
1249
1250static rtx
a4cad544 1251convert_set_attr_alternative (exp, id)
41299f41 1252 rtx exp;
a4cad544 1253 struct insn_def *id;
41299f41 1254{
a4cad544 1255 int num_alt = id->num_alternatives;
41299f41
TW
1256 rtx condexp;
1257 int i;
1258
1259 if (XVECLEN (exp, 1) != num_alt)
a4cad544
RH
1260 {
1261 message_with_line (id->lineno,
c9541287 1262 "bad number of entries in SET_ATTR_ALTERNATIVE");
a4cad544
RH
1263 have_error = 1;
1264 return NULL_RTX;
1265 }
41299f41
TW
1266
1267 /* Make a COND with all tests but the last. Select the last value via the
1268 default. */
1269 condexp = rtx_alloc (COND);
1270 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1271
1272 for (i = 0; i < num_alt - 1; i++)
1273 {
3cce094d 1274 const char *p;
81fd4c6e 1275 p = attr_numeral (i);
3e7b5313 1276
81fd4c6e 1277 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
41299f41
TW
1278 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1279 }
1280
1281 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1282
3e7b5313 1283 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
41299f41
TW
1284}
1285\f
1286/* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1287 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1288
1289static rtx
a4cad544 1290convert_set_attr (exp, id)
41299f41 1291 rtx exp;
a4cad544 1292 struct insn_def *id;
41299f41
TW
1293{
1294 rtx newexp;
3cce094d 1295 const char *name_ptr;
41299f41
TW
1296 char *p;
1297 int n;
1298
1299 /* See how many alternative specified. */
1300 n = n_comma_elts (XSTR (exp, 1));
1301 if (n == 1)
3e7b5313
TW
1302 return attr_rtx (SET,
1303 attr_rtx (ATTR, XSTR (exp, 0)),
1304 attr_rtx (CONST_STRING, XSTR (exp, 1)));
41299f41
TW
1305
1306 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1307 XSTR (newexp, 0) = XSTR (exp, 0);
1308 XVEC (newexp, 1) = rtvec_alloc (n);
1309
1310 /* Process each comma-separated name. */
1311 name_ptr = XSTR (exp, 1);
1312 n = 0;
1313 while ((p = next_comma_elt (&name_ptr)) != NULL)
3e7b5313 1314 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
41299f41 1315
a4cad544 1316 return convert_set_attr_alternative (newexp, id);
41299f41
TW
1317}
1318\f
1319/* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1320 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
0f41302f 1321 expressions. */
41299f41
TW
1322
1323static void
1324check_defs ()
1325{
1326 struct insn_def *id;
1327 struct attr_desc *attr;
1328 int i;
1329 rtx value;
1330
1331 for (id = defs; id; id = id->next)
1332 {
1333 if (XVEC (id->def, id->vec_idx) == NULL)
1334 continue;
1335
1336 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1337 {
1338 value = XVECEXP (id->def, id->vec_idx, i);
1339 switch (GET_CODE (value))
1340 {
1341 case SET:
1342 if (GET_CODE (XEXP (value, 0)) != ATTR)
a4cad544
RH
1343 {
1344 message_with_line (id->lineno, "bad attribute set");
1345 have_error = 1;
1346 value = NULL_RTX;
1347 }
41299f41
TW
1348 break;
1349
1350 case SET_ATTR_ALTERNATIVE:
a4cad544 1351 value = convert_set_attr_alternative (value, id);
41299f41
TW
1352 break;
1353
1354 case SET_ATTR:
a4cad544 1355 value = convert_set_attr (value, id);
41299f41
TW
1356 break;
1357
1358 default:
a4cad544
RH
1359 message_with_line (id->lineno, "invalid attribute code %s",
1360 GET_RTX_NAME (GET_CODE (value)));
1361 have_error = 1;
1362 value = NULL_RTX;
41299f41 1363 }
a4cad544
RH
1364 if (value == NULL_RTX)
1365 continue;
41299f41
TW
1366
1367 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
a4cad544
RH
1368 {
1369 message_with_line (id->lineno, "unknown attribute %s",
1370 XSTR (XEXP (value, 0), 0));
1371 have_error = 1;
1372 continue;
1373 }
41299f41
TW
1374
1375 XVECEXP (id->def, id->vec_idx, i) = value;
81fd4c6e 1376 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
41299f41
TW
1377 }
1378 }
1379}
1380\f
71d9b493 1381#if 0
3e7b5313
TW
1382/* Given a constant SYMBOL_REF expression, convert to a COND that
1383 explicitly tests each enumerated value. */
1384
1385static rtx
1386convert_const_symbol_ref (exp, attr)
1387 rtx exp;
1388 struct attr_desc *attr;
1389{
1390 rtx condexp;
1391 struct attr_value *av;
1392 int i;
1393 int num_alt = 0;
1394
1395 for (av = attr->first_value; av; av = av->next)
1396 num_alt++;
1397
1398 /* Make a COND with all tests but the last, and in the original order.
1399 Select the last value via the default. Note that the attr values
1400 are constructed in reverse order. */
1401
1402 condexp = rtx_alloc (COND);
1403 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1404 av = attr->first_value;
1405 XEXP (condexp, 1) = av->value;
1406
1407 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1408 {
81fd4c6e 1409 char *p, *string;
3e7b5313
TW
1410 rtx value;
1411
0e9414fd 1412 string = p = (char *) oballoc (2
81fd4c6e
RS
1413 + strlen (attr->name)
1414 + strlen (XSTR (av->value, 0)));
3e7b5313
TW
1415 strcpy (p, attr->name);
1416 strcat (p, "_");
1417 strcat (p, XSTR (av->value, 0));
1418 for (; *p != '\0'; p++)
92a438d1 1419 *p = TOUPPER (*p);
3e7b5313 1420
81fd4c6e
RS
1421 value = attr_rtx (SYMBOL_REF, string);
1422 RTX_UNCHANGING_P (value) = 1;
c9541287 1423
3715a518 1424 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
81fd4c6e 1425
3e7b5313
TW
1426 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1427 }
1428
1429 return condexp;
1430}
71d9b493 1431#endif
3e7b5313 1432\f
41299f41
TW
1433/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1434 expressions by converting them into a COND. This removes cases from this
1435 program. Also, replace an attribute value of "*" with the default attribute
1436 value. */
1437
1438static rtx
1439make_canonical (attr, exp)
1440 struct attr_desc *attr;
1441 rtx exp;
1442{
1443 int i;
1444 rtx newexp;
1445
1446 switch (GET_CODE (exp))
1447 {
1448 case CONST_INT:
1449 exp = make_numeric_value (INTVAL (exp));
1450 break;
1451
1452 case CONST_STRING:
1453 if (! strcmp (XSTR (exp, 0), "*"))
1454 {
1455 if (attr == 0 || attr->default_val == 0)
1456 fatal ("(attr_value \"*\") used in invalid context.");
1457 exp = attr->default_val->value;
1458 }
1459
1460 break;
1461
3e7b5313
TW
1462 case SYMBOL_REF:
1463 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1464 break;
3715a518
RS
1465 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1466 This makes the COND something that won't be considered an arbitrary
1467 expression by walk_attr_value. */
1468 RTX_UNCHANGING_P (exp) = 1;
71d9b493
RH
1469#if 0
1470 /* ??? Why do we do this? With attribute values { A B C D E }, this
1471 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
c9541287 1472 than (x==E). */
3e7b5313 1473 exp = convert_const_symbol_ref (exp, attr);
052aaaef 1474 RTX_UNCHANGING_P (exp) = 1;
81fd4c6e 1475 exp = check_attr_value (exp, attr);
3e7b5313 1476 /* Goto COND case since this is now a COND. Note that while the
956d6950 1477 new expression is rescanned, all symbol_ref notes are marked as
3e7b5313
TW
1478 unchanging. */
1479 goto cond;
71d9b493
RH
1480#else
1481 exp = check_attr_value (exp, attr);
1482 break;
1483#endif
3e7b5313 1484
41299f41
TW
1485 case IF_THEN_ELSE:
1486 newexp = rtx_alloc (COND);
1487 XVEC (newexp, 0) = rtvec_alloc (2);
1488 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1489 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1490
1491 XEXP (newexp, 1) = XEXP (exp, 2);
1492
1493 exp = newexp;
1494 /* Fall through to COND case since this is now a COND. */
1495
1496 case COND:
7339c88d
RS
1497 {
1498 int allsame = 1;
1499 rtx defval;
41299f41 1500
0f41302f 1501 /* First, check for degenerate COND. */
7339c88d
RS
1502 if (XVECLEN (exp, 0) == 0)
1503 return make_canonical (attr, XEXP (exp, 1));
1504 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
41299f41 1505
7339c88d
RS
1506 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1507 {
81fd4c6e 1508 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
7339c88d
RS
1509 XVECEXP (exp, 0, i + 1)
1510 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1511 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1512 allsame = 0;
1513 }
1514 if (allsame)
1515 return defval;
7339c88d 1516 }
e9a25f70
JL
1517 break;
1518
1519 default:
1520 break;
41299f41
TW
1521 }
1522
1523 return exp;
1524}
81fd4c6e
RS
1525
1526static rtx
1527copy_boolean (exp)
1528 rtx exp;
1529{
1530 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1531 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1532 copy_boolean (XEXP (exp, 1)));
1533 return exp;
1534}
41299f41
TW
1535\f
1536/* Given a value and an attribute description, return a `struct attr_value *'
1537 that represents that value. This is either an existing structure, if the
1538 value has been previously encountered, or a newly-created structure.
1539
1540 `insn_code' is the code of an insn whose attribute has the specified
1541 value (-2 if not processing an insn). We ensure that all insns for
1542 a given value have the same number of alternatives if the value checks
1543 alternatives. */
1544
1545static struct attr_value *
1546get_attr_value (value, attr, insn_code)
1547 rtx value;
1548 struct attr_desc *attr;
1549 int insn_code;
1550{
1551 struct attr_value *av;
1552 int num_alt = 0;
1553
1554 value = make_canonical (attr, value);
1555 if (compares_alternatives_p (value))
1556 {
1557 if (insn_code < 0 || insn_alternatives == NULL)
1558 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1559 else
1560 num_alt = insn_alternatives[insn_code];
1561 }
1562
1563 for (av = attr->first_value; av; av = av->next)
1564 if (rtx_equal_p (value, av->value)
1565 && (num_alt == 0 || av->first_insn == NULL
1566 || insn_alternatives[av->first_insn->insn_code]))
1567 return av;
1568
0e9414fd 1569 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
41299f41
TW
1570 av->value = value;
1571 av->next = attr->first_value;
1572 attr->first_value = av;
1573 av->first_insn = NULL;
1574 av->num_insns = 0;
1575 av->has_asm_insn = 0;
1576
1577 return av;
1578}
1579\f
1580/* After all DEFINE_DELAYs have been read in, create internal attributes
1581 to generate the required routines.
1582
1583 First, we compute the number of delay slots for each insn (as a COND of
1584 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1585 delay type is specified, we compute a similar function giving the
1586 DEFINE_DELAY ordinal for each insn.
1587
1588 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1589 tells whether a given insn can be in that delay slot.
1590
6dc42e49 1591 Normal attribute filling and optimization expands these to contain the
41299f41
TW
1592 information needed to handle delay slots. */
1593
1594static void
1595expand_delays ()
1596{
1597 struct delay_desc *delay;
1598 rtx condexp;
1599 rtx newexp;
1600 int i;
1601 char *p;
1602
1603 /* First, generate data for `num_delay_slots' function. */
1604
1605 condexp = rtx_alloc (COND);
1606 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1607 XEXP (condexp, 1) = make_numeric_value (0);
1608
1609 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1610 {
1611 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1612 XVECEXP (condexp, 0, i + 1)
1613 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1614 }
1615
1616 make_internal_attr ("*num_delay_slots", condexp, 0);
1617
1618 /* If more than one delay type, do the same for computing the delay type. */
1619 if (num_delays > 1)
1620 {
1621 condexp = rtx_alloc (COND);
1622 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1623 XEXP (condexp, 1) = make_numeric_value (0);
1624
1625 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1626 {
1627 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1628 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1629 }
1630
1631 make_internal_attr ("*delay_type", condexp, 1);
1632 }
1633
6dc42e49
RS
1634 /* For each delay possibility and delay slot, compute an eligibility
1635 attribute for non-annulled insns and for each type of annulled (annul
41299f41 1636 if true and annul if false). */
c9541287
KH
1637 for (delay = delays; delay; delay = delay->next)
1638 {
1639 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1640 {
1641 condexp = XVECEXP (delay->def, 1, i);
1642 if (condexp == 0)
1643 condexp = false_rtx;
1644 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1645 make_numeric_value (1), make_numeric_value (0));
1646
1647 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS * 2,
1648 "*delay_%d_%d",
1649 delay->num, i / 3);
1650 make_internal_attr (p, newexp, 1);
1651
1652 if (have_annul_true)
1653 {
1654 condexp = XVECEXP (delay->def, 1, i + 1);
1655 if (condexp == 0) condexp = false_rtx;
1656 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1657 make_numeric_value (1),
1658 make_numeric_value (0));
1659 p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS * 2,
1660 "*annul_true_%d_%d", delay->num, i / 3);
1661 make_internal_attr (p, newexp, 1);
1662 }
1663
1664 if (have_annul_false)
1665 {
1666 condexp = XVECEXP (delay->def, 1, i + 2);
1667 if (condexp == 0) condexp = false_rtx;
1668 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1669 make_numeric_value (1),
1670 make_numeric_value (0));
1671 p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS * 2,
1672 "*annul_false_%d_%d", delay->num, i / 3);
1673 make_internal_attr (p, newexp, 1);
1674 }
1675 }
1676 }
41299f41
TW
1677}
1678\f
1679/* This function is given a left and right side expression and an operator.
1680 Each side is a conditional expression, each alternative of which has a
1681 numerical value. The function returns another conditional expression
1682 which, for every possible set of condition values, returns a value that is
1683 the operator applied to the values of the two sides.
1684
1685 Since this is called early, it must also support IF_THEN_ELSE. */
1686
1687static rtx
1688operate_exp (op, left, right)
1689 enum operator op;
1690 rtx left, right;
1691{
1692 int left_value, right_value;
1693 rtx newexp;
1694 int i;
1695
1696 /* If left is a string, apply operator to it and the right side. */
1697 if (GET_CODE (left) == CONST_STRING)
1698 {
1699 /* If right is also a string, just perform the operation. */
1700 if (GET_CODE (right) == CONST_STRING)
1701 {
1702 left_value = atoi (XSTR (left, 0));
1703 right_value = atoi (XSTR (right, 0));
1704 switch (op)
1705 {
1706 case PLUS_OP:
1707 i = left_value + right_value;
1708 break;
1709
1710 case MINUS_OP:
1711 i = left_value - right_value;
1712 break;
1713
bee757e1
TW
1714 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1715 if (left_value > right_value)
1716 i = left_value - right_value;
1717 else
1718 i = 0;
1719 break;
1720
41299f41 1721 case OR_OP:
71d9b493 1722 case ORX_OP:
41299f41
TW
1723 i = left_value | right_value;
1724 break;
1725
bee757e1
TW
1726 case EQ_OP:
1727 i = left_value == right_value;
1728 break;
1729
1730 case RANGE_OP:
1731 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1732 break;
1733
41299f41
TW
1734 case MAX_OP:
1735 if (left_value > right_value)
1736 i = left_value;
1737 else
1738 i = right_value;
1739 break;
1740
bee757e1
TW
1741 case MIN_OP:
1742 if (left_value < right_value)
1743 i = left_value;
1744 else
1745 i = right_value;
1746 break;
1747
41299f41
TW
1748 default:
1749 abort ();
1750 }
1751
71d9b493
RH
1752 if (i == left_value)
1753 return left;
1754 if (i == right_value)
1755 return right;
41299f41
TW
1756 return make_numeric_value (i);
1757 }
1758 else if (GET_CODE (right) == IF_THEN_ELSE)
1759 {
1760 /* Apply recursively to all values within. */
7339c88d
RS
1761 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1762 rtx newright = operate_exp (op, left, XEXP (right, 2));
1763 if (rtx_equal_p (newleft, newright))
1764 return newleft;
1765 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
41299f41
TW
1766 }
1767 else if (GET_CODE (right) == COND)
1768 {
7339c88d
RS
1769 int allsame = 1;
1770 rtx defval;
1771
41299f41
TW
1772 newexp = rtx_alloc (COND);
1773 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
7339c88d
RS
1774 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1775
41299f41
TW
1776 for (i = 0; i < XVECLEN (right, 0); i += 2)
1777 {
1778 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1779 XVECEXP (newexp, 0, i + 1)
1780 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
7339c88d 1781 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
c9541287 1782 defval))
7339c88d 1783 allsame = 0;
41299f41
TW
1784 }
1785
7339c88d
RS
1786 /* If the resulting cond is trivial (all alternatives
1787 give the same value), optimize it away. */
1788 if (allsame)
1f8f4a0b 1789 return operate_exp (op, left, XEXP (right, 1));
41299f41
TW
1790
1791 return newexp;
1792 }
1793 else
1794 fatal ("Badly formed attribute value");
1795 }
1796
71d9b493
RH
1797 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1798 not associate through IF_THEN_ELSE. */
1799 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1800 {
1801 return attr_rtx (IOR, left, right);
1802 }
1803
41299f41
TW
1804 /* Otherwise, do recursion the other way. */
1805 else if (GET_CODE (left) == IF_THEN_ELSE)
1806 {
7339c88d
RS
1807 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1808 rtx newright = operate_exp (op, XEXP (left, 2), right);
1809 if (rtx_equal_p (newleft, newright))
1810 return newleft;
1811 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
41299f41 1812 }
41299f41
TW
1813 else if (GET_CODE (left) == COND)
1814 {
7339c88d
RS
1815 int allsame = 1;
1816 rtx defval;
1817
41299f41
TW
1818 newexp = rtx_alloc (COND);
1819 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
7339c88d
RS
1820 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1821
41299f41
TW
1822 for (i = 0; i < XVECLEN (left, 0); i += 2)
1823 {
1824 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1825 XVECEXP (newexp, 0, i + 1)
1826 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
7339c88d 1827 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
c9541287 1828 defval))
7339c88d 1829 allsame = 0;
41299f41
TW
1830 }
1831
7339c88d
RS
1832 /* If the cond is trivial (all alternatives give the same value),
1833 optimize it away. */
1834 if (allsame)
1f8f4a0b 1835 return operate_exp (op, XEXP (left, 1), right);
7339c88d
RS
1836
1837 /* If the result is the same as the LEFT operand,
1838 just use that. */
1839 if (rtx_equal_p (newexp, left))
1f8f4a0b 1840 return left;
41299f41
TW
1841
1842 return newexp;
1843 }
1844
1845 else
1846 fatal ("Badly formed attribute value.");
1847 /* NOTREACHED */
1848 return NULL;
1849}
1850\f
1851/* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1852 construct a number of attributes.
1853
1854 The first produces a function `function_units_used' which is given an
72f1215c
TW
1855 insn and produces an encoding showing which function units are required
1856 for the execution of that insn. If the value is non-negative, the insn
1857 uses that unit; otherwise, the value is a one's compliment mask of units
1858 used.
41299f41
TW
1859
1860 The second produces a function `result_ready_cost' which is used to
1861 determine the time that the result of an insn will be ready and hence
1862 a worst-case schedule.
1863
1864 Both of these produce quite complex expressions which are then set as the
1865 default value of internal attributes. Normal attribute simplification
1866 should produce reasonable expressions.
1867
1868 For each unit, a `<name>_unit_ready_cost' function will take an
1869 insn and give the delay until that unit will be ready with the result
72f1215c 1870 and a `<name>_unit_conflict_cost' function is given an insn already
41299f41
TW
1871 executing on the unit and a candidate to execute and will give the
1872 cost from the time the executing insn started until the candidate
bee757e1
TW
1873 can start (ignore limitations on the number of simultaneous insns).
1874
1875 For each unit, a `<name>_unit_blockage' function is given an insn
1876 already executing on the unit and a candidate to execute and will
1877 give the delay incurred due to function unit conflicts. The range of
1878 blockage cost values for a given executing insn is given by the
1879 `<name>_unit_blockage_range' function. These values are encoded in
1880 an int where the upper half gives the minimum value and the lower
1881 half gives the maximum value. */
41299f41
TW
1882
1883static void
1884expand_units ()
1885{
72f1215c
TW
1886 struct function_unit *unit, **unit_num;
1887 struct function_unit_op *op, **op_array, ***unit_ops;
41299f41
TW
1888 rtx unitsmask;
1889 rtx readycost;
1890 rtx newexp;
85fda1eb 1891 const char *str;
72f1215c 1892 int i, j, u, num, nvalues;
41299f41 1893
bee757e1
TW
1894 /* Rebuild the condition for the unit to share the RTL expressions.
1895 Sharing is required by simplify_by_exploding. Build the issue delay
1896 expressions. Validate the expressions we were given for the conditions
1897 and conflict vector. Then make attributes for use in the conflict
1898 function. */
1899
72f1215c 1900 for (unit = units; unit; unit = unit->next)
bee757e1 1901 {
a4cad544 1902 unit->condexp = check_attr_test (unit->condexp, 0, unit->first_lineno);
bee757e1
TW
1903
1904 for (op = unit->ops; op; op = op->next)
1905 {
1906 rtx issue_delay = make_numeric_value (op->issue_delay);
1907 rtx issue_exp = issue_delay;
1908
1909 /* Build, validate, and simplify the issue delay expression. */
1910 if (op->conflict_exp != true_rtx)
1911 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1912 issue_exp, make_numeric_value (0));
1913 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1914 issue_exp),
72f1215c 1915 NULL_ATTR);
bee757e1
TW
1916 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1917 op->issue_exp = issue_exp;
1918
1919 /* Make an attribute for use in the conflict function if needed. */
1920 unit->needs_conflict_function = (unit->issue_delay.min
1921 != unit->issue_delay.max);
1922 if (unit->needs_conflict_function)
1923 {
0e9414fd
MM
1924 str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1925 "*%s_cost_%d", unit->name, op->num);
bee757e1
TW
1926 make_internal_attr (str, issue_exp, 1);
1927 }
1928
1929 /* Validate the condition. */
a4cad544 1930 op->condexp = check_attr_test (op->condexp, 0, op->lineno);
bee757e1
TW
1931 }
1932 }
41299f41 1933
72f1215c
TW
1934 /* Compute the mask of function units used. Initially, the unitsmask is
1935 zero. Set up a conditional to compute each unit's contribution. */
1936 unitsmask = make_numeric_value (0);
41299f41
TW
1937 newexp = rtx_alloc (IF_THEN_ELSE);
1938 XEXP (newexp, 2) = make_numeric_value (0);
1939
71d9b493
RH
1940 /* If we have just a few units, we may be all right expanding the whole
1941 thing. But the expansion is 2**N in space on the number of opclasses,
1942 so we can't do this for very long -- Alpha and MIPS in particular have
1943 problems with this. So in that situation, we fall back on an alternate
1944 implementation method. */
1945#define NUM_UNITOP_CUTOFF 20
1946
1947 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
72f1215c 1948 {
71d9b493
RH
1949 /* Merge each function unit into the unit mask attributes. */
1950 for (unit = units; unit; unit = unit->next)
c9541287
KH
1951 {
1952 XEXP (newexp, 0) = unit->condexp;
1953 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1954 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1955 }
71d9b493
RH
1956 }
1957 else
1958 {
1959 /* Merge each function unit into the unit mask attributes. */
1960 for (unit = units; unit; unit = unit->next)
c9541287
KH
1961 {
1962 XEXP (newexp, 0) = unit->condexp;
1963 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1964 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1965 }
72f1215c
TW
1966 }
1967
1968 /* Simplify the unit mask expression, encode it, and make an attribute
1969 for the function_units_used function. */
1970 unitsmask = simplify_by_exploding (unitsmask);
71d9b493
RH
1971
1972 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1973 unitsmask = encode_units_mask (unitsmask);
1974 else
1975 {
1976 /* We can no longer encode unitsmask at compile time, so emit code to
1977 calculate it at runtime. Rather, put a marker for where we'd do
1978 the code, and actually output it in write_attr_get(). */
1979 unitsmask = attr_rtx (FFS, unitsmask);
1980 }
1981
6f6074ea 1982 make_internal_attr ("*function_units_used", unitsmask, 10);
72f1215c
TW
1983
1984 /* Create an array of ops for each unit. Add an extra unit for the
1985 result_ready_cost function that has the ops of all other units. */
1986 unit_ops = (struct function_unit_op ***)
b548dffb 1987 xmalloc ((num_units + 1) * sizeof (struct function_unit_op **));
72f1215c 1988 unit_num = (struct function_unit **)
b548dffb 1989 xmalloc ((num_units + 1) * sizeof (struct function_unit *));
72f1215c
TW
1990
1991 unit_num[num_units] = unit = (struct function_unit *)
b548dffb 1992 xmalloc (sizeof (struct function_unit));
72f1215c
TW
1993 unit->num = num_units;
1994 unit->num_opclasses = 0;
1995
1996 for (unit = units; unit; unit = unit->next)
1997 {
1998 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1999 unit_num[unit->num] = unit;
2000 unit_ops[unit->num] = op_array = (struct function_unit_op **)
b548dffb 2001 xmalloc (unit->num_opclasses * sizeof (struct function_unit_op *));
72f1215c
TW
2002
2003 for (op = unit->ops; op; op = op->next)
2004 op_array[op->num] = op;
2005 }
2006
2007 /* Compose the array of ops for the extra unit. */
2008 unit_ops[num_units] = op_array = (struct function_unit_op **)
b548dffb 2009 xmalloc (unit_num[num_units]->num_opclasses
72f1215c
TW
2010 * sizeof (struct function_unit_op *));
2011
2012 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
4c9a05bc 2013 bcopy ((char *) unit_ops[unit->num], (char *) &op_array[i],
72f1215c
TW
2014 unit->num_opclasses * sizeof (struct function_unit_op *));
2015
2016 /* Compute the ready cost function for each unit by computing the
2017 condition for each non-default value. */
2018 for (u = 0; u <= num_units; u++)
2019 {
2020 rtx orexp;
2021 int value;
2022
2023 unit = unit_num[u];
2024 op_array = unit_ops[unit->num];
2025 num = unit->num_opclasses;
2026
2027 /* Sort the array of ops into increasing ready cost order. */
2028 for (i = 0; i < num; i++)
2029 for (j = num - 1; j > i; j--)
c9541287 2030 if (op_array[j - 1]->ready < op_array[j]->ready)
72f1215c
TW
2031 {
2032 op = op_array[j];
c9541287
KH
2033 op_array[j] = op_array[j - 1];
2034 op_array[j - 1] = op;
72f1215c
TW
2035 }
2036
2037 /* Determine how many distinct non-default ready cost values there
2038 are. We use a default ready cost value of 1. */
2039 nvalues = 0; value = 1;
2040 for (i = num - 1; i >= 0; i--)
2041 if (op_array[i]->ready > value)
2042 {
2043 value = op_array[i]->ready;
2044 nvalues++;
2045 }
2046
2047 if (nvalues == 0)
2048 readycost = make_numeric_value (1);
2049 else
2050 {
2051 /* Construct the ready cost expression as a COND of each value from
2052 the largest to the smallest. */
2053 readycost = rtx_alloc (COND);
2054 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2055 XEXP (readycost, 1) = make_numeric_value (1);
2056
c9541287
KH
2057 nvalues = 0;
2058 orexp = false_rtx;
2059 value = op_array[0]->ready;
72f1215c
TW
2060 for (i = 0; i < num; i++)
2061 {
2062 op = op_array[i];
2063 if (op->ready <= 1)
2064 break;
2065 else if (op->ready == value)
f75d38a7 2066 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
72f1215c
TW
2067 else
2068 {
2069 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2070 XVECEXP (readycost, 0, nvalues * 2 + 1)
2071 = make_numeric_value (value);
2072 nvalues++;
2073 value = op->ready;
2074 orexp = op->condexp;
2075 }
2076 }
2077 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2078 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2079 }
2080
72f1215c 2081 if (u < num_units)
bee757e1
TW
2082 {
2083 rtx max_blockage = 0, min_blockage = 0;
2084
2085 /* Simplify the readycost expression by only considering insns
2086 that use the unit. */
2087 readycost = simplify_knowing (readycost, unit->condexp);
2088
2089 /* Determine the blockage cost the executing insn (E) given
2090 the candidate insn (C). This is the maximum of the issue
2091 delay, the pipeline delay, and the simultaneity constraint.
2092 Each function_unit_op represents the characteristics of the
2093 candidate insn, so in the expressions below, C is a known
2094 term and E is an unknown term.
2095
cb1520bc
JW
2096 We compute the blockage cost for each E for every possible C.
2097 Thus OP represents E, and READYCOST is a list of values for
2098 every possible C.
2099
bee757e1
TW
2100 The issue delay function for C is op->issue_exp and is used to
2101 write the `<name>_unit_conflict_cost' function. Symbolicly
2102 this is "ISSUE-DELAY (E,C)".
2103
2104 The pipeline delay results form the FIFO constraint on the
2105 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2106
2107 The simultaneity constraint is based on how long it takes to
2108 fill the unit given the minimum issue delay. FILL-TIME is the
2109 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2110 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2111 if SIMULTANEITY is non-zero and zero otherwise.
2112
2113 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2114
2115 MAX (ISSUE-DELAY (E,C),
2116 READY-COST (E) - (READY-COST (C) - 1))
2117
2118 and otherwise
2119
2120 MAX (ISSUE-DELAY (E,C),
2121 READY-COST (E) - (READY-COST (C) - 1),
2122 READY-COST (E) - FILL-TIME)
2123
2124 The `<name>_unit_blockage' function is computed by determining
2125 this value for each candidate insn. As these values are
2126 computed, we also compute the upper and lower bounds for
2127 BLOCKAGE (E,*). These are combined to form the function
2128 `<name>_unit_blockage_range'. Finally, the maximum blockage
2129 cost, MAX (BLOCKAGE (*,*)), is computed. */
2130
2131 for (op = unit->ops; op; op = op->next)
2132 {
8c660648 2133 rtx blockage = op->issue_exp;
bee757e1
TW
2134 blockage = simplify_knowing (blockage, unit->condexp);
2135
2136 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2137 MIN (BLOCKAGE (E,*)). */
2138 if (max_blockage == 0)
2139 max_blockage = min_blockage = blockage;
2140 else
2141 {
2142 max_blockage
2143 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2144 blockage),
2145 unit->condexp);
2146 min_blockage
2147 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2148 blockage),
2149 unit->condexp);
2150 }
2151
2152 /* Make an attribute for use in the blockage function. */
0e9414fd
MM
2153 str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2154 "*%s_block_%d", unit->name, op->num);
bee757e1
TW
2155 make_internal_attr (str, blockage, 1);
2156 }
2157
2158 /* Record MAX (BLOCKAGE (*,*)). */
7ee37ba4
RH
2159 {
2160 int unknown;
2161 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2162 }
bee757e1
TW
2163
2164 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2165 same. If so, the blockage function carries no additional
2166 information and is not written. */
2167 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2168 newexp = simplify_knowing (newexp, unit->condexp);
2169 unit->needs_blockage_function
2170 = (GET_CODE (newexp) != CONST_STRING
2171 || atoi (XSTR (newexp, 0)) != 1);
2172
2173 /* If the all values of BLOCKAGE (E,C) have the same value,
c9541287 2174 neither blockage function is written. */
bee757e1
TW
2175 unit->needs_range_function
2176 = (unit->needs_blockage_function
2177 || GET_CODE (max_blockage) != CONST_STRING);
2178
2179 if (unit->needs_range_function)
2180 {
2181 /* Compute the blockage range function and make an attribute
9ec36da5 2182 for writing its value. */
bee757e1
TW
2183 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2184 newexp = simplify_knowing (newexp, unit->condexp);
2185
0e9414fd 2186 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
bee757e1 2187 "*%s_unit_blockage_range", unit->name);
6f6074ea 2188 make_internal_attr (str, newexp, 20);
bee757e1
TW
2189 }
2190
0e9414fd
MM
2191 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2192 "*%s_unit_ready_cost", unit->name);
bee757e1 2193 }
72f1215c
TW
2194 else
2195 str = "*result_ready_cost";
bee757e1
TW
2196
2197 /* Make an attribute for the ready_cost function. Simplifying
2198 further with simplify_by_exploding doesn't win. */
72f1215c
TW
2199 make_internal_attr (str, readycost, 0);
2200 }
2201
2202 /* For each unit that requires a conflict cost function, make an attribute
2203 that maps insns to the operation number. */
41299f41
TW
2204 for (unit = units; unit; unit = unit->next)
2205 {
72f1215c 2206 rtx caseexp;
41299f41 2207
bee757e1
TW
2208 if (! unit->needs_conflict_function
2209 && ! unit->needs_blockage_function)
72f1215c
TW
2210 continue;
2211
2212 caseexp = rtx_alloc (COND);
41299f41
TW
2213 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2214
2215 for (op = unit->ops; op; op = op->next)
2216 {
72f1215c
TW
2217 /* Make our adjustment to the COND being computed. If we are the
2218 last operation class, place our values into the default of the
2219 COND. */
41299f41
TW
2220 if (op->num == unit->num_opclasses - 1)
2221 {
41299f41
TW
2222 XEXP (caseexp, 1) = make_numeric_value (op->num);
2223 }
2224 else
2225 {
41299f41
TW
2226 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2227 XVECEXP (caseexp, 0, op->num * 2 + 1)
2228 = make_numeric_value (op->num);
2229 }
2230 }
2231
72f1215c 2232 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
0e9414fd
MM
2233 str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2234 "*%s_cases", unit->name);
41299f41 2235 make_internal_attr (str, caseexp, 1);
72f1215c
TW
2236 }
2237}
41299f41 2238
bee757e1
TW
2239/* Simplify EXP given KNOWN_TRUE. */
2240
2241static rtx
2242simplify_knowing (exp, known_true)
2243 rtx exp, known_true;
2244{
2245 if (GET_CODE (exp) != CONST_STRING)
2246 {
6166aa01 2247 int unknown = 0, max;
7ee37ba4
RH
2248 max = max_attr_value (exp, &unknown);
2249 if (! unknown)
2250 {
2251 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
c9541287
KH
2252 make_numeric_value (max));
2253 exp = simplify_by_exploding (exp);
7ee37ba4 2254 }
bee757e1
TW
2255 }
2256 return exp;
2257}
2258
72f1215c
TW
2259/* Translate the CONST_STRING expressions in X to change the encoding of
2260 value. On input, the value is a bitmask with a one bit for each unit
2261 used; on output, the value is the unit number (zero based) if one
2262 and only one unit is used or the one's compliment of the bitmask. */
41299f41 2263
72f1215c
TW
2264static rtx
2265encode_units_mask (x)
2266 rtx x;
2267{
2268 register int i;
2269 register int j;
2270 register enum rtx_code code;
6f7d635c 2271 register const char *fmt;
72f1215c
TW
2272
2273 code = GET_CODE (x);
2274
2275 switch (code)
2276 {
2277 case CONST_STRING:
2278 i = atoi (XSTR (x, 0));
2279 if (i < 0)
c9541287
KH
2280 /* The sign bit encodes a one's compliment mask. */
2281 abort ();
72f1215c
TW
2282 else if (i != 0 && i == (i & -i))
2283 /* Only one bit is set, so yield that unit number. */
2284 for (j = 0; (i >>= 1) != 0; j++)
2285 ;
2286 else
2287 j = ~i;
0e9414fd 2288 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
41299f41 2289
72f1215c
TW
2290 case REG:
2291 case QUEUED:
2292 case CONST_INT:
2293 case CONST_DOUBLE:
2294 case SYMBOL_REF:
2295 case CODE_LABEL:
2296 case PC:
2297 case CC0:
2298 case EQ_ATTR:
2299 return x;
c9541287 2300
e9a25f70
JL
2301 default:
2302 break;
41299f41
TW
2303 }
2304
72f1215c
TW
2305 /* Compare the elements. If any pair of corresponding elements
2306 fail to match, return 0 for the whole things. */
2307
2308 fmt = GET_RTX_FORMAT (code);
2309 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2310 {
2311 switch (fmt[i])
2312 {
2313 case 'V':
2314 case 'E':
2315 for (j = 0; j < XVECLEN (x, i); j++)
2316 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2317 break;
2318
2319 case 'e':
2320 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2321 break;
2322 }
2323 }
2324 return x;
41299f41
TW
2325}
2326\f
2327/* Once all attributes and insns have been read and checked, we construct for
2328 each attribute value a list of all the insns that have that value for
2329 the attribute. */
2330
2331static void
2332fill_attr (attr)
2333 struct attr_desc *attr;
2334{
2335 struct attr_value *av;
2336 struct insn_ent *ie;
2337 struct insn_def *id;
2338 int i;
2339 rtx value;
2340
b31a5831
RS
2341 /* Don't fill constant attributes. The value is independent of
2342 any particular insn. */
2343 if (attr->is_const)
2344 return;
2345
41299f41
TW
2346 for (id = defs; id; id = id->next)
2347 {
2348 /* If no value is specified for this insn for this attribute, use the
2349 default. */
2350 value = NULL;
2351 if (XVEC (id->def, id->vec_idx))
2352 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
c9541287 2353 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
41299f41
TW
2354 attr->name))
2355 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2356
2357 if (value == NULL)
2358 av = attr->default_val;
2359 else
2360 av = get_attr_value (value, attr, id->insn_code);
2361
0e9414fd 2362 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
41299f41
TW
2363 ie->insn_code = id->insn_code;
2364 ie->insn_index = id->insn_code;
2365 insert_insn_ent (av, ie);
2366 }
2367}
2368\f
ae90e6a3
RS
2369/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2370 test that checks relative positions of insns (uses MATCH_DUP or PC).
2371 If so, replace it with what is obtained by passing the expression to
2372 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2373 recursively on each value (including the default value). Otherwise,
2374 return the value returned by NO_ADDRESS_FN applied to EXP. */
41299f41
TW
2375
2376static rtx
2377substitute_address (exp, no_address_fn, address_fn)
2378 rtx exp;
a94ae8f5
KG
2379 rtx (*no_address_fn) PARAMS ((rtx));
2380 rtx (*address_fn) PARAMS ((rtx));
41299f41
TW
2381{
2382 int i;
2383 rtx newexp;
2384
ae90e6a3
RS
2385 if (GET_CODE (exp) == COND)
2386 {
2387 /* See if any tests use addresses. */
2388 address_used = 0;
2389 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2390 walk_attr_value (XVECEXP (exp, 0, i));
41299f41 2391
ae90e6a3
RS
2392 if (address_used)
2393 return (*address_fn) (exp);
41299f41 2394
ae90e6a3
RS
2395 /* Make a new copy of this COND, replacing each element. */
2396 newexp = rtx_alloc (COND);
2397 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2398 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2399 {
2400 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2401 XVECEXP (newexp, 0, i + 1)
2402 = substitute_address (XVECEXP (exp, 0, i + 1),
2403 no_address_fn, address_fn);
2404 }
41299f41 2405
ae90e6a3
RS
2406 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2407 no_address_fn, address_fn);
2408
2409 return newexp;
41299f41
TW
2410 }
2411
ae90e6a3
RS
2412 else if (GET_CODE (exp) == IF_THEN_ELSE)
2413 {
2414 address_used = 0;
2415 walk_attr_value (XEXP (exp, 0));
2416 if (address_used)
2417 return (*address_fn) (exp);
41299f41 2418
3e7b5313
TW
2419 return attr_rtx (IF_THEN_ELSE,
2420 substitute_address (XEXP (exp, 0),
2421 no_address_fn, address_fn),
2422 substitute_address (XEXP (exp, 1),
2423 no_address_fn, address_fn),
2424 substitute_address (XEXP (exp, 2),
2425 no_address_fn, address_fn));
ae90e6a3
RS
2426 }
2427
2428 return (*no_address_fn) (exp);
41299f41
TW
2429}
2430\f
2431/* Make new attributes from the `length' attribute. The following are made,
2432 each corresponding to a function called from `shorten_branches' or
2433 `get_attr_length':
2434
2435 *insn_default_length This is the length of the insn to be returned
2436 by `get_attr_length' before `shorten_branches'
2437 has been called. In each case where the length
2438 depends on relative addresses, the largest
2439 possible is used. This routine is also used
2440 to compute the initial size of the insn.
2441
2442 *insn_variable_length_p This returns 1 if the insn's length depends
2443 on relative addresses, zero otherwise.
2444
2445 *insn_current_length This is only called when it is known that the
2446 insn has a variable length and returns the
2447 current length, based on relative addresses.
2448 */
2449
2450static void
2451make_length_attrs ()
2452{
85fda1eb
KG
2453 static const char *new_names[] = {"*insn_default_length",
2454 "*insn_variable_length_p",
2455 "*insn_current_length"};
a94ae8f5
KG
2456 static rtx (*no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
2457 static rtx (*address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
d6f4ec51 2458 size_t i;
41299f41
TW
2459 struct attr_desc *length_attr, *new_attr;
2460 struct attr_value *av, *new_av;
2461 struct insn_ent *ie, *new_ie;
2462
2463 /* See if length attribute is defined. If so, it must be numeric. Make
2464 it special so we don't output anything for it. */
2465 length_attr = find_attr ("length", 0);
2466 if (length_attr == 0)
2467 return;
2468
2469 if (! length_attr->is_numeric)
2470 fatal ("length attribute must be numeric.");
2471
3e7b5313 2472 length_attr->is_const = 0;
41299f41
TW
2473 length_attr->is_special = 1;
2474
2475 /* Make each new attribute, in turn. */
b6a1cbae 2476 for (i = 0; i < ARRAY_SIZE (new_names); i++)
41299f41
TW
2477 {
2478 make_internal_attr (new_names[i],
2479 substitute_address (length_attr->default_val->value,
2480 no_address_fn[i], address_fn[i]),
2481 0);
2482 new_attr = find_attr (new_names[i], 0);
2483 for (av = length_attr->first_value; av; av = av->next)
2484 for (ie = av->first_insn; ie; ie = ie->next)
2485 {
2486 new_av = get_attr_value (substitute_address (av->value,
2487 no_address_fn[i],
2488 address_fn[i]),
2489 new_attr, ie->insn_code);
0e9414fd 2490 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
41299f41
TW
2491 new_ie->insn_code = ie->insn_code;
2492 new_ie->insn_index = ie->insn_index;
2493 insert_insn_ent (new_av, new_ie);
2494 }
2495 }
2496}
2497
2498/* Utility functions called from above routine. */
2499
2500static rtx
2501identity_fn (exp)
2502 rtx exp;
2503{
2504 return exp;
2505}
2506
2507static rtx
2508zero_fn (exp)
d6f4ec51 2509 rtx exp ATTRIBUTE_UNUSED;
41299f41
TW
2510{
2511 return make_numeric_value (0);
2512}
2513
2514static rtx
2515one_fn (exp)
d6f4ec51 2516 rtx exp ATTRIBUTE_UNUSED;
41299f41
TW
2517{
2518 return make_numeric_value (1);
2519}
2520
2521static rtx
2522max_fn (exp)
2523 rtx exp;
2524{
7ee37ba4
RH
2525 int unknown;
2526 return make_numeric_value (max_attr_value (exp, &unknown));
41299f41 2527}
fc470718
R
2528
2529static void
2530write_length_unit_log ()
2531{
2532 struct attr_desc *length_attr = find_attr ("length", 0);
2533 struct attr_value *av;
2534 struct insn_ent *ie;
2535 unsigned int length_unit_log, length_or;
7ee37ba4 2536 int unknown = 0;
fc470718
R
2537
2538 if (length_attr == 0)
2539 return;
7ee37ba4
RH
2540 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2541 for (av = length_attr->first_value; av; av = av->next)
2542 for (ie = av->first_insn; ie; ie = ie->next)
2543 length_or |= or_attr_value (av->value, &unknown);
2544
2545 if (unknown)
2546 length_unit_log = 0;
2547 else
2548 {
2549 length_or = ~length_or;
2550 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
c9541287 2551 length_unit_log++;
7ee37ba4 2552 }
fc470718
R
2553 printf ("int length_unit_log = %u;\n", length_unit_log);
2554}
41299f41
TW
2555\f
2556/* Take a COND expression and see if any of the conditions in it can be
2557 simplified. If any are known true or known false for the particular insn
2558 code, the COND can be further simplified.
2559
2560 Also call ourselves on any COND operations that are values of this COND.
2561
7339c88d 2562 We do not modify EXP; rather, we make and return a new rtx. */
41299f41
TW
2563
2564static rtx
2565simplify_cond (exp, insn_code, insn_index)
2566 rtx exp;
2567 int insn_code, insn_index;
2568{
2569 int i, j;
7339c88d
RS
2570 /* We store the desired contents here,
2571 then build a new expression if they don't match EXP. */
2572 rtx defval = XEXP (exp, 1);
eaed7119 2573 rtx new_defval = XEXP (exp, 1);
7339c88d 2574 int len = XVECLEN (exp, 0);
b548dffb 2575 rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
7339c88d 2576 int allsame = 1;
b5b6ad46 2577 char *first_spacer;
b548dffb 2578 rtx ret;
41299f41 2579
7339c88d 2580 /* This lets us free all storage allocated below, if appropriate. */
81fd4c6e 2581 first_spacer = (char *) obstack_finish (rtl_obstack);
41299f41 2582
4e135bdd 2583 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
41299f41 2584
7339c88d
RS
2585 /* See if default value needs simplification. */
2586 if (GET_CODE (defval) == COND)
eaed7119 2587 new_defval = simplify_cond (defval, insn_code, insn_index);
41299f41 2588
81fd4c6e 2589 /* Simplify the subexpressions, and see what tests we can get rid of. */
41299f41 2590
81fd4c6e 2591 for (i = 0; i < len; i += 2)
7339c88d
RS
2592 {
2593 rtx newtest, newval;
41299f41 2594
7339c88d 2595 /* Simplify this test. */
910eabe5
JL
2596 newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index);
2597 tests[i] = newtest;
41299f41 2598
910eabe5 2599 newval = tests[i + 1];
7339c88d
RS
2600 /* See if this value may need simplification. */
2601 if (GET_CODE (newval) == COND)
2602 newval = simplify_cond (newval, insn_code, insn_index);
2603
2604 /* Look for ways to delete or combine this test. */
2605 if (newtest == true_rtx)
2606 {
2607 /* If test is true, make this value the default
2608 and discard this + any following tests. */
2609 len = i;
910eabe5 2610 defval = tests[i + 1];
eaed7119 2611 new_defval = newval;
41299f41
TW
2612 }
2613
7339c88d 2614 else if (newtest == false_rtx)
41299f41 2615 {
7339c88d
RS
2616 /* If test is false, discard it and its value. */
2617 for (j = i; j < len - 2; j++)
910eabe5 2618 tests[j] = tests[j + 2];
81fd4c6e
RS
2619 len -= 2;
2620 }
41299f41 2621
910eabe5 2622 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
81fd4c6e
RS
2623 {
2624 /* If this value and the value for the prev test are the same,
2625 merge the tests. */
2626
910eabe5
JL
2627 tests[i - 2]
2628 = insert_right_side (IOR, tests[i - 2], newtest,
81fd4c6e
RS
2629 insn_code, insn_index);
2630
2631 /* Delete this test/value. */
2632 for (j = i; j < len - 2; j++)
910eabe5 2633 tests[j] = tests[j + 2];
7339c88d 2634 len -= 2;
41299f41
TW
2635 }
2636
81fd4c6e 2637 else
910eabe5 2638 tests[i + 1] = newval;
7339c88d 2639 }
41299f41 2640
81fd4c6e
RS
2641 /* If the last test in a COND has the same value
2642 as the default value, that test isn't needed. */
2643
910eabe5 2644 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
81fd4c6e
RS
2645 len -= 2;
2646
2647 /* See if we changed anything. */
2648 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2649 allsame = 0;
2650 else
2651 for (i = 0; i < len; i++)
910eabe5 2652 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
81fd4c6e
RS
2653 {
2654 allsame = 0;
2655 break;
2656 }
41299f41 2657
7339c88d
RS
2658 if (len == 0)
2659 {
7339c88d 2660 if (GET_CODE (defval) == COND)
b548dffb
ZW
2661 ret = simplify_cond (defval, insn_code, insn_index);
2662 else
2663 ret = defval;
7339c88d 2664 }
81fd4c6e 2665 else if (allsame)
b548dffb 2666 ret = exp;
7339c88d
RS
2667 else
2668 {
81fd4c6e 2669 rtx newexp = rtx_alloc (COND);
7339c88d
RS
2670
2671 XVEC (newexp, 0) = rtvec_alloc (len);
4e135bdd 2672 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
81fd4c6e 2673 XEXP (newexp, 1) = new_defval;
b548dffb 2674 ret = newexp;
41299f41 2675 }
b548dffb
ZW
2676 free (tests);
2677 return ret;
41299f41
TW
2678}
2679\f
2680/* Remove an insn entry from an attribute value. */
2681
2682static void
2683remove_insn_ent (av, ie)
2684 struct attr_value *av;
2685 struct insn_ent *ie;
2686{
2687 struct insn_ent *previe;
2688
2689 if (av->first_insn == ie)
2690 av->first_insn = ie->next;
2691 else
2692 {
2693 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2694 ;
2695 previe->next = ie->next;
2696 }
2697
2698 av->num_insns--;
2699 if (ie->insn_code == -1)
2700 av->has_asm_insn = 0;
1c69865d
ILT
2701
2702 num_insn_ents--;
41299f41
TW
2703}
2704
2705/* Insert an insn entry in an attribute value list. */
2706
2707static void
2708insert_insn_ent (av, ie)
2709 struct attr_value *av;
2710 struct insn_ent *ie;
2711{
2712 ie->next = av->first_insn;
2713 av->first_insn = ie;
2714 av->num_insns++;
2715 if (ie->insn_code == -1)
2716 av->has_asm_insn = 1;
1c69865d
ILT
2717
2718 num_insn_ents++;
41299f41
TW
2719}
2720\f
2721/* This is a utility routine to take an expression that is a tree of either
2722 AND or IOR expressions and insert a new term. The new term will be
2723 inserted at the right side of the first node whose code does not match
2724 the root. A new node will be created with the root's code. Its left
2725 side will be the old right side and its right side will be the new
2726 term.
2727
2728 If the `term' is itself a tree, all its leaves will be inserted. */
2729
2730static rtx
2731insert_right_side (code, exp, term, insn_code, insn_index)
f75d38a7 2732 enum rtx_code code;
41299f41
TW
2733 rtx exp;
2734 rtx term;
2735 int insn_code, insn_index;
2736{
2737 rtx newexp;
2738
7339c88d
RS
2739 /* Avoid consing in some special cases. */
2740 if (code == AND && term == true_rtx)
2741 return exp;
2742 if (code == AND && term == false_rtx)
2743 return false_rtx;
2744 if (code == AND && exp == true_rtx)
2745 return term;
2746 if (code == AND && exp == false_rtx)
2747 return false_rtx;
2748 if (code == IOR && term == true_rtx)
2749 return true_rtx;
2750 if (code == IOR && term == false_rtx)
2751 return exp;
2752 if (code == IOR && exp == true_rtx)
2753 return true_rtx;
2754 if (code == IOR && exp == false_rtx)
2755 return term;
81fd4c6e 2756 if (attr_equal_p (exp, term))
7339c88d
RS
2757 return exp;
2758
41299f41
TW
2759 if (GET_CODE (term) == code)
2760 {
2761 exp = insert_right_side (code, exp, XEXP (term, 0),
2762 insn_code, insn_index);
2763 exp = insert_right_side (code, exp, XEXP (term, 1),
2764 insn_code, insn_index);
2765
2766 return exp;
2767 }
2768
2769 if (GET_CODE (exp) == code)
2770 {
7339c88d
RS
2771 rtx new = insert_right_side (code, XEXP (exp, 1),
2772 term, insn_code, insn_index);
2773 if (new != XEXP (exp, 1))
2774 /* Make a copy of this expression and call recursively. */
2775 newexp = attr_rtx (code, XEXP (exp, 0), new);
2776 else
2777 newexp = exp;
41299f41
TW
2778 }
2779 else
2780 {
2781 /* Insert the new term. */
3e7b5313 2782 newexp = attr_rtx (code, exp, term);
7339c88d 2783 }
41299f41
TW
2784
2785 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2786}
2787\f
2788/* If we have an expression which AND's a bunch of
2789 (not (eq_attrq "alternative" "n"))
2790 terms, we may have covered all or all but one of the possible alternatives.
2791 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2792
2793 This routine is passed an expression and either AND or IOR. It returns a
f75d38a7 2794 bitmask indicating which alternatives are mentioned within EXP. */
41299f41
TW
2795
2796static int
2797compute_alternative_mask (exp, code)
2798 rtx exp;
f75d38a7 2799 enum rtx_code code;
41299f41 2800{
3cce094d 2801 const char *string;
41299f41
TW
2802 if (GET_CODE (exp) == code)
2803 return compute_alternative_mask (XEXP (exp, 0), code)
2804 | compute_alternative_mask (XEXP (exp, 1), code);
2805
2806 else if (code == AND && GET_CODE (exp) == NOT
2807 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2808 && XSTR (XEXP (exp, 0), 0) == alternative_name)
b31a5831 2809 string = XSTR (XEXP (exp, 0), 1);
41299f41
TW
2810
2811 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2812 && XSTR (exp, 0) == alternative_name)
b31a5831 2813 string = XSTR (exp, 1);
41299f41
TW
2814
2815 else
2816 return 0;
b31a5831
RS
2817
2818 if (string[1] == 0)
2819 return 1 << (string[0] - '0');
2820 return 1 << atoi (string);
41299f41
TW
2821}
2822
2823/* Given I, a single-bit mask, return RTX to compare the `alternative'
2824 attribute with the value represented by that bit. */
2825
2826static rtx
2827make_alternative_compare (mask)
2828 int mask;
2829{
2830 rtx newexp;
2831 int i;
41299f41
TW
2832
2833 /* Find the bit. */
2834 for (i = 0; (mask & (1 << i)) == 0; i++)
2835 ;
2836
81fd4c6e 2837 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
41299f41
TW
2838 RTX_UNCHANGING_P (newexp) = 1;
2839
2840 return newexp;
2841}
2842\f
2843/* If we are processing an (eq_attr "attr" "value") test, we find the value
2844 of "attr" for this insn code. From that value, we can compute a test
2845 showing when the EQ_ATTR will be true. This routine performs that
2846 computation. If a test condition involves an address, we leave the EQ_ATTR
c9541287 2847 intact because addresses are only valid for the `length' attribute.
41299f41 2848
f75d38a7
RK
2849 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2850 for the insn corresponding to INSN_CODE and INSN_INDEX. */
7339c88d 2851
41299f41
TW
2852static rtx
2853evaluate_eq_attr (exp, value, insn_code, insn_index)
2854 rtx exp;
2855 rtx value;
2856 int insn_code, insn_index;
2857{
2858 rtx orexp, andexp;
2859 rtx right;
2860 rtx newexp;
2861 int i;
2862
2863 if (GET_CODE (value) == CONST_STRING)
2864 {
2865 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2866 newexp = true_rtx;
2867 else
2868 newexp = false_rtx;
2869 }
71d9b493
RH
2870 else if (GET_CODE (value) == SYMBOL_REF)
2871 {
b548dffb
ZW
2872 char *p;
2873 char string[256];
71d9b493
RH
2874
2875 if (GET_CODE (exp) != EQ_ATTR)
c9541287 2876 abort ();
71d9b493 2877
b548dffb
ZW
2878 if (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 > 256)
2879 abort ();
2880
71d9b493
RH
2881 strcpy (string, XSTR (exp, 0));
2882 strcat (string, "_");
2883 strcat (string, XSTR (exp, 1));
c9541287 2884 for (p = string; *p; p++)
92a438d1 2885 *p = TOUPPER (*p);
c9541287 2886
71d9b493
RH
2887 newexp = attr_rtx (EQ, value,
2888 attr_rtx (SYMBOL_REF,
c9541287 2889 attr_string (string, strlen (string))));
71d9b493 2890 }
41299f41
TW
2891 else if (GET_CODE (value) == COND)
2892 {
2893 /* We construct an IOR of all the cases for which the requested attribute
2894 value is present. Since we start with FALSE, if it is not present,
2895 FALSE will be returned.
2896
2897 Each case is the AND of the NOT's of the previous conditions with the
c9541287 2898 current condition; in the default case the current condition is TRUE.
41299f41
TW
2899
2900 For each possible COND value, call ourselves recursively.
2901
2902 The extra TRUE and FALSE expressions will be eliminated by another
0f41302f 2903 call to the simplification routine. */
41299f41
TW
2904
2905 orexp = false_rtx;
2906 andexp = true_rtx;
2907
3715a518
RS
2908 if (current_alternative_string)
2909 clear_struct_flag (value);
2910
41299f41
TW
2911 for (i = 0; i < XVECLEN (value, 0); i += 2)
2912 {
7339c88d
RS
2913 rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
2914 insn_code, insn_index);
2915
3715a518
RS
2916 SIMPLIFY_ALTERNATIVE (this);
2917
7339c88d 2918 right = insert_right_side (AND, andexp, this,
41299f41
TW
2919 insn_code, insn_index);
2920 right = insert_right_side (AND, right,
f75d38a7
RK
2921 evaluate_eq_attr (exp,
2922 XVECEXP (value, 0,
2923 i + 1),
2924 insn_code, insn_index),
41299f41
TW
2925 insn_code, insn_index);
2926 orexp = insert_right_side (IOR, orexp, right,
2927 insn_code, insn_index);
2928
2929 /* Add this condition into the AND expression. */
7339c88d 2930 newexp = attr_rtx (NOT, this);
41299f41
TW
2931 andexp = insert_right_side (AND, andexp, newexp,
2932 insn_code, insn_index);
2933 }
2934
2935 /* Handle the default case. */
2936 right = insert_right_side (AND, andexp,
2937 evaluate_eq_attr (exp, XEXP (value, 1),
f75d38a7 2938 insn_code, insn_index),
41299f41
TW
2939 insn_code, insn_index);
2940 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2941 }
2942 else
2943 abort ();
2944
052aaaef
RK
2945 /* If uses an address, must return original expression. But set the
2946 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
41299f41
TW
2947
2948 address_used = 0;
2949 walk_attr_value (newexp);
2950
2951 if (address_used)
052aaaef 2952 {
45044655
RS
2953 /* This had `&& current_alternative_string', which seems to be wrong. */
2954 if (! RTX_UNCHANGING_P (exp))
7339c88d 2955 return copy_rtx_unchanging (exp);
052aaaef
RK
2956 return exp;
2957 }
41299f41
TW
2958 else
2959 return newexp;
2960}
2961\f
2962/* This routine is called when an AND of a term with a tree of AND's is
2963 encountered. If the term or its complement is present in the tree, it
2964 can be replaced with TRUE or FALSE, respectively.
2965
2966 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
c9541287 2967 be true and hence are complementary.
41299f41
TW
2968
2969 There is one special case: If we see
2970 (and (not (eq_attr "att" "v1"))
2971 (eq_attr "att" "v2"))
2972 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2973 replace the term, not anything in the AND tree. So we pass a pointer to
2974 the term. */
2975
2976static rtx
2977simplify_and_tree (exp, pterm, insn_code, insn_index)
2978 rtx exp;
2979 rtx *pterm;
2980 int insn_code, insn_index;
2981{
2982 rtx left, right;
2983 rtx newexp;
2984 rtx temp;
2985 int left_eliminates_term, right_eliminates_term;
2986
2987 if (GET_CODE (exp) == AND)
2988 {
c9541287 2989 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
41299f41
TW
2990 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2991 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2992 {
3e7b5313 2993 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41
TW
2994
2995 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2996 }
2997 }
2998
2999 else if (GET_CODE (exp) == IOR)
3000 {
3001 /* For the IOR case, we do the same as above, except that we can
3002 only eliminate `term' if both sides of the IOR would do so. */
3003 temp = *pterm;
c9541287 3004 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
41299f41
TW
3005 left_eliminates_term = (temp == true_rtx);
3006
3007 temp = *pterm;
3008 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3009 right_eliminates_term = (temp == true_rtx);
3010
3011 if (left_eliminates_term && right_eliminates_term)
3012 *pterm = true_rtx;
3013
3014 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3015 {
3e7b5313 3016 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41
TW
3017
3018 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3019 }
3020 }
3021
3022 /* Check for simplifications. Do some extra checking here since this
3023 routine is called so many times. */
3024
3025 if (exp == *pterm)
3026 return true_rtx;
3027
3028 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
3029 return false_rtx;
3030
3031 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
3032 return false_rtx;
3033
3034 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
3035 {
3036 if (XSTR (exp, 0) != XSTR (*pterm, 0))
3037 return exp;
3038
3039 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
3040 return true_rtx;
3041 else
3042 return false_rtx;
3043 }
3044
3045 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3046 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3047 {
3048 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3049 return exp;
3050
3051 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3052 return false_rtx;
3053 else
3054 return true_rtx;
3055 }
3056
3057 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3058 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3059 {
3060 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3061 return exp;
3062
3063 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3064 return false_rtx;
3065 else
3066 *pterm = true_rtx;
3067 }
3068
3069 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3070 {
81fd4c6e 3071 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
41299f41
TW
3072 return true_rtx;
3073 }
3074
3075 else if (GET_CODE (exp) == NOT)
3076 {
81fd4c6e 3077 if (attr_equal_p (XEXP (exp, 0), *pterm))
41299f41
TW
3078 return false_rtx;
3079 }
3080
3081 else if (GET_CODE (*pterm) == NOT)
3082 {
81fd4c6e 3083 if (attr_equal_p (XEXP (*pterm, 0), exp))
41299f41
TW
3084 return false_rtx;
3085 }
3086
81fd4c6e 3087 else if (attr_equal_p (exp, *pterm))
41299f41
TW
3088 return true_rtx;
3089
3090 return exp;
3091}
3092\f
6dc42e49 3093/* Similar to `simplify_and_tree', but for IOR trees. */
41299f41
TW
3094
3095static rtx
3096simplify_or_tree (exp, pterm, insn_code, insn_index)
3097 rtx exp;
3098 rtx *pterm;
3099 int insn_code, insn_index;
3100{
3101 rtx left, right;
3102 rtx newexp;
3103 rtx temp;
3104 int left_eliminates_term, right_eliminates_term;
3105
3106 if (GET_CODE (exp) == IOR)
3107 {
c9541287 3108 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
41299f41
TW
3109 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3110 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3111 {
3e7b5313 3112 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41
TW
3113
3114 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3115 }
3116 }
3117
3118 else if (GET_CODE (exp) == AND)
3119 {
3120 /* For the AND case, we do the same as above, except that we can
3121 only eliminate `term' if both sides of the AND would do so. */
3122 temp = *pterm;
c9541287 3123 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
41299f41
TW
3124 left_eliminates_term = (temp == false_rtx);
3125
3126 temp = *pterm;
3127 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3128 right_eliminates_term = (temp == false_rtx);
3129
3130 if (left_eliminates_term && right_eliminates_term)
3131 *pterm = false_rtx;
3132
3133 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3134 {
3e7b5313 3135 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41
TW
3136
3137 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3138 }
3139 }
3140
81fd4c6e 3141 if (attr_equal_p (exp, *pterm))
41299f41
TW
3142 return false_rtx;
3143
81fd4c6e 3144 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
41299f41
TW
3145 return true_rtx;
3146
81fd4c6e 3147 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
41299f41
TW
3148 return true_rtx;
3149
3150 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3151 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3152 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3153 *pterm = false_rtx;
3154
3155 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3156 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3157 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3158 return false_rtx;
3159
3160 return exp;
3161}
2bed3391
JH
3162/* Compute approximate cost of the expression. Used to decide whether
3163 expression is cheap enought for inline. */
3164static int
3165attr_rtx_cost (x)
3166 rtx x;
3167{
3168 int cost = 0;
3169 enum rtx_code code;
3170 if (!x)
3171 return 0;
3172 code = GET_CODE (x);
3173 switch (code)
3174 {
3175 case MATCH_OPERAND:
3176 if (XSTR (x, 1)[0])
3177 return 10;
3178 else
3179 return 0;
3180 case EQ_ATTR:
3181 /* Alternatives don't result into function call. */
3182 if (!strcmp (XSTR (x, 0), "alternative"))
3183 return 0;
3184 else
3185 return 5;
3186 default:
3187 {
3188 int i, j;
3189 const char *fmt = GET_RTX_FORMAT (code);
3190 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3191 {
3192 switch (fmt[i])
3193 {
3194 case 'V':
3195 case 'E':
3196 for (j = 0; j < XVECLEN (x, i); j++)
3197 cost += attr_rtx_cost (XVECEXP (x, i, j));
3198 break;
3199 case 'e':
3200 cost += attr_rtx_cost (XEXP (x, i));
3201 break;
3202 }
3203 }
3204 }
3205 break;
3206 }
3207 return cost;
3208}
41299f41
TW
3209\f
3210/* Given an expression, see if it can be simplified for a particular insn
3211 code based on the values of other attributes being tested. This can
3212 eliminate nested get_attr_... calls.
3213
c9541287 3214 Note that if an endless recursion is specified in the patterns, the
41299f41
TW
3215 optimization will loop. However, it will do so in precisely the cases where
3216 an infinite recursion loop could occur during compilation. It's better that
3217 it occurs here! */
3218
3219static rtx
3220simplify_test_exp (exp, insn_code, insn_index)
3221 rtx exp;
3222 int insn_code, insn_index;
3223{
3224 rtx left, right;
3225 struct attr_desc *attr;
3226 struct attr_value *av;
3227 struct insn_ent *ie;
3228 int i;
3229 rtx newexp = exp;
7339c88d 3230
7339c88d 3231 /* Don't re-simplify something we already simplified. */
85093b9c 3232 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
7339c88d 3233 return exp;
41299f41
TW
3234
3235 switch (GET_CODE (exp))
3236 {
3237 case AND:
61abc2ca 3238 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3715a518
RS
3239 SIMPLIFY_ALTERNATIVE (left);
3240 if (left == false_rtx)
1f8f4a0b 3241 return false_rtx;
61abc2ca 3242 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3715a518
RS
3243 SIMPLIFY_ALTERNATIVE (right);
3244 if (left == false_rtx)
1f8f4a0b 3245 return false_rtx;
61abc2ca
RS
3246
3247 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3248 present on both sides, apply the distributive law since this will
3249 yield simplifications. */
3250 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3251 && compute_alternative_mask (left, IOR)
3252 && compute_alternative_mask (right, IOR))
41299f41 3253 {
61abc2ca 3254 if (GET_CODE (left) == IOR)
41299f41 3255 {
61abc2ca
RS
3256 rtx tem = left;
3257 left = right;
3258 right = tem;
3259 }
3260
3261 newexp = attr_rtx (IOR,
3262 attr_rtx (AND, left, XEXP (right, 0)),
3263 attr_rtx (AND, left, XEXP (right, 1)));
3264
3265 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3266 }
3267
3268 /* Try with the term on both sides. */
3269 right = simplify_and_tree (right, &left, insn_code, insn_index);
3270 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3271 left = simplify_and_tree (left, &right, insn_code, insn_index);
3272
3273 if (left == false_rtx || right == false_rtx)
1f8f4a0b 3274 return false_rtx;
61abc2ca
RS
3275 else if (left == true_rtx)
3276 {
85093b9c 3277 return right;
61abc2ca
RS
3278 }
3279 else if (right == true_rtx)
3280 {
85093b9c 3281 return left;
61abc2ca 3282 }
61abc2ca
RS
3283 /* See if all or all but one of the insn's alternatives are specified
3284 in this tree. Optimize if so. */
3285
3286 else if (insn_code >= 0
3287 && (GET_CODE (left) == AND
3288 || (GET_CODE (left) == NOT
3289 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3290 && XSTR (XEXP (left, 0), 0) == alternative_name)
3291 || GET_CODE (right) == AND
3292 || (GET_CODE (right) == NOT
3293 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3294 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3295 {
3296 i = compute_alternative_mask (exp, AND);
3297 if (i & ~insn_alternatives[insn_code])
9916c524 3298 fatal ("Invalid alternative specified for pattern number %d",
61abc2ca
RS
3299 insn_index);
3300
0f41302f 3301 /* If all alternatives are excluded, this is false. */
61abc2ca
RS
3302 i ^= insn_alternatives[insn_code];
3303 if (i == 0)
3304 return false_rtx;
3305 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3306 {
3307 /* If just one excluded, AND a comparison with that one to the
3308 front of the tree. The others will be eliminated by
3309 optimization. We do not want to do this if the insn has one
3310 alternative and we have tested none of them! */
3311 left = make_alternative_compare (i);
3312 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3313 newexp = attr_rtx (AND, left, right);
41299f41
TW
3314
3315 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3316 }
3317 }
61abc2ca
RS
3318
3319 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3320 {
3321 newexp = attr_rtx (AND, left, right);
3322 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3323 }
3324 break;
41299f41
TW
3325
3326 case IOR:
61abc2ca 3327 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3715a518
RS
3328 SIMPLIFY_ALTERNATIVE (left);
3329 if (left == true_rtx)
1f8f4a0b 3330 return true_rtx;
61abc2ca 3331 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3715a518
RS
3332 SIMPLIFY_ALTERNATIVE (right);
3333 if (right == true_rtx)
1f8f4a0b 3334 return true_rtx;
61abc2ca
RS
3335
3336 right = simplify_or_tree (right, &left, insn_code, insn_index);
3337 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3338 left = simplify_or_tree (left, &right, insn_code, insn_index);
3339
3340 if (right == true_rtx || left == true_rtx)
1f8f4a0b 3341 return true_rtx;
61abc2ca
RS
3342 else if (left == false_rtx)
3343 {
85093b9c 3344 return right;
61abc2ca
RS
3345 }
3346 else if (right == false_rtx)
3347 {
85093b9c 3348 return left;
61abc2ca
RS
3349 }
3350
3351 /* Test for simple cases where the distributive law is useful. I.e.,
3352 convert (ior (and (x) (y))
3353 (and (x) (z)))
3354 to (and (x)
3355 (ior (y) (z)))
3356 */
3357
3358 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
c9541287 3359 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
61abc2ca
RS
3360 {
3361 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3362
3363 left = XEXP (left, 0);
3364 right = newexp;
3365 newexp = attr_rtx (AND, left, right);
3366 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3367 }
3368
3369 /* See if all or all but one of the insn's alternatives are specified
3370 in this tree. Optimize if so. */
3371
3372 else if (insn_code >= 0
c9541287
KH
3373 && (GET_CODE (left) == IOR
3374 || (GET_CODE (left) == EQ_ATTR
3375 && XSTR (left, 0) == alternative_name)
3376 || GET_CODE (right) == IOR
3377 || (GET_CODE (right) == EQ_ATTR
3378 && XSTR (right, 0) == alternative_name)))
61abc2ca
RS
3379 {
3380 i = compute_alternative_mask (exp, IOR);
3381 if (i & ~insn_alternatives[insn_code])
9916c524 3382 fatal ("Invalid alternative specified for pattern number %d",
61abc2ca
RS
3383 insn_index);
3384
0f41302f 3385 /* If all alternatives are included, this is true. */
61abc2ca
RS
3386 i ^= insn_alternatives[insn_code];
3387 if (i == 0)
3388 return true_rtx;
3389 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3390 {
3391 /* If just one excluded, IOR a comparison with that one to the
3392 front of the tree. The others will be eliminated by
3393 optimization. We do not want to do this if the insn has one
3394 alternative and we have tested none of them! */
3395 left = make_alternative_compare (i);
3396 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3397 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3398
3399 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3400 }
3401 }
3402
3403 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3404 {
3405 newexp = attr_rtx (IOR, left, right);
3406 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3407 }
3408 break;
41299f41
TW
3409
3410 case NOT:
7339c88d 3411 if (GET_CODE (XEXP (exp, 0)) == NOT)
3715a518
RS
3412 {
3413 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3414 insn_code, insn_index);
3415 SIMPLIFY_ALTERNATIVE (left);
3416 return left;
3417 }
3418
41299f41 3419 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3715a518 3420 SIMPLIFY_ALTERNATIVE (left);
41299f41
TW
3421 if (GET_CODE (left) == NOT)
3422 return XEXP (left, 0);
3423
3424 if (left == false_rtx)
1f8f4a0b 3425 return true_rtx;
41299f41 3426 else if (left == true_rtx)
1f8f4a0b 3427 return false_rtx;
41299f41
TW
3428
3429 /* Try to apply De`Morgan's laws. */
3430 else if (GET_CODE (left) == IOR)
3431 {
3e7b5313
TW
3432 newexp = attr_rtx (AND,
3433 attr_rtx (NOT, XEXP (left, 0)),
3434 attr_rtx (NOT, XEXP (left, 1)));
41299f41
TW
3435
3436 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3437 }
3438 else if (GET_CODE (left) == AND)
3439 {
3e7b5313
TW
3440 newexp = attr_rtx (IOR,
3441 attr_rtx (NOT, XEXP (left, 0)),
3442 attr_rtx (NOT, XEXP (left, 1)));
41299f41
TW
3443
3444 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3445 }
3446 else if (left != XEXP (exp, 0))
3447 {
3e7b5313 3448 newexp = attr_rtx (NOT, left);
41299f41
TW
3449 }
3450 break;
3451
3452 case EQ_ATTR:
3715a518
RS
3453 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3454 return (XSTR (exp, 1) == current_alternative_string
3455 ? true_rtx : false_rtx);
c9541287 3456
41299f41
TW
3457 /* Look at the value for this insn code in the specified attribute.
3458 We normally can replace this comparison with the condition that
3459 would give this insn the values being tested for. */
3460 if (XSTR (exp, 0) != alternative_name
3461 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3462 for (av = attr->first_value; av; av = av->next)
3463 for (ie = av->first_insn; ie; ie = ie->next)
3464 if (ie->insn_code == insn_code)
2bed3391
JH
3465 {
3466 rtx x;
3467 struct obstack *old = rtl_obstack;
3468 rtl_obstack = temp_obstack;
3469 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3470 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
3471 rtl_obstack = old;
3472 if (attr_rtx_cost(x) < 20)
3473 return attr_copy_rtx (x);
3474 }
e9a25f70 3475 break;
c9541287 3476
e9a25f70
JL
3477 default:
3478 break;
41299f41
TW
3479 }
3480
3481 /* We have already simplified this expression. Simplifying it again
3482 won't buy anything unless we weren't given a valid insn code
3483 to process (i.e., we are canonicalizing something.). */
45044655 3484 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3715a518
RS
3485 && ! RTX_UNCHANGING_P (newexp))
3486 return copy_rtx_unchanging (newexp);
41299f41
TW
3487
3488 return newexp;
3489}
3490\f
3491/* Optimize the attribute lists by seeing if we can determine conditional
3492 values from the known values of other attributes. This will save subroutine
3493 calls during the compilation. */
3494
3495static void
3496optimize_attrs ()
3497{
3498 struct attr_desc *attr;
3499 struct attr_value *av;
b5b6ad46 3500 struct insn_ent *ie;
41299f41
TW
3501 rtx newexp;
3502 int something_changed = 1;
85093b9c 3503 int i;
c9541287
KH
3504 struct attr_value_list
3505 {
3506 struct attr_value *av;
3507 struct insn_ent *ie;
3508 struct attr_desc *attr;
3509 struct attr_value_list *next;
3510 };
85093b9c 3511 struct attr_value_list **insn_code_values;
1c69865d 3512 struct attr_value_list *ivbuf;
85093b9c
RS
3513 struct attr_value_list *iv;
3514
3515 /* For each insn code, make a list of all the insn_ent's for it,
3516 for all values for all attributes. */
3517
bd1b0893
ILT
3518 if (num_insn_ents == 0)
3519 return;
3520
85093b9c
RS
3521 /* Make 2 extra elements, for "code" values -2 and -1. */
3522 insn_code_values
b548dffb 3523 = (struct attr_value_list **) xmalloc ((insn_code_number + 2)
85093b9c 3524 * sizeof (struct attr_value_list *));
961192e1 3525 memset ((char *) insn_code_values, 0,
85093b9c 3526 (insn_code_number + 2) * sizeof (struct attr_value_list *));
4c9a05bc 3527
85093b9c
RS
3528 /* Offset the table address so we can index by -2 or -1. */
3529 insn_code_values += 2;
3530
1c69865d
ILT
3531 iv = ivbuf = ((struct attr_value_list *)
3532 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3533
3715a518
RS
3534 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3535 for (attr = attrs[i]; attr; attr = attr->next)
3536 for (av = attr->first_value; av; av = av->next)
3537 for (ie = av->first_insn; ie; ie = ie->next)
3538 {
3715a518
RS
3539 iv->attr = attr;
3540 iv->av = av;
3541 iv->ie = ie;
3542 iv->next = insn_code_values[ie->insn_code];
3543 insn_code_values[ie->insn_code] = iv;
1c69865d 3544 iv++;
3715a518 3545 }
41299f41 3546
1c69865d
ILT
3547 /* Sanity check on num_insn_ents. */
3548 if (iv != ivbuf + num_insn_ents)
3549 abort ();
3550
3715a518
RS
3551 /* Process one insn code at a time. */
3552 for (i = -2; i < insn_code_number; i++)
41299f41 3553 {
3715a518
RS
3554 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3555 We use it to mean "already simplified for this insn". */
3556 for (iv = insn_code_values[i]; iv; iv = iv->next)
3557 clear_struct_flag (iv->av->value);
3558
3559 /* Loop until nothing changes for one iteration. */
3560 something_changed = 1;
3561 while (something_changed)
85093b9c 3562 {
3715a518 3563 something_changed = 0;
85093b9c
RS
3564 for (iv = insn_code_values[i]; iv; iv = iv->next)
3565 {
3566 struct obstack *old = rtl_obstack;
85093b9c
RS
3567
3568 attr = iv->attr;
3569 av = iv->av;
3570 ie = iv->ie;
3571 if (GET_CODE (av->value) != COND)
3572 continue;
3573
3574 rtl_obstack = temp_obstack;
3715a518
RS
3575#if 0 /* This was intended as a speed up, but it was slower. */
3576 if (insn_n_alternatives[ie->insn_code] > 6
3577 && count_sub_rtxs (av->value, 200) >= 200)
3578 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3579 ie->insn_index);
3580 else
3581#endif
3582 newexp = simplify_cond (av->value, ie->insn_code,
3583 ie->insn_index);
3584
85093b9c
RS
3585 rtl_obstack = old;
3586 if (newexp != av->value)
3587 {
3588 newexp = attr_copy_rtx (newexp);
3589 remove_insn_ent (av, ie);
3590 av = get_attr_value (newexp, attr, ie->insn_code);
3591 iv->av = av;
3592 insert_insn_ent (av, ie);
3593 something_changed = 1;
3594 }
85093b9c
RS
3595 }
3596 }
3597 }
1c69865d
ILT
3598
3599 free (ivbuf);
b548dffb 3600 free (insn_code_values - 2);
85093b9c
RS
3601}
3602
b5b6ad46 3603#if 0
3715a518
RS
3604static rtx
3605simplify_by_alternatives (exp, insn_code, insn_index)
3606 rtx exp;
3607 int insn_code, insn_index;
3608{
3609 int i;
3610 int len = insn_n_alternatives[insn_code];
3611 rtx newexp = rtx_alloc (COND);
3612 rtx ultimate;
3613
3715a518
RS
3614 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3615
3616 /* It will not matter what value we use as the default value
3617 of the new COND, since that default will never be used.
3618 Choose something of the right type. */
3619 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3620 ultimate = XEXP (ultimate, 1);
3621 XEXP (newexp, 1) = ultimate;
3622
3623 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3624 {
3625 current_alternative_string = attr_numeral (i);
3626 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3627 XVECEXP (newexp, 0, i * 2 + 1)
3628 = simplify_cond (exp, insn_code, insn_index);
3629 }
3630
3631 current_alternative_string = 0;
3632 return simplify_cond (newexp, insn_code, insn_index);
3633}
b5b6ad46 3634#endif
3715a518 3635\f
72f1215c
TW
3636/* If EXP is a suitable expression, reorganize it by constructing an
3637 equivalent expression that is a COND with the tests being all combinations
3638 of attribute values and the values being simple constants. */
3639
3640static rtx
3641simplify_by_exploding (exp)
3642 rtx exp;
3643{
aefdd5ab 3644 rtx list = 0, link, condexp, defval = NULL_RTX;
72f1215c
TW
3645 struct dimension *space;
3646 rtx *condtest, *condval;
bee757e1 3647 int i, j, total, ndim = 0;
72f1215c 3648 int most_tests, num_marks, new_marks;
b548dffb 3649 rtx ret;
72f1215c
TW
3650
3651 /* Locate all the EQ_ATTR expressions. */
bee757e1 3652 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
72f1215c
TW
3653 {
3654 unmark_used_attributes (list, 0, 0);
3655 return exp;
3656 }
3657
3658 /* Create an attribute space from the list of used attributes. For each
3659 dimension in the attribute space, record the attribute, list of values
3660 used, and number of values used. Add members to the list of values to
3661 cover the domain of the attribute. This makes the expanded COND form
3662 order independent. */
3663
b548dffb 3664 space = (struct dimension *) xmalloc (ndim * sizeof (struct dimension));
72f1215c
TW
3665
3666 total = 1;
3667 for (ndim = 0; list; ndim++)
3668 {
3669 /* Pull the first attribute value from the list and record that
3670 attribute as another dimension in the attribute space. */
3cce094d 3671 const char *name = XSTR (XEXP (list, 0), 0);
72f1215c
TW
3672 rtx *prev;
3673
3674 if ((space[ndim].attr = find_attr (name, 0)) == 0
3675 || space[ndim].attr->is_numeric)
3676 {
3677 unmark_used_attributes (list, space, ndim);
3678 return exp;
3679 }
3680
3681 /* Add all remaining attribute values that refer to this attribute. */
3682 space[ndim].num_values = 0;
3683 space[ndim].values = 0;
3684 prev = &list;
3685 for (link = list; link; link = *prev)
3686 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3687 {
3688 space[ndim].num_values++;
3689 *prev = XEXP (link, 1);
3690 XEXP (link, 1) = space[ndim].values;
3691 space[ndim].values = link;
3692 }
3693 else
3694 prev = &XEXP (link, 1);
3695
3696 /* Add sufficient members to the list of values to make the list
3697 mutually exclusive and record the total size of the attribute
3698 space. */
3699 total *= add_values_to_cover (&space[ndim]);
3700 }
3701
3702 /* Sort the attribute space so that the attributes go from non-constant
3703 to constant and from most values to least values. */
3704 for (i = 0; i < ndim; i++)
3705 for (j = ndim - 1; j > i; j--)
3706 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3707 || space[j-1].num_values < space[j].num_values)
3708 {
3709 struct dimension tmp;
3710 tmp = space[j];
c9541287
KH
3711 space[j] = space[j - 1];
3712 space[j - 1] = tmp;
72f1215c
TW
3713 }
3714
3715 /* Establish the initial current value. */
3716 for (i = 0; i < ndim; i++)
3717 space[i].current_value = space[i].values;
3718
b548dffb
ZW
3719 condtest = (rtx *) xmalloc (total * sizeof (rtx));
3720 condval = (rtx *) xmalloc (total * sizeof (rtx));
72f1215c
TW
3721
3722 /* Expand the tests and values by iterating over all values in the
3723 attribute space. */
3724 for (i = 0;; i++)
3725 {
3726 condtest[i] = test_for_current_value (space, ndim);
3727 condval[i] = simplify_with_current_value (exp, space, ndim);
3728 if (! increment_current_value (space, ndim))
3729 break;
3730 }
3731 if (i != total - 1)
3732 abort ();
3733
3734 /* We are now finished with the original expression. */
3735 unmark_used_attributes (0, space, ndim);
b548dffb 3736 free (space);
72f1215c
TW
3737
3738 /* Find the most used constant value and make that the default. */
3739 most_tests = -1;
3740 for (i = num_marks = 0; i < total; i++)
3741 if (GET_CODE (condval[i]) == CONST_STRING
3742 && ! MEM_VOLATILE_P (condval[i]))
3743 {
3744 /* Mark the unmarked constant value and count how many are marked. */
3745 MEM_VOLATILE_P (condval[i]) = 1;
3746 for (j = new_marks = 0; j < total; j++)
3747 if (GET_CODE (condval[j]) == CONST_STRING
3748 && MEM_VOLATILE_P (condval[j]))
3749 new_marks++;
3750 if (new_marks - num_marks > most_tests)
3751 {
3752 most_tests = new_marks - num_marks;
3753 defval = condval[i];
3754 }
3755 num_marks = new_marks;
3756 }
3757 /* Clear all the marks. */
3758 for (i = 0; i < total; i++)
3759 MEM_VOLATILE_P (condval[i]) = 0;
3760
3761 /* Give up if nothing is constant. */
3762 if (num_marks == 0)
b548dffb
ZW
3763 ret = exp;
3764
bee757e1 3765 /* If all values are the default, use that. */
b548dffb
ZW
3766 else if (total == most_tests)
3767 ret = defval;
bee757e1 3768
72f1215c
TW
3769 /* Make a COND with the most common constant value the default. (A more
3770 complex method where tests with the same value were combined didn't
3771 seem to improve things.) */
b548dffb
ZW
3772 else
3773 {
3774 condexp = rtx_alloc (COND);
3775 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3776 XEXP (condexp, 1) = defval;
3777 for (i = j = 0; i < total; i++)
3778 if (condval[i] != defval)
3779 {
3780 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3781 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3782 j++;
3783 }
3784 ret = condexp;
3785 }
3786 free (condtest);
3787 free (condval);
3788 return ret;
72f1215c
TW
3789}
3790
3791/* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3792 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3793 tests have known value. */
3794
3795static int
bee757e1 3796find_and_mark_used_attributes (exp, terms, nterms)
72f1215c 3797 rtx exp, *terms;
bee757e1 3798 int *nterms;
72f1215c
TW
3799{
3800 int i;
3801
3802 switch (GET_CODE (exp))
3803 {
3804 case EQ_ATTR:
3805 if (! MEM_VOLATILE_P (exp))
3806 {
3807 rtx link = rtx_alloc (EXPR_LIST);
3808 XEXP (link, 0) = exp;
3809 XEXP (link, 1) = *terms;
3810 *terms = link;
bee757e1 3811 *nterms += 1;
72f1215c
TW
3812 MEM_VOLATILE_P (exp) = 1;
3813 }
7ee37ba4
RH
3814 return 1;
3815
72f1215c 3816 case CONST_STRING:
5830e3a0 3817 case CONST_INT:
72f1215c
TW
3818 return 1;
3819
3820 case IF_THEN_ELSE:
bee757e1 3821 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
72f1215c
TW
3822 return 0;
3823 case IOR:
3824 case AND:
bee757e1 3825 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
72f1215c
TW
3826 return 0;
3827 case NOT:
bee757e1 3828 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
72f1215c
TW
3829 return 0;
3830 return 1;
3831
3832 case COND:
3833 for (i = 0; i < XVECLEN (exp, 0); i++)
bee757e1 3834 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
72f1215c 3835 return 0;
bee757e1 3836 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
72f1215c
TW
3837 return 0;
3838 return 1;
72f1215c 3839
e9a25f70
JL
3840 default:
3841 return 0;
3842 }
72f1215c
TW
3843}
3844
3845/* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3846 in the values of the NDIM-dimensional attribute space SPACE. */
3847
3848static void
3849unmark_used_attributes (list, space, ndim)
3850 rtx list;
3851 struct dimension *space;
3852 int ndim;
3853{
3854 rtx link, exp;
3855 int i;
3856
3857 for (i = 0; i < ndim; i++)
3858 unmark_used_attributes (space[i].values, 0, 0);
3859
3860 for (link = list; link; link = XEXP (link, 1))
3861 {
3862 exp = XEXP (link, 0);
3863 if (GET_CODE (exp) == EQ_ATTR)
3864 MEM_VOLATILE_P (exp) = 0;
3865 }
3866}
3867
3868/* Update the attribute dimension DIM so that all values of the attribute
3869 are tested. Return the updated number of values. */
3870
3871static int
3872add_values_to_cover (dim)
3873 struct dimension *dim;
3874{
3875 struct attr_value *av;
3876 rtx exp, link, *prev;
3877 int nalt = 0;
3878
3879 for (av = dim->attr->first_value; av; av = av->next)
3880 if (GET_CODE (av->value) == CONST_STRING)
3881 nalt++;
3882
3883 if (nalt < dim->num_values)
3884 abort ();
3885 else if (nalt == dim->num_values)
c9541287
KH
3886 /* OK. */
3887 ;
5830e3a0 3888 else if (nalt * 2 < dim->num_values * 3)
72f1215c
TW
3889 {
3890 /* Most all the values of the attribute are used, so add all the unused
3891 values. */
3892 prev = &dim->values;
3893 for (link = dim->values; link; link = *prev)
3894 prev = &XEXP (link, 1);
3895
3896 for (av = dim->attr->first_value; av; av = av->next)
3897 if (GET_CODE (av->value) == CONST_STRING)
3898 {
3899 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3900 if (MEM_VOLATILE_P (exp))
3901 continue;
3902
3903 link = rtx_alloc (EXPR_LIST);
3904 XEXP (link, 0) = exp;
3905 XEXP (link, 1) = 0;
3906 *prev = link;
3907 prev = &XEXP (link, 1);
3908 }
3909 dim->num_values = nalt;
3910 }
3911 else
3912 {
3913 rtx orexp = false_rtx;
3914
3915 /* Very few values are used, so compute a mutually exclusive
3916 expression. (We could do this for numeric values if that becomes
3917 important.) */
3918 prev = &dim->values;
3919 for (link = dim->values; link; link = *prev)
3920 {
f75d38a7 3921 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
72f1215c
TW
3922 prev = &XEXP (link, 1);
3923 }
3924 link = rtx_alloc (EXPR_LIST);
3925 XEXP (link, 0) = attr_rtx (NOT, orexp);
3926 XEXP (link, 1) = 0;
3927 *prev = link;
3928 dim->num_values++;
3929 }
3930 return dim->num_values;
3931}
3932
3933/* Increment the current value for the NDIM-dimensional attribute space SPACE
3934 and return FALSE if the increment overflowed. */
3935
3936static int
3937increment_current_value (space, ndim)
3938 struct dimension *space;
3939 int ndim;
3940{
3941 int i;
3942
3943 for (i = ndim - 1; i >= 0; i--)
3944 {
3945 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3946 space[i].current_value = space[i].values;
3947 else
3948 return 1;
3949 }
3950 return 0;
3951}
3952
3953/* Construct an expression corresponding to the current value for the
3954 NDIM-dimensional attribute space SPACE. */
3955
3956static rtx
3957test_for_current_value (space, ndim)
3958 struct dimension *space;
3959 int ndim;
3960{
3961 int i;
3962 rtx exp = true_rtx;
3963
3964 for (i = 0; i < ndim; i++)
f75d38a7
RK
3965 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3966 -2, -2);
72f1215c
TW
3967
3968 return exp;
3969}
3970
3971/* Given the current value of the NDIM-dimensional attribute space SPACE,
3972 set the corresponding EQ_ATTR expressions to that value and reduce
3973 the expression EXP as much as possible. On input [and output], all
3974 known EQ_ATTR expressions are set to FALSE. */
3975
3976static rtx
3977simplify_with_current_value (exp, space, ndim)
3978 rtx exp;
3979 struct dimension *space;
3980 int ndim;
3981{
3982 int i;
3983 rtx x;
3984
3985 /* Mark each current value as TRUE. */
3986 for (i = 0; i < ndim; i++)
3987 {
3988 x = XEXP (space[i].current_value, 0);
3989 if (GET_CODE (x) == EQ_ATTR)
3990 MEM_VOLATILE_P (x) = 0;
3991 }
3992
3993 exp = simplify_with_current_value_aux (exp);
3994
3995 /* Change each current value back to FALSE. */
3996 for (i = 0; i < ndim; i++)
3997 {
3998 x = XEXP (space[i].current_value, 0);
3999 if (GET_CODE (x) == EQ_ATTR)
4000 MEM_VOLATILE_P (x) = 1;
4001 }
b5b6ad46
MM
4002
4003 return exp;
72f1215c
TW
4004}
4005
4006/* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
4007 all EQ_ATTR expressions. */
4008
4009static rtx
4010simplify_with_current_value_aux (exp)
4011 rtx exp;
4012{
4013 register int i;
4014 rtx cond;
4015
4016 switch (GET_CODE (exp))
4017 {
4018 case EQ_ATTR:
4019 if (MEM_VOLATILE_P (exp))
4020 return false_rtx;
4021 else
4022 return true_rtx;
4023 case CONST_STRING:
5830e3a0 4024 case CONST_INT:
72f1215c
TW
4025 return exp;
4026
4027 case IF_THEN_ELSE:
4028 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4029 if (cond == true_rtx)
4030 return simplify_with_current_value_aux (XEXP (exp, 1));
4031 else if (cond == false_rtx)
4032 return simplify_with_current_value_aux (XEXP (exp, 2));
4033 else
4034 return attr_rtx (IF_THEN_ELSE, cond,
4035 simplify_with_current_value_aux (XEXP (exp, 1)),
4036 simplify_with_current_value_aux (XEXP (exp, 2)));
4037
4038 case IOR:
4039 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4040 if (cond == true_rtx)
4041 return cond;
4042 else if (cond == false_rtx)
4043 return simplify_with_current_value_aux (XEXP (exp, 0));
4044 else
4045 return attr_rtx (IOR, cond,
4046 simplify_with_current_value_aux (XEXP (exp, 0)));
4047
4048 case AND:
4049 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4050 if (cond == true_rtx)
4051 return simplify_with_current_value_aux (XEXP (exp, 0));
4052 else if (cond == false_rtx)
4053 return cond;
4054 else
4055 return attr_rtx (AND, cond,
4056 simplify_with_current_value_aux (XEXP (exp, 0)));
4057
4058 case NOT:
4059 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4060 if (cond == true_rtx)
4061 return false_rtx;
4062 else if (cond == false_rtx)
4063 return true_rtx;
4064 else
4065 return attr_rtx (NOT, cond);
4066
4067 case COND:
4068 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4069 {
4070 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
4071 if (cond == true_rtx)
4072 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4073 else if (cond == false_rtx)
4074 continue;
4075 else
4076 abort (); /* With all EQ_ATTR's of known value, a case should
4077 have been selected. */
4078 }
4079 return simplify_with_current_value_aux (XEXP (exp, 1));
e9a25f70
JL
4080
4081 default:
4082 abort ();
72f1215c 4083 }
72f1215c
TW
4084}
4085\f
85093b9c
RS
4086/* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4087
9a63e81d 4088static void
85093b9c
RS
4089clear_struct_flag (x)
4090 rtx x;
4091{
4092 register int i;
4093 register int j;
4094 register enum rtx_code code;
6f7d635c 4095 register const char *fmt;
85093b9c
RS
4096
4097 MEM_IN_STRUCT_P (x) = 0;
4098 if (RTX_UNCHANGING_P (x))
4099 return;
4100
4101 code = GET_CODE (x);
4102
4103 switch (code)
4104 {
4105 case REG:
4106 case QUEUED:
4107 case CONST_INT:
4108 case CONST_DOUBLE:
4109 case SYMBOL_REF:
4110 case CODE_LABEL:
4111 case PC:
4112 case CC0:
4113 case EQ_ATTR:
0b0316dc 4114 case ATTR_FLAG:
85093b9c 4115 return;
c9541287 4116
e9a25f70
JL
4117 default:
4118 break;
85093b9c
RS
4119 }
4120
4121 /* Compare the elements. If any pair of corresponding elements
4122 fail to match, return 0 for the whole things. */
4123
4124 fmt = GET_RTX_FORMAT (code);
4125 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4126 {
4127 switch (fmt[i])
4128 {
4129 case 'V':
4130 case 'E':
85093b9c
RS
4131 for (j = 0; j < XVECLEN (x, i); j++)
4132 clear_struct_flag (XVECEXP (x, i, j));
4133 break;
4134
4135 case 'e':
4136 clear_struct_flag (XEXP (x, i));
4137 break;
4138 }
41299f41
TW
4139 }
4140}
3715a518
RS
4141
4142/* Return the number of RTX objects making up the expression X.
38e01259 4143 But if we count more than MAX objects, stop counting. */
3715a518 4144
9a63e81d 4145static int
3715a518
RS
4146count_sub_rtxs (x, max)
4147 rtx x;
4148 int max;
4149{
4150 register int i;
4151 register int j;
4152 register enum rtx_code code;
6f7d635c 4153 register const char *fmt;
3715a518
RS
4154 int total = 0;
4155
4156 code = GET_CODE (x);
4157
4158 switch (code)
4159 {
4160 case REG:
4161 case QUEUED:
4162 case CONST_INT:
4163 case CONST_DOUBLE:
4164 case SYMBOL_REF:
4165 case CODE_LABEL:
4166 case PC:
4167 case CC0:
4168 case EQ_ATTR:
0b0316dc 4169 case ATTR_FLAG:
3715a518 4170 return 1;
c9541287 4171
e9a25f70
JL
4172 default:
4173 break;
3715a518
RS
4174 }
4175
4176 /* Compare the elements. If any pair of corresponding elements
4177 fail to match, return 0 for the whole things. */
4178
4179 fmt = GET_RTX_FORMAT (code);
4180 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4181 {
4182 if (total >= max)
4183 return total;
4184
4185 switch (fmt[i])
4186 {
4187 case 'V':
4188 case 'E':
4189 for (j = 0; j < XVECLEN (x, i); j++)
4190 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4191 break;
4192
4193 case 'e':
4194 total += count_sub_rtxs (XEXP (x, i), max);
4195 break;
4196 }
4197 }
4198 return total;
4199
4200}
41299f41
TW
4201\f
4202/* Create table entries for DEFINE_ATTR. */
4203
4204static void
a4cad544 4205gen_attr (exp, lineno)
41299f41 4206 rtx exp;
a4cad544 4207 int lineno;
41299f41
TW
4208{
4209 struct attr_desc *attr;
4210 struct attr_value *av;
3cce094d 4211 const char *name_ptr;
41299f41
TW
4212 char *p;
4213
4214 /* Make a new attribute structure. Check for duplicate by looking at
4215 attr->default_val, since it is initialized by this routine. */
4216 attr = find_attr (XSTR (exp, 0), 1);
4217 if (attr->default_val)
a4cad544
RH
4218 {
4219 message_with_line (lineno, "duplicate definition for attribute %s",
4220 attr->name);
4221 message_with_line (attr->lineno, "previous definition");
4222 have_error = 1;
4223 return;
4224 }
4225 attr->lineno = lineno;
41299f41
TW
4226
4227 if (*XSTR (exp, 1) == '\0')
7ee37ba4 4228 attr->is_numeric = 1;
41299f41
TW
4229 else
4230 {
4231 name_ptr = XSTR (exp, 1);
4232 while ((p = next_comma_elt (&name_ptr)) != NULL)
4233 {
0e9414fd 4234 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
3e7b5313 4235 av->value = attr_rtx (CONST_STRING, p);
41299f41
TW
4236 av->next = attr->first_value;
4237 attr->first_value = av;
4238 av->first_insn = NULL;
4239 av->num_insns = 0;
4240 av->has_asm_insn = 0;
4241 }
4242 }
4243
3e7b5313
TW
4244 if (GET_CODE (XEXP (exp, 2)) == CONST)
4245 {
4246 attr->is_const = 1;
4247 if (attr->is_numeric)
a4cad544
RH
4248 {
4249 message_with_line (lineno,
4250 "constant attributes may not take numeric values");
4251 have_error = 1;
4252 }
4253
3e7b5313
TW
4254 /* Get rid of the CONST node. It is allowed only at top-level. */
4255 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4256 }
4257
41299f41 4258 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
a4cad544 4259 {
c9541287
KH
4260 message_with_line (lineno,
4261 "`length' attribute must take numeric values");
a4cad544
RH
4262 have_error = 1;
4263 }
41299f41 4264
0f41302f 4265 /* Set up the default value. */
81fd4c6e 4266 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
41299f41
TW
4267 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4268}
4269\f
4270/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4271 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4272 number of alternatives as this should be checked elsewhere. */
4273
4274static int
4275count_alternatives (exp)
4276 rtx exp;
4277{
4278 int i, j, n;
6f7d635c 4279 const char *fmt;
c9541287 4280
41299f41
TW
4281 if (GET_CODE (exp) == MATCH_OPERAND)
4282 return n_comma_elts (XSTR (exp, 2));
4283
4284 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4285 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4286 switch (*fmt++)
4287 {
4288 case 'e':
4289 case 'u':
4290 n = count_alternatives (XEXP (exp, i));
4291 if (n)
4292 return n;
4293 break;
4294
4295 case 'E':
4296 case 'V':
4297 if (XVEC (exp, i) != NULL)
4298 for (j = 0; j < XVECLEN (exp, i); j++)
4299 {
4300 n = count_alternatives (XVECEXP (exp, i, j));
4301 if (n)
4302 return n;
4303 }
4304 }
4305
4306 return 0;
4307}
4308\f
4309/* Returns non-zero if the given expression contains an EQ_ATTR with the
4310 `alternative' attribute. */
4311
4312static int
4313compares_alternatives_p (exp)
4314 rtx exp;
4315{
4316 int i, j;
6f7d635c 4317 const char *fmt;
41299f41
TW
4318
4319 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4320 return 1;
4321
4322 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4323 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4324 switch (*fmt++)
4325 {
4326 case 'e':
4327 case 'u':
4328 if (compares_alternatives_p (XEXP (exp, i)))
4329 return 1;
4330 break;
4331
4332 case 'E':
4333 for (j = 0; j < XVECLEN (exp, i); j++)
4334 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4335 return 1;
4336 break;
4337 }
4338
4339 return 0;
4340}
4341\f
4342/* Returns non-zero is INNER is contained in EXP. */
4343
4344static int
4345contained_in_p (inner, exp)
4346 rtx inner;
4347 rtx exp;
4348{
4349 int i, j;
6f7d635c 4350 const char *fmt;
41299f41
TW
4351
4352 if (rtx_equal_p (inner, exp))
4353 return 1;
4354
4355 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4356 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4357 switch (*fmt++)
4358 {
4359 case 'e':
4360 case 'u':
4361 if (contained_in_p (inner, XEXP (exp, i)))
4362 return 1;
4363 break;
4364
4365 case 'E':
4366 for (j = 0; j < XVECLEN (exp, i); j++)
4367 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4368 return 1;
4369 break;
4370 }
4371
4372 return 0;
4373}
c9541287 4374\f
41299f41
TW
4375/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4376
4377static void
a4cad544 4378gen_insn (exp, lineno)
41299f41 4379 rtx exp;
a4cad544 4380 int lineno;
41299f41
TW
4381{
4382 struct insn_def *id;
4383
0e9414fd 4384 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
41299f41
TW
4385 id->next = defs;
4386 defs = id;
4387 id->def = exp;
a4cad544 4388 id->lineno = lineno;
41299f41
TW
4389
4390 switch (GET_CODE (exp))
4391 {
4392 case DEFINE_INSN:
c88c0d42
CP
4393 id->insn_code = insn_code_number;
4394 id->insn_index = insn_index_number;
41299f41
TW
4395 id->num_alternatives = count_alternatives (exp);
4396 if (id->num_alternatives == 0)
4397 id->num_alternatives = 1;
4398 id->vec_idx = 4;
4399 break;
4400
4401 case DEFINE_PEEPHOLE:
c88c0d42
CP
4402 id->insn_code = insn_code_number;
4403 id->insn_index = insn_index_number;
41299f41
TW
4404 id->num_alternatives = count_alternatives (exp);
4405 if (id->num_alternatives == 0)
4406 id->num_alternatives = 1;
4407 id->vec_idx = 3;
4408 break;
4409
4410 case DEFINE_ASM_ATTRIBUTES:
4411 id->insn_code = -1;
4412 id->insn_index = -1;
4413 id->num_alternatives = 1;
4414 id->vec_idx = 0;
4415 got_define_asm_attributes = 1;
4416 break;
c9541287 4417
e9a25f70
JL
4418 default:
4419 abort ();
41299f41
TW
4420 }
4421}
4422\f
4423/* Process a DEFINE_DELAY. Validate the vector length, check if annul
4424 true or annul false is specified, and make a `struct delay_desc'. */
4425
4426static void
a4cad544 4427gen_delay (def, lineno)
41299f41 4428 rtx def;
a4cad544 4429 int lineno;
41299f41
TW
4430{
4431 struct delay_desc *delay;
4432 int i;
4433
4434 if (XVECLEN (def, 1) % 3 != 0)
a4cad544
RH
4435 {
4436 message_with_line (lineno,
c9541287 4437 "number of elements in DEFINE_DELAY must be multiple of three");
a4cad544
RH
4438 have_error = 1;
4439 return;
4440 }
41299f41
TW
4441
4442 for (i = 0; i < XVECLEN (def, 1); i += 3)
4443 {
4444 if (XVECEXP (def, 1, i + 1))
4445 have_annul_true = 1;
4446 if (XVECEXP (def, 1, i + 2))
4447 have_annul_false = 1;
4448 }
c9541287 4449
0e9414fd 4450 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
41299f41
TW
4451 delay->def = def;
4452 delay->num = ++num_delays;
4453 delay->next = delays;
a4cad544 4454 delay->lineno = lineno;
41299f41
TW
4455 delays = delay;
4456}
4457\f
c9541287 4458/* Process a DEFINE_FUNCTION_UNIT.
41299f41
TW
4459
4460 This gives information about a function unit contained in the CPU.
4461 We fill in a `struct function_unit_op' and a `struct function_unit'
4462 with information used later by `expand_unit'. */
4463
4464static void
a4cad544 4465gen_unit (def, lineno)
41299f41 4466 rtx def;
a4cad544 4467 int lineno;
41299f41
TW
4468{
4469 struct function_unit *unit;
4470 struct function_unit_op *op;
3cce094d 4471 const char *name = XSTR (def, 0);
bee757e1
TW
4472 int multiplicity = XINT (def, 1);
4473 int simultaneity = XINT (def, 2);
4474 rtx condexp = XEXP (def, 3);
4475 int ready_cost = MAX (XINT (def, 4), 1);
4476 int issue_delay = MAX (XINT (def, 5), 1);
41299f41
TW
4477
4478 /* See if we have already seen this function unit. If so, check that
6dc42e49 4479 the multiplicity and simultaneity values are the same. If not, make
41299f41
TW
4480 a structure for this function unit. */
4481 for (unit = units; unit; unit = unit->next)
bee757e1 4482 if (! strcmp (unit->name, name))
41299f41 4483 {
bee757e1
TW
4484 if (unit->multiplicity != multiplicity
4485 || unit->simultaneity != simultaneity)
a4cad544
RH
4486 {
4487 message_with_line (lineno,
c9541287
KH
4488 "differing specifications given for function unit %s",
4489 unit->name);
a4cad544
RH
4490 message_with_line (unit->first_lineno, "previous definition");
4491 have_error = 1;
4492 return;
4493 }
41299f41
TW
4494 break;
4495 }
4496
4497 if (unit == 0)
4498 {
0e9414fd 4499 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
bee757e1
TW
4500 unit->name = name;
4501 unit->multiplicity = multiplicity;
4502 unit->simultaneity = simultaneity;
4503 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
41299f41
TW
4504 unit->num = num_units++;
4505 unit->num_opclasses = 0;
4506 unit->condexp = false_rtx;
4507 unit->ops = 0;
4508 unit->next = units;
a4cad544 4509 unit->first_lineno = lineno;
41299f41
TW
4510 units = unit;
4511 }
4512
4513 /* Make a new operation class structure entry and initialize it. */
0e9414fd 4514 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
bee757e1 4515 op->condexp = condexp;
41299f41 4516 op->num = unit->num_opclasses++;
bee757e1
TW
4517 op->ready = ready_cost;
4518 op->issue_delay = issue_delay;
41299f41 4519 op->next = unit->ops;
a4cad544 4520 op->lineno = lineno;
41299f41 4521 unit->ops = op;
71d9b493 4522 num_unit_opclasses++;
41299f41 4523
bee757e1 4524 /* Set our issue expression based on whether or not an optional conflict
41299f41
TW
4525 vector was specified. */
4526 if (XVEC (def, 6))
4527 {
4528 /* Compute the IOR of all the specified expressions. */
4529 rtx orexp = false_rtx;
4530 int i;
4531
4532 for (i = 0; i < XVECLEN (def, 6); i++)
f75d38a7 4533 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
41299f41 4534
bee757e1
TW
4535 op->conflict_exp = orexp;
4536 extend_range (&unit->issue_delay, 1, issue_delay);
41299f41
TW
4537 }
4538 else
72f1215c 4539 {
bee757e1
TW
4540 op->conflict_exp = true_rtx;
4541 extend_range (&unit->issue_delay, issue_delay, issue_delay);
72f1215c 4542 }
41299f41
TW
4543
4544 /* Merge our conditional into that of the function unit so we can determine
4545 which insns are used by the function unit. */
f75d38a7 4546 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
41299f41
TW
4547}
4548\f
9ec36da5 4549/* Given a piece of RTX, print a C expression to test its truth value.
c9541287 4550 We use AND and IOR both for logical and bit-wise operations, so
41299f41 4551 interpret them as logical unless they are inside a comparison expression.
71d9b493
RH
4552 The first bit of FLAGS will be non-zero in that case.
4553
4554 Set the second bit of FLAGS to make references to attribute values use
4555 a cached local variable instead of calling a function. */
41299f41
TW
4556
4557static void
71d9b493 4558write_test_expr (exp, flags)
41299f41 4559 rtx exp;
71d9b493 4560 int flags;
41299f41
TW
4561{
4562 int comparison_operator = 0;
4563 RTX_CODE code;
4564 struct attr_desc *attr;
4565
4566 /* In order not to worry about operator precedence, surround our part of
4567 the expression with parentheses. */
4568
4569 printf ("(");
4570 code = GET_CODE (exp);
4571 switch (code)
4572 {
4573 /* Binary operators. */
4574 case EQ: case NE:
4575 case GE: case GT: case GEU: case GTU:
4576 case LE: case LT: case LEU: case LTU:
4577 comparison_operator = 1;
4578
4579 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4580 case AND: case IOR: case XOR:
45620ed4 4581 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
71d9b493 4582 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
41299f41 4583 switch (code)
c9541287 4584 {
41299f41
TW
4585 case EQ:
4586 printf (" == ");
4587 break;
4588 case NE:
4589 printf (" != ");
4590 break;
4591 case GE:
4592 printf (" >= ");
4593 break;
4594 case GT:
4595 printf (" > ");
4596 break;
4597 case GEU:
4598 printf (" >= (unsigned) ");
4599 break;
4600 case GTU:
4601 printf (" > (unsigned) ");
4602 break;
4603 case LE:
4604 printf (" <= ");
4605 break;
4606 case LT:
4607 printf (" < ");
4608 break;
4609 case LEU:
4610 printf (" <= (unsigned) ");
4611 break;
4612 case LTU:
4613 printf (" < (unsigned) ");
4614 break;
4615 case PLUS:
4616 printf (" + ");
4617 break;
4618 case MINUS:
4619 printf (" - ");
4620 break;
4621 case MULT:
4622 printf (" * ");
4623 break;
4624 case DIV:
4625 printf (" / ");
4626 break;
4627 case MOD:
412dc348 4628 printf (" %% ");
41299f41
TW
4629 break;
4630 case AND:
71d9b493 4631 if (flags & 1)
41299f41
TW
4632 printf (" & ");
4633 else
4634 printf (" && ");
4635 break;
4636 case IOR:
71d9b493 4637 if (flags & 1)
41299f41
TW
4638 printf (" | ");
4639 else
4640 printf (" || ");
4641 break;
4642 case XOR:
4643 printf (" ^ ");
4644 break;
41299f41
TW
4645 case ASHIFT:
4646 printf (" << ");
4647 break;
4648 case LSHIFTRT:
4649 case ASHIFTRT:
4650 printf (" >> ");
4651 break;
e9a25f70
JL
4652 default:
4653 abort ();
c9541287 4654 }
41299f41 4655
71d9b493 4656 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
41299f41
TW
4657 break;
4658
4659 case NOT:
4660 /* Special-case (not (eq_attrq "alternative" "x")) */
71d9b493 4661 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
41299f41
TW
4662 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4663 {
4664 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4665 break;
4666 }
4667
4668 /* Otherwise, fall through to normal unary operator. */
4669
c9541287 4670 /* Unary operators. */
41299f41
TW
4671 case ABS: case NEG:
4672 switch (code)
4673 {
4674 case NOT:
71d9b493 4675 if (flags & 1)
41299f41
TW
4676 printf ("~ ");
4677 else
4678 printf ("! ");
4679 break;
4680 case ABS:
4681 printf ("abs ");
4682 break;
4683 case NEG:
4684 printf ("-");
4685 break;
e9a25f70
JL
4686 default:
4687 abort ();
41299f41
TW
4688 }
4689
71d9b493 4690 write_test_expr (XEXP (exp, 0), flags);
41299f41
TW
4691 break;
4692
4693 /* Comparison test of an attribute with a value. Most of these will
4694 have been removed by optimization. Handle "alternative"
4695 specially and give error if EQ_ATTR present inside a comparison. */
4696 case EQ_ATTR:
71d9b493 4697 if (flags & 1)
41299f41
TW
4698 fatal ("EQ_ATTR not valid inside comparison");
4699
4700 if (XSTR (exp, 0) == alternative_name)
4701 {
4702 printf ("which_alternative == %s", XSTR (exp, 1));
4703 break;
4704 }
4705
4706 attr = find_attr (XSTR (exp, 0), 0);
c9541287
KH
4707 if (! attr)
4708 abort ();
b31a5831
RS
4709
4710 /* Now is the time to expand the value of a constant attribute. */
4711 if (attr->is_const)
4712 {
4713 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
dedb78d4 4714 -2, -2),
71d9b493 4715 flags);
b31a5831
RS
4716 }
4717 else
4718 {
71d9b493
RH
4719 if (flags & 2)
4720 printf ("attr_%s", attr->name);
4721 else
4722 printf ("get_attr_%s (insn)", attr->name);
4723 printf (" == ");
4724 write_attr_valueq (attr, XSTR (exp, 1));
b31a5831 4725 }
41299f41
TW
4726 break;
4727
0b0316dc
JL
4728 /* Comparison test of flags for define_delays. */
4729 case ATTR_FLAG:
71d9b493 4730 if (flags & 1)
0b0316dc
JL
4731 fatal ("ATTR_FLAG not valid inside comparison");
4732 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4733 break;
4734
41299f41
TW
4735 /* See if an operand matches a predicate. */
4736 case MATCH_OPERAND:
4737 /* If only a mode is given, just ensure the mode matches the operand.
4738 If neither a mode nor predicate is given, error. */
c9541287 4739 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
41299f41
TW
4740 {
4741 if (GET_MODE (exp) == VOIDmode)
4742 fatal ("Null MATCH_OPERAND specified as test");
4743 else
4744 printf ("GET_MODE (operands[%d]) == %smode",
4745 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4746 }
4747 else
4748 printf ("%s (operands[%d], %smode)",
4749 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4750 break;
4751
8450a694
JC
4752 case MATCH_INSN:
4753 printf ("%s (insn)", XSTR (exp, 0));
4754 break;
4755
0f41302f 4756 /* Constant integer. */
41299f41 4757 case CONST_INT:
76d31c63 4758 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
41299f41
TW
4759 break;
4760
0f41302f 4761 /* A random C expression. */
41299f41
TW
4762 case SYMBOL_REF:
4763 printf ("%s", XSTR (exp, 0));
4764 break;
4765
4766 /* The address of the branch target. */
4767 case MATCH_DUP:
a4cad544 4768 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
5ab7138b 4769 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
41299f41
TW
4770 break;
4771
41299f41 4772 case PC:
fc470718
R
4773 /* The address of the current insn. We implement this actually as the
4774 address of the current insn for backward branches, but the last
4775 address of the next insn for forward branches, and both with
4776 adjustments that account for the worst-case possible stretching of
4777 intervening alignments between this insn and its destination. */
c9541287 4778 printf ("insn_current_reference_address (insn)");
41299f41
TW
4779 break;
4780
71d9b493
RH
4781 case CONST_STRING:
4782 printf ("%s", XSTR (exp, 0));
4783 break;
4784
4785 case IF_THEN_ELSE:
4786 write_test_expr (XEXP (exp, 0), flags & 2);
4787 printf (" ? ");
4788 write_test_expr (XEXP (exp, 1), flags | 1);
4789 printf (" : ");
4790 write_test_expr (XEXP (exp, 2), flags | 1);
4791 break;
4792
41299f41
TW
4793 default:
4794 fatal ("bad RTX code `%s' in attribute calculation\n",
4795 GET_RTX_NAME (code));
4796 }
4797
4798 printf (")");
4799}
4800\f
4801/* Given an attribute value, return the maximum CONST_STRING argument
7ee37ba4 4802 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
41299f41
TW
4803
4804static int
7ee37ba4 4805max_attr_value (exp, unknownp)
41299f41 4806 rtx exp;
7ee37ba4 4807 int *unknownp;
41299f41 4808{
7ee37ba4
RH
4809 int current_max;
4810 int i, n;
41299f41 4811
7ee37ba4 4812 switch (GET_CODE (exp))
41299f41 4813 {
7ee37ba4
RH
4814 case CONST_STRING:
4815 current_max = atoi (XSTR (exp, 0));
4816 break;
4817
4818 case COND:
4819 current_max = max_attr_value (XEXP (exp, 1), unknownp);
41299f41
TW
4820 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4821 {
7ee37ba4 4822 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
41299f41
TW
4823 if (n > current_max)
4824 current_max = n;
4825 }
7ee37ba4 4826 break;
41299f41 4827
7ee37ba4
RH
4828 case IF_THEN_ELSE:
4829 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4830 n = max_attr_value (XEXP (exp, 2), unknownp);
41299f41
TW
4831 if (n > current_max)
4832 current_max = n;
7ee37ba4 4833 break;
41299f41 4834
7ee37ba4
RH
4835 default:
4836 *unknownp = 1;
4837 current_max = INT_MAX;
4838 break;
bee757e1
TW
4839 }
4840
41299f41
TW
4841 return current_max;
4842}
fc470718
R
4843
4844/* Given an attribute value, return the result of ORing together all
7ee37ba4
RH
4845 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4846 if the numeric value is not known. */
fc470718
R
4847
4848static int
7ee37ba4 4849or_attr_value (exp, unknownp)
fc470718 4850 rtx exp;
7ee37ba4 4851 int *unknownp;
fc470718 4852{
7ee37ba4 4853 int current_or;
fc470718
R
4854 int i;
4855
7ee37ba4 4856 switch (GET_CODE (exp))
fc470718 4857 {
7ee37ba4
RH
4858 case CONST_STRING:
4859 current_or = atoi (XSTR (exp, 0));
4860 break;
4861
4862 case COND:
4863 current_or = or_attr_value (XEXP (exp, 1), unknownp);
fc470718 4864 for (i = 0; i < XVECLEN (exp, 0); i += 2)
7ee37ba4
RH
4865 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4866 break;
fc470718 4867
7ee37ba4
RH
4868 case IF_THEN_ELSE:
4869 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4870 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4871 break;
fc470718 4872
7ee37ba4
RH
4873 default:
4874 *unknownp = 1;
4875 current_or = -1;
4876 break;
fc470718
R
4877 }
4878
fc470718
R
4879 return current_or;
4880}
41299f41
TW
4881\f
4882/* Scan an attribute value, possibly a conditional, and record what actions
4883 will be required to do any conditional tests in it.
4884
4885 Specifically, set
4886 `must_extract' if we need to extract the insn operands
4887 `must_constrain' if we must compute `which_alternative'
4888 `address_used' if an address expression was used
d7c665bf 4889 `length_used' if an (eq_attr "length" ...) was used
41299f41
TW
4890 */
4891
4892static void
4893walk_attr_value (exp)
4894 rtx exp;
4895{
4896 register int i, j;
6f7d635c 4897 register const char *fmt;
41299f41
TW
4898 RTX_CODE code;
4899
4900 if (exp == NULL)
4901 return;
4902
4903 code = GET_CODE (exp);
4904 switch (code)
4905 {
4906 case SYMBOL_REF:
3e7b5313
TW
4907 if (! RTX_UNCHANGING_P (exp))
4908 /* Since this is an arbitrary expression, it can look at anything.
4909 However, constant expressions do not depend on any particular
4910 insn. */
4911 must_extract = must_constrain = 1;
41299f41
TW
4912 return;
4913
4914 case MATCH_OPERAND:
4915 must_extract = 1;
4916 return;
4917
4918 case EQ_ATTR:
4919 if (XSTR (exp, 0) == alternative_name)
4920 must_extract = must_constrain = 1;
d7c665bf
RK
4921 else if (strcmp (XSTR (exp, 0), "length") == 0)
4922 length_used = 1;
41299f41
TW
4923 return;
4924
4925 case MATCH_DUP:
426cd2f4
RK
4926 must_extract = 1;
4927 address_used = 1;
4928 return;
4929
41299f41
TW
4930 case PC:
4931 address_used = 1;
4932 return;
0b0316dc
JL
4933
4934 case ATTR_FLAG:
4935 return;
e9a25f70
JL
4936
4937 default:
4938 break;
41299f41
TW
4939 }
4940
4941 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4942 switch (*fmt++)
4943 {
4944 case 'e':
4945 case 'u':
4946 walk_attr_value (XEXP (exp, i));
4947 break;
4948
4949 case 'E':
4950 if (XVEC (exp, i) != NULL)
4951 for (j = 0; j < XVECLEN (exp, i); j++)
4952 walk_attr_value (XVECEXP (exp, i, j));
4953 break;
4954 }
4955}
4956\f
4957/* Write out a function to obtain the attribute for a given INSN. */
4958
4959static void
4960write_attr_get (attr)
4961 struct attr_desc *attr;
4962{
4963 struct attr_value *av, *common_av;
4964
4965 /* Find the most used attribute value. Handle that as the `default' of the
0f41302f 4966 switch we will generate. */
41299f41
TW
4967 common_av = find_most_used (attr);
4968
c9541287 4969 /* Write out prototype of function. */
69277eec
KG
4970 if (!attr->is_numeric)
4971 printf ("extern enum attr_%s ", attr->name);
4972 else if (attr->unsigned_p)
4973 printf ("extern unsigned int ");
4974 else
4975 printf ("extern int ");
4976 /* If the attribute name starts with a star, the remainder is the name of
4977 the subroutine to use, instead of `get_attr_...'. */
4978 if (attr->name[0] == '*')
a94ae8f5 4979 printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
69277eec 4980 else
a94ae8f5 4981 printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
69277eec
KG
4982 (attr->is_const ? "void" : "rtx"));
4983
41299f41
TW
4984 /* Write out start of function, then all values with explicit `case' lines,
4985 then a `default', then the value with the most uses. */
bee757e1 4986 if (!attr->is_numeric)
41299f41 4987 printf ("enum attr_%s\n", attr->name);
bee757e1
TW
4988 else if (attr->unsigned_p)
4989 printf ("unsigned int\n");
4990 else
4991 printf ("int\n");
41299f41
TW
4992
4993 /* If the attribute name starts with a star, the remainder is the name of
4994 the subroutine to use, instead of `get_attr_...'. */
4995 if (attr->name[0] == '*')
4996 printf ("%s (insn)\n", &attr->name[1]);
3e7b5313 4997 else if (attr->is_const == 0)
41299f41 4998 printf ("get_attr_%s (insn)\n", attr->name);
3e7b5313
TW
4999 else
5000 {
5001 printf ("get_attr_%s ()\n", attr->name);
5002 printf ("{\n");
5003
5004 for (av = attr->first_value; av; av = av->next)
5005 if (av->num_insns != 0)
5006 write_attr_set (attr, 2, av->value, "return", ";",
5007 true_rtx, av->first_insn->insn_code,
5008 av->first_insn->insn_index);
5009
5010 printf ("}\n\n");
5011 return;
5012 }
71d9b493 5013
41299f41
TW
5014 printf (" rtx insn;\n");
5015 printf ("{\n");
41299f41 5016
71d9b493
RH
5017 if (GET_CODE (common_av->value) == FFS)
5018 {
5019 rtx p = XEXP (common_av->value, 0);
41299f41 5020
c9541287 5021 /* No need to emit code to abort if the insn is unrecognized; the
71d9b493
RH
5022 other get_attr_foo functions will do that when we call them. */
5023
5024 write_toplevel_expr (p);
5025
5026 printf ("\n if (accum && accum == (accum & -accum))\n");
5027 printf (" {\n");
5028 printf (" int i;\n");
5029 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
5030 printf (" accum = i;\n");
5031 printf (" }\n else\n");
5032 printf (" accum = ~accum;\n");
5033 printf (" return accum;\n}\n\n");
5034 }
5035 else
5036 {
5037 printf (" switch (recog_memoized (insn))\n");
5038 printf (" {\n");
5039
5040 for (av = attr->first_value; av; av = av->next)
5041 if (av != common_av)
5042 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5043
5044 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5045 printf (" }\n}\n\n");
5046 }
41299f41
TW
5047}
5048\f
5049/* Given an AND tree of known true terms (because we are inside an `if' with
5050 that as the condition or are in an `else' clause) and an expression,
5051 replace any known true terms with TRUE. Use `simplify_and_tree' to do
5052 the bulk of the work. */
5053
5054static rtx
5055eliminate_known_true (known_true, exp, insn_code, insn_index)
5056 rtx known_true;
5057 rtx exp;
5058 int insn_code, insn_index;
5059{
5060 rtx term;
5061
61abc2ca
RS
5062 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
5063
5064 if (GET_CODE (known_true) == AND)
5065 {
5066 exp = eliminate_known_true (XEXP (known_true, 0), exp,
5067 insn_code, insn_index);
5068 exp = eliminate_known_true (XEXP (known_true, 1), exp,
5069 insn_code, insn_index);
5070 }
5071 else
5072 {
5073 term = known_true;
5074 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
5075 }
5076
5077 return exp;
41299f41
TW
5078}
5079\f
5080/* Write out a series of tests and assignment statements to perform tests and
5081 sets of an attribute value. We are passed an indentation amount and prefix
5082 and suffix strings to write around each attribute value (e.g., "return"
5083 and ";"). */
5084
5085static void
5086write_attr_set (attr, indent, value, prefix, suffix, known_true,
5087 insn_code, insn_index)
5088 struct attr_desc *attr;
5089 int indent;
5090 rtx value;
85fda1eb
KG
5091 const char *prefix;
5092 const char *suffix;
41299f41
TW
5093 rtx known_true;
5094 int insn_code, insn_index;
5095{
7ee37ba4 5096 if (GET_CODE (value) == COND)
41299f41
TW
5097 {
5098 /* Assume the default value will be the default of the COND unless we
5099 find an always true expression. */
5100 rtx default_val = XEXP (value, 1);
5101 rtx our_known_true = known_true;
5102 rtx newexp;
5103 int first_if = 1;
5104 int i;
5105
5106 for (i = 0; i < XVECLEN (value, 0); i += 2)
5107 {
5108 rtx testexp;
5109 rtx inner_true;
5110
5111 testexp = eliminate_known_true (our_known_true,
5112 XVECEXP (value, 0, i),
5113 insn_code, insn_index);
3e7b5313 5114 newexp = attr_rtx (NOT, testexp);
c9541287
KH
5115 newexp = insert_right_side (AND, our_known_true, newexp,
5116 insn_code, insn_index);
41299f41
TW
5117
5118 /* If the test expression is always true or if the next `known_true'
5119 expression is always false, this is the last case, so break
5120 out and let this value be the `else' case. */
5121 if (testexp == true_rtx || newexp == false_rtx)
5122 {
5123 default_val = XVECEXP (value, 0, i + 1);
5124 break;
5125 }
5126
5127 /* Compute the expression to pass to our recursive call as being
5128 known true. */
5129 inner_true = insert_right_side (AND, our_known_true,
5130 testexp, insn_code, insn_index);
5131
5132 /* If this is always false, skip it. */
5133 if (inner_true == false_rtx)
5134 continue;
5135
5136 write_indent (indent);
5137 printf ("%sif ", first_if ? "" : "else ");
5138 first_if = 0;
5139 write_test_expr (testexp, 0);
5140 printf ("\n");
5141 write_indent (indent + 2);
5142 printf ("{\n");
5143
c9541287 5144 write_attr_set (attr, indent + 4,
41299f41
TW
5145 XVECEXP (value, 0, i + 1), prefix, suffix,
5146 inner_true, insn_code, insn_index);
5147 write_indent (indent + 2);
5148 printf ("}\n");
5149 our_known_true = newexp;
5150 }
5151
5152 if (! first_if)
5153 {
5154 write_indent (indent);
5155 printf ("else\n");
5156 write_indent (indent + 2);
5157 printf ("{\n");
5158 }
5159
5160 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5161 prefix, suffix, our_known_true, insn_code, insn_index);
5162
5163 if (! first_if)
5164 {
5165 write_indent (indent + 2);
5166 printf ("}\n");
5167 }
5168 }
5169 else
7ee37ba4
RH
5170 {
5171 write_indent (indent);
5172 printf ("%s ", prefix);
5173 write_attr_value (attr, value);
5174 printf ("%s\n", suffix);
5175 }
41299f41
TW
5176}
5177\f
5178/* Write out the computation for one attribute value. */
5179
5180static void
f75d38a7
RK
5181write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5182 known_true)
41299f41
TW
5183 struct attr_desc *attr;
5184 struct attr_value *av;
5185 int write_case_lines;
85fda1eb 5186 const char *prefix, *suffix;
41299f41
TW
5187 int indent;
5188 rtx known_true;
5189{
5190 struct insn_ent *ie;
5191
5192 if (av->num_insns == 0)
5193 return;
5194
5195 if (av->has_asm_insn)
5196 {
5197 write_indent (indent);
5198 printf ("case -1:\n");
5199 write_indent (indent + 2);
5200 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5201 write_indent (indent + 2);
5202 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5203 write_indent (indent + 2);
5204 printf (" fatal_insn_not_found (insn);\n");
5205 }
5206
5207 if (write_case_lines)
5208 {
5209 for (ie = av->first_insn; ie; ie = ie->next)
5210 if (ie->insn_code != -1)
5211 {
5212 write_indent (indent);
5213 printf ("case %d:\n", ie->insn_code);
5214 }
5215 }
5216 else
5217 {
5218 write_indent (indent);
5219 printf ("default:\n");
5220 }
5221
d7c665bf 5222 /* See what we have to do to output this value. */
41299f41
TW
5223 must_extract = must_constrain = address_used = 0;
5224 walk_attr_value (av->value);
5225
d90ffc8d 5226 if (must_constrain)
41299f41
TW
5227 {
5228 write_indent (indent + 2);
d90ffc8d 5229 printf ("extract_constrain_insn_cached (insn);\n");
41299f41 5230 }
d90ffc8d 5231 else if (must_extract)
41299f41 5232 {
41299f41 5233 write_indent (indent + 2);
d90ffc8d 5234 printf ("extract_insn_cached (insn);\n");
41299f41
TW
5235 }
5236
5237 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5238 known_true, av->first_insn->insn_code,
5239 av->first_insn->insn_index);
5240
5241 if (strncmp (prefix, "return", 6))
5242 {
5243 write_indent (indent + 2);
5244 printf ("break;\n");
5245 }
5246 printf ("\n");
5247}
5248\f
71d9b493
RH
5249/* Search for uses of non-const attributes and write code to cache them. */
5250
5251static int
5252write_expr_attr_cache (p, attr)
5253 rtx p;
5254 struct attr_desc *attr;
5255{
6f7d635c 5256 const char *fmt;
71d9b493
RH
5257 int i, ie, j, je;
5258
5259 if (GET_CODE (p) == EQ_ATTR)
5260 {
5261 if (XSTR (p, 0) != attr->name)
5262 return 0;
5263
5264 if (!attr->is_numeric)
5265 printf (" register enum attr_%s ", attr->name);
5266 else if (attr->unsigned_p)
5267 printf (" register unsigned int ");
5268 else
5269 printf (" register int ");
5270
5271 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5272 return 1;
5273 }
5274
5275 fmt = GET_RTX_FORMAT (GET_CODE (p));
5276 ie = GET_RTX_LENGTH (GET_CODE (p));
5277 for (i = 0; i < ie; i++)
5278 {
5279 switch (*fmt++)
5280 {
5281 case 'e':
5282 if (write_expr_attr_cache (XEXP (p, i), attr))
5283 return 1;
5284 break;
5285
5286 case 'E':
5287 je = XVECLEN (p, i);
5288 for (j = 0; j < je; ++j)
5289 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5290 return 1;
5291 break;
5292 }
5293 }
5294
5295 return 0;
5296}
5297
5298/* Evaluate an expression at top level. A front end to write_test_expr,
5299 in which we cache attribute values and break up excessively large
5300 expressions to cater to older compilers. */
5301
5302static void
5303write_toplevel_expr (p)
5304 rtx p;
5305{
5306 struct attr_desc *attr;
5307 int i;
5308
5309 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
c9541287 5310 for (attr = attrs[i]; attr; attr = attr->next)
71d9b493
RH
5311 if (!attr->is_const)
5312 write_expr_attr_cache (p, attr);
5313
c9541287 5314 printf (" register unsigned long accum = 0;\n\n");
71d9b493
RH
5315
5316 while (GET_CODE (p) == IOR)
5317 {
5318 rtx e;
5319 if (GET_CODE (XEXP (p, 0)) == IOR)
5320 e = XEXP (p, 1), p = XEXP (p, 0);
5321 else
5322 e = XEXP (p, 0), p = XEXP (p, 1);
5323
5324 printf (" accum |= ");
5325 write_test_expr (e, 3);
5326 printf (";\n");
5327 }
5328 printf (" accum |= ");
5329 write_test_expr (p, 3);
5330 printf (";\n");
5331}
5332\f
41299f41
TW
5333/* Utilities to write names in various forms. */
5334
6f6074ea
MM
5335static void
5336write_unit_name (prefix, num, suffix)
85fda1eb 5337 const char *prefix;
6f6074ea 5338 int num;
85fda1eb 5339 const char *suffix;
6f6074ea
MM
5340{
5341 struct function_unit *unit;
5342
5343 for (unit = units; unit; unit = unit->next)
5344 if (unit->num == num)
5345 {
5346 printf ("%s%s%s", prefix, unit->name, suffix);
5347 return;
5348 }
5349
5350 printf ("%s<unknown>%s", prefix, suffix);
5351}
5352
41299f41
TW
5353static void
5354write_attr_valueq (attr, s)
5355 struct attr_desc *attr;
3cce094d 5356 const char *s;
41299f41
TW
5357{
5358 if (attr->is_numeric)
bee757e1 5359 {
6f6074ea
MM
5360 int num = atoi (s);
5361
5362 printf ("%d", num);
5363
5364 /* Make the blockage range values and function units used values easier
5365 to read. */
5366 if (attr->func_units_p)
5367 {
5368 if (num == -1)
5369 printf (" /* units: none */");
5370 else if (num >= 0)
5371 write_unit_name (" /* units: ", num, " */");
5372 else
5373 {
5374 int i;
85fda1eb 5375 const char *sep = " /* units: ";
6f6074ea
MM
5376 for (i = 0, num = ~num; num; i++, num >>= 1)
5377 if (num & 1)
5378 {
5379 write_unit_name (sep, i, (num == 1) ? " */" : "");
5380 sep = ", ";
5381 }
5382 }
5383 }
5384
5385 else if (attr->blockage_p)
5386 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5387 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5388
5389 else if (num > 9 || num < 0)
5390 printf (" /* 0x%x */", num);
bee757e1 5391 }
41299f41
TW
5392 else
5393 {
5394 write_upcase (attr->name);
5395 printf ("_");
5396 write_upcase (s);
5397 }
5398}
5399
5400static void
5401write_attr_value (attr, value)
5402 struct attr_desc *attr;
5403 rtx value;
5404{
7ee37ba4
RH
5405 int op;
5406
5407 switch (GET_CODE (value))
5408 {
5409 case CONST_STRING:
5410 write_attr_valueq (attr, XSTR (value, 0));
5411 break;
5412
6ef67412
JH
5413 case CONST_INT:
5414 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
5415 break;
5416
7ee37ba4
RH
5417 case SYMBOL_REF:
5418 fputs (XSTR (value, 0), stdout);
5419 break;
5420
5421 case ATTR:
5422 {
5423 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
c9541287 5424 printf ("get_attr_%s (%s)", attr2->name,
7ee37ba4
RH
5425 (attr2->is_const ? "" : "insn"));
5426 }
5427 break;
41299f41 5428
7ee37ba4
RH
5429 case PLUS:
5430 op = '+';
5431 goto do_operator;
5432 case MINUS:
5433 op = '-';
5434 goto do_operator;
5435 case MULT:
5436 op = '*';
5437 goto do_operator;
5438 case DIV:
5439 op = '/';
5440 goto do_operator;
5441 case MOD:
5442 op = '%';
5443 goto do_operator;
5444
5445 do_operator:
5446 write_attr_value (attr, XEXP (value, 0));
5447 putchar (' ');
5448 putchar (op);
5449 putchar (' ');
5450 write_attr_value (attr, XEXP (value, 1));
5451 break;
5452
5453 default:
5454 abort ();
5455 }
41299f41
TW
5456}
5457
5458static void
5459write_upcase (str)
92a438d1 5460 const char *str;
41299f41
TW
5461{
5462 while (*str)
c9541287
KH
5463 {
5464 /* The argument of TOUPPER should not have side effects. */
5465 putchar (TOUPPER(*str));
5466 str++;
5467 }
41299f41
TW
5468}
5469
5470static void
5471write_indent (indent)
5472 int indent;
5473{
5474 for (; indent > 8; indent -= 8)
5475 printf ("\t");
5476
5477 for (; indent; indent--)
5478 printf (" ");
5479}
5480\f
5481/* Write a subroutine that is given an insn that requires a delay slot, a
5482 delay slot ordinal, and a candidate insn. It returns non-zero if the
5483 candidate can be placed in the specified delay slot of the insn.
5484
5485 We can write as many as three subroutines. `eligible_for_delay'
5486 handles normal delay slots, `eligible_for_annul_true' indicates that
5487 the specified insn can be annulled if the branch is true, and likewise
5488 for `eligible_for_annul_false'.
5489
6dc42e49 5490 KIND is a string distinguishing these three cases ("delay", "annul_true",
41299f41
TW
5491 or "annul_false"). */
5492
5493static void
5494write_eligible_delay (kind)
c9541287 5495 const char *kind;
41299f41
TW
5496{
5497 struct delay_desc *delay;
5498 int max_slots;
5499 char str[50];
5500 struct attr_desc *attr;
5501 struct attr_value *av, *common_av;
5502 int i;
5503
5504 /* Compute the maximum number of delay slots required. We use the delay
5505 ordinal times this number plus one, plus the slot number as an index into
5506 the appropriate predicate to test. */
5507
5508 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5509 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5510 max_slots = XVECLEN (delay->def, 1) / 3;
5511
5512 /* Write function prelude. */
5513
5514 printf ("int\n");
c9541287
KH
5515 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5516 kind);
41299f41
TW
5517 printf (" rtx delay_insn;\n");
5518 printf (" int slot;\n");
5519 printf (" rtx candidate_insn;\n");
69277eec 5520 printf (" int flags ATTRIBUTE_UNUSED;\n");
41299f41
TW
5521 printf ("{\n");
5522 printf (" rtx insn;\n");
5523 printf ("\n");
5524 printf (" if (slot >= %d)\n", max_slots);
5525 printf (" abort ();\n");
5526 printf ("\n");
5527
5528 /* If more than one delay type, find out which type the delay insn is. */
5529
5530 if (num_delays > 1)
5531 {
412dc348 5532 attr = find_attr ("*delay_type", 0);
c9541287
KH
5533 if (! attr)
5534 abort ();
41299f41
TW
5535 common_av = find_most_used (attr);
5536
5537 printf (" insn = delay_insn;\n");
5538 printf (" switch (recog_memoized (insn))\n");
5539 printf (" {\n");
5540
5541 sprintf (str, " * %d;\n break;", max_slots);
5542 for (av = attr->first_value; av; av = av->next)
5543 if (av != common_av)
5544 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5545
5546 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5547 printf (" }\n\n");
5548
5549 /* Ensure matched. Otherwise, shouldn't have been called. */
5550 printf (" if (slot < %d)\n", max_slots);
5551 printf (" abort ();\n\n");
5552 }
5553
5554 /* If just one type of delay slot, write simple switch. */
5555 if (num_delays == 1 && max_slots == 1)
5556 {
5557 printf (" insn = candidate_insn;\n");
5558 printf (" switch (recog_memoized (insn))\n");
5559 printf (" {\n");
5560
5561 attr = find_attr ("*delay_1_0", 0);
c9541287
KH
5562 if (! attr)
5563 abort ();
41299f41
TW
5564 common_av = find_most_used (attr);
5565
5566 for (av = attr->first_value; av; av = av->next)
5567 if (av != common_av)
5568 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5569
5570 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5571 printf (" }\n");
5572 }
5573
5574 else
5575 {
5576 /* Write a nested CASE. The first indicates which condition we need to
5577 test, and the inner CASE tests the condition. */
5578 printf (" insn = candidate_insn;\n");
5579 printf (" switch (slot)\n");
5580 printf (" {\n");
5581
5582 for (delay = delays; delay; delay = delay->next)
5583 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5584 {
5585 printf (" case %d:\n",
5586 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5587 printf (" switch (recog_memoized (insn))\n");
5588 printf ("\t{\n");
5589
5590 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5591 attr = find_attr (str, 0);
c9541287
KH
5592 if (! attr)
5593 abort ();
41299f41
TW
5594 common_av = find_most_used (attr);
5595
5596 for (av = attr->first_value; av; av = av->next)
5597 if (av != common_av)
5598 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5599
5600 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5601 printf (" }\n");
5602 }
5603
5604 printf (" default:\n");
c9541287 5605 printf (" abort ();\n");
41299f41
TW
5606 printf (" }\n");
5607 }
5608
5609 printf ("}\n\n");
5610}
5611\f
5612/* Write routines to compute conflict cost for function units. Then write a
5613 table describing the available function units. */
5614
5615static void
5616write_function_unit_info ()
5617{
5618 struct function_unit *unit;
41299f41
TW
5619 int i;
5620
5621 /* Write out conflict routines for function units. Don't bother writing
bee757e1 5622 one if there is only one issue delay value. */
41299f41
TW
5623
5624 for (unit = units; unit; unit = unit->next)
5625 {
bee757e1
TW
5626 if (unit->needs_blockage_function)
5627 write_complex_function (unit, "blockage", "block");
72f1215c
TW
5628
5629 /* If the minimum and maximum conflict costs are the same, there
5630 is only one value, so we don't need a function. */
bee757e1 5631 if (! unit->needs_conflict_function)
41299f41 5632 {
bee757e1 5633 unit->default_cost = make_numeric_value (unit->issue_delay.max);
72f1215c 5634 continue;
41299f41
TW
5635 }
5636
5637 /* The function first computes the case from the candidate insn. */
41299f41 5638 unit->default_cost = make_numeric_value (0);
bee757e1 5639 write_complex_function (unit, "conflict_cost", "cost");
41299f41
TW
5640 }
5641
5642 /* Now that all functions have been written, write the table describing
6dc42e49 5643 the function units. The name is included for documentation purposes
41299f41
TW
5644 only. */
5645
5646 printf ("struct function_unit_desc function_units[] = {\n");
5647
72f1215c
TW
5648 /* Write out the descriptions in numeric order, but don't force that order
5649 on the list. Doing so increases the runtime of genattrtab.c. */
5650 for (i = 0; i < num_units; i++)
41299f41 5651 {
72f1215c
TW
5652 for (unit = units; unit; unit = unit->next)
5653 if (unit->num == i)
5654 break;
5655
bee757e1 5656 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
41299f41 5657 unit->name, 1 << unit->num, unit->multiplicity,
72f1215c 5658 unit->simultaneity, XSTR (unit->default_cost, 0),
bee757e1 5659 unit->issue_delay.max, unit->name);
41299f41
TW
5660
5661 if (unit->needs_conflict_function)
bee757e1
TW
5662 printf ("%s_unit_conflict_cost, ", unit->name);
5663 else
5664 printf ("0, ");
5665
5666 printf ("%d, ", unit->max_blockage);
5667
5668 if (unit->needs_range_function)
5669 printf ("%s_unit_blockage_range, ", unit->name);
5670 else
5671 printf ("0, ");
5672
5673 if (unit->needs_blockage_function)
5674 printf ("%s_unit_blockage", unit->name);
41299f41
TW
5675 else
5676 printf ("0");
5677
5678 printf ("}, \n");
5679 }
5680
5681 printf ("};\n\n");
5682}
bee757e1
TW
5683
5684static void
5685write_complex_function (unit, name, connection)
5686 struct function_unit *unit;
85fda1eb 5687 const char *name, *connection;
bee757e1
TW
5688{
5689 struct attr_desc *case_attr, *attr;
5690 struct attr_value *av, *common_av;
5691 rtx value;
b548dffb 5692 char str[256];
bee757e1
TW
5693 int using_case;
5694 int i;
5695
a94ae8f5 5696 printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
bee757e1 5697 printf ("static int\n");
c9541287 5698 printf ("%s_unit_%s (executing_insn, candidate_insn)\n", unit->name, name);
bee757e1
TW
5699 printf (" rtx executing_insn;\n");
5700 printf (" rtx candidate_insn;\n");
5701 printf ("{\n");
5702 printf (" rtx insn;\n");
5703 printf (" int casenum;\n\n");
cb1520bc 5704 printf (" insn = executing_insn;\n");
bee757e1
TW
5705 printf (" switch (recog_memoized (insn))\n");
5706 printf (" {\n");
5707
5708 /* Write the `switch' statement to get the case value. */
b548dffb
ZW
5709 if (strlen (unit->name) + sizeof "*_cases" > 256)
5710 abort ();
bee757e1
TW
5711 sprintf (str, "*%s_cases", unit->name);
5712 case_attr = find_attr (str, 0);
c9541287
KH
5713 if (! case_attr)
5714 abort ();
bee757e1
TW
5715 common_av = find_most_used (case_attr);
5716
5717 for (av = case_attr->first_value; av; av = av->next)
5718 if (av != common_av)
5719 write_attr_case (case_attr, av, 1,
5720 "casenum =", ";", 4, unit->condexp);
5721
5722 write_attr_case (case_attr, common_av, 0,
5723 "casenum =", ";", 4, unit->condexp);
5724 printf (" }\n\n");
5725
5726 /* Now write an outer switch statement on each case. Then write
5727 the tests on the executing function within each. */
cb1520bc 5728 printf (" insn = candidate_insn;\n");
bee757e1
TW
5729 printf (" switch (casenum)\n");
5730 printf (" {\n");
5731
5732 for (i = 0; i < unit->num_opclasses; i++)
5733 {
5734 /* Ensure using this case. */
5735 using_case = 0;
5736 for (av = case_attr->first_value; av; av = av->next)
5737 if (av->num_insns
5738 && contained_in_p (make_numeric_value (i), av->value))
5739 using_case = 1;
5740
5741 if (! using_case)
5742 continue;
5743
5744 printf (" case %d:\n", i);
5745 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5746 attr = find_attr (str, 0);
c9541287
KH
5747 if (! attr)
5748 abort ();
bee757e1
TW
5749
5750 /* If single value, just write it. */
5751 value = find_single_value (attr);
5752 if (value)
f75d38a7 5753 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
bee757e1
TW
5754 else
5755 {
5756 common_av = find_most_used (attr);
5757 printf (" switch (recog_memoized (insn))\n");
5758 printf ("\t{\n");
5759
5760 for (av = attr->first_value; av; av = av->next)
5761 if (av != common_av)
5762 write_attr_case (attr, av, 1,
5763 "return", ";", 8, unit->condexp);
5764
5765 write_attr_case (attr, common_av, 0,
5766 "return", ";", 8, unit->condexp);
5767 printf (" }\n\n");
5768 }
5769 }
5770
2e61a5a5
JL
5771 /* This default case should not be needed, but gcc's analysis is not
5772 good enough to realize that the default case is not needed for the
5773 second switch statement. */
5774 printf (" default:\n abort ();\n");
bee757e1
TW
5775 printf (" }\n}\n\n");
5776}
41299f41
TW
5777\f
5778/* This page contains miscellaneous utility routines. */
5779
5780/* Given a string, return the number of comma-separated elements in it.
5781 Return 0 for the null string. */
5782
5783static int
5784n_comma_elts (s)
3cce094d 5785 const char *s;
41299f41
TW
5786{
5787 int n;
5788
5789 if (*s == '\0')
5790 return 0;
5791
5792 for (n = 1; *s; s++)
5793 if (*s == ',')
5794 n++;
5795
5796 return n;
5797}
5798
5799/* Given a pointer to a (char *), return a malloc'ed string containing the
5800 next comma-separated element. Advance the pointer to after the string
5801 scanned, or the end-of-string. Return NULL if at end of string. */
5802
5803static char *
5804next_comma_elt (pstr)
3cce094d 5805 const char **pstr;
41299f41
TW
5806{
5807 char *out_str;
3cce094d 5808 const char *p;
41299f41
TW
5809
5810 if (**pstr == '\0')
5811 return NULL;
5812
5813 /* Find end of string to compute length. */
5814 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5815 ;
5816
3e7b5313
TW
5817 out_str = attr_string (*pstr, p - *pstr);
5818 *pstr = p;
41299f41 5819
41299f41
TW
5820 if (**pstr == ',')
5821 (*pstr)++;
5822
5823 return out_str;
5824}
5825
5826/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5827 is non-zero, build a new attribute, if one does not exist. */
5828
5829static struct attr_desc *
5830find_attr (name, create)
85fda1eb 5831 const char *name;
41299f41
TW
5832 int create;
5833{
5834 struct attr_desc *attr;
3715a518 5835 int index;
41299f41
TW
5836
5837 /* Before we resort to using `strcmp', see if the string address matches
5838 anywhere. In most cases, it should have been canonicalized to do so. */
5839 if (name == alternative_name)
5840 return NULL;
5841
3715a518
RS
5842 index = name[0] & (MAX_ATTRS_INDEX - 1);
5843 for (attr = attrs[index]; attr; attr = attr->next)
41299f41
TW
5844 if (name == attr->name)
5845 return attr;
5846
5847 /* Otherwise, do it the slow way. */
3715a518 5848 for (attr = attrs[index]; attr; attr = attr->next)
81fd4c6e 5849 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
41299f41
TW
5850 return attr;
5851
5852 if (! create)
5853 return NULL;
5854
0e9414fd 5855 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
3715a518 5856 attr->name = attr_string (name, strlen (name));
41299f41 5857 attr->first_value = attr->default_val = NULL;
72f1215c 5858 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
605fba2b 5859 attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
3715a518
RS
5860 attr->next = attrs[index];
5861 attrs[index] = attr;
41299f41
TW
5862
5863 return attr;
5864}
5865
5866/* Create internal attribute with the given default value. */
5867
5868static void
5869make_internal_attr (name, value, special)
85fda1eb 5870 const char *name;
41299f41
TW
5871 rtx value;
5872 int special;
5873{
5874 struct attr_desc *attr;
5875
5876 attr = find_attr (name, 1);
5877 if (attr->default_val)
5878 abort ();
5879
5880 attr->is_numeric = 1;
3e7b5313 5881 attr->is_const = 0;
72f1215c
TW
5882 attr->is_special = (special & 1) != 0;
5883 attr->negative_ok = (special & 2) != 0;
bee757e1 5884 attr->unsigned_p = (special & 4) != 0;
6f6074ea
MM
5885 attr->func_units_p = (special & 8) != 0;
5886 attr->blockage_p = (special & 16) != 0;
41299f41
TW
5887 attr->default_val = get_attr_value (value, attr, -2);
5888}
5889
5890/* Find the most used value of an attribute. */
5891
5892static struct attr_value *
5893find_most_used (attr)
5894 struct attr_desc *attr;
5895{
5896 struct attr_value *av;
5897 struct attr_value *most_used;
5898 int nuses;
5899
5900 most_used = NULL;
5901 nuses = -1;
5902
5903 for (av = attr->first_value; av; av = av->next)
5904 if (av->num_insns > nuses)
5905 nuses = av->num_insns, most_used = av;
5906
5907 return most_used;
5908}
5909
5910/* If an attribute only has a single value used, return it. Otherwise
5911 return NULL. */
5912
5913static rtx
5914find_single_value (attr)
5915 struct attr_desc *attr;
5916{
5917 struct attr_value *av;
5918 rtx unique_value;
5919
5920 unique_value = NULL;
5921 for (av = attr->first_value; av; av = av->next)
5922 if (av->num_insns)
5923 {
5924 if (unique_value)
5925 return NULL;
5926 else
5927 unique_value = av->value;
5928 }
5929
5930 return unique_value;
5931}
5932
5933/* Return (attr_value "n") */
5934
5935static rtx
5936make_numeric_value (n)
5937 int n;
5938{
5939 static rtx int_values[20];
5940 rtx exp;
3e7b5313 5941 char *p;
41299f41
TW
5942
5943 if (n < 0)
5944 abort ();
5945
5946 if (n < 20 && int_values[n])
5947 return int_values[n];
5948
0e9414fd 5949 p = attr_printf (MAX_DIGITS, "%d", n);
3e7b5313 5950 exp = attr_rtx (CONST_STRING, p);
41299f41
TW
5951
5952 if (n < 20)
5953 int_values[n] = exp;
5954
5955 return exp;
5956}
5957\f
bee757e1
TW
5958static void
5959extend_range (range, min, max)
5960 struct range *range;
5961 int min;
5962 int max;
5963{
c9541287
KH
5964 if (range->min > min)
5965 range->min = min;
5966 if (range->max < max)
5967 range->max = max;
bee757e1
TW
5968}
5969
7339c88d
RS
5970static rtx
5971copy_rtx_unchanging (orig)
5972 register rtx orig;
5973{
b5b6ad46 5974#if 0
7339c88d
RS
5975 register rtx copy;
5976 register RTX_CODE code;
b5b6ad46 5977#endif
7339c88d 5978
85093b9c 5979 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
81fd4c6e
RS
5980 return orig;
5981
85093b9c
RS
5982 MEM_IN_STRUCT_P (orig) = 1;
5983 return orig;
7339c88d 5984
85093b9c
RS
5985#if 0
5986 code = GET_CODE (orig);
7339c88d
RS
5987 switch (code)
5988 {
5989 case CONST_INT:
5990 case CONST_DOUBLE:
5991 case SYMBOL_REF:
5992 case CODE_LABEL:
5993 return orig;
c9541287 5994
e9a25f70
JL
5995 default:
5996 break;
7339c88d
RS
5997 }
5998
5999 copy = rtx_alloc (code);
6000 PUT_MODE (copy, GET_MODE (orig));
6001 RTX_UNCHANGING_P (copy) = 1;
c9541287 6002
4e135bdd
KG
6003 memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
6004 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
7339c88d 6005 return copy;
85093b9c 6006#endif
7339c88d
RS
6007}
6008
d7c665bf
RK
6009/* Determine if an insn has a constant number of delay slots, i.e., the
6010 number of delay slots is not a function of the length of the insn. */
6011
69277eec 6012static void
a9ab5e00
TM
6013write_const_num_delay_slots ()
6014{
6015 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
6016 struct attr_value *av;
6017 struct insn_ent *ie;
a9ab5e00
TM
6018
6019 if (attr)
6020 {
6021 printf ("int\nconst_num_delay_slots (insn)\n");
dea2643c 6022 printf (" rtx insn;\n");
a9ab5e00
TM
6023 printf ("{\n");
6024 printf (" switch (recog_memoized (insn))\n");
6025 printf (" {\n");
6026
6027 for (av = attr->first_value; av; av = av->next)
d7c665bf
RK
6028 {
6029 length_used = 0;
6030 walk_attr_value (av->value);
6031 if (length_used)
6032 {
6033 for (ie = av->first_insn; ie; ie = ie->next)
c9541287
KH
6034 if (ie->insn_code != -1)
6035 printf (" case %d:\n", ie->insn_code);
d7c665bf
RK
6036 printf (" return 0;\n");
6037 }
6038 }
6039
a9ab5e00
TM
6040 printf (" default:\n");
6041 printf (" return 1;\n");
fc470718 6042 printf (" }\n}\n\n");
a9ab5e00
TM
6043 }
6044}
41299f41 6045\f
a94ae8f5 6046extern int main PARAMS ((int, char **));
c1b59dce 6047
41299f41
TW
6048int
6049main (argc, argv)
6050 int argc;
6051 char **argv;
6052{
6053 rtx desc;
41299f41 6054 struct attr_desc *attr;
41299f41
TW
6055 struct insn_def *id;
6056 rtx tem;
3715a518 6057 int i;
41299f41 6058
ef178af3
ZW
6059 progname = "genattrtab";
6060
c88c0d42
CP
6061 if (argc <= 1)
6062 fatal ("No input file name.");
6063
3916d6d8
RH
6064 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
6065 return (FATAL_EXIT_CODE);
6066
7339c88d 6067 obstack_init (hash_obstack);
81fd4c6e 6068 obstack_init (temp_obstack);
41299f41 6069
41299f41 6070 /* Set up true and false rtx's */
81fd4c6e 6071 true_rtx = rtx_alloc (CONST_INT);
3d678dca 6072 XWINT (true_rtx, 0) = 1;
81fd4c6e 6073 false_rtx = rtx_alloc (CONST_INT);
3d678dca 6074 XWINT (false_rtx, 0) = 0;
41299f41 6075 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
81fd4c6e
RS
6076 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
6077
6078 alternative_name = attr_string ("alternative", strlen ("alternative"));
41299f41
TW
6079
6080 printf ("/* Generated automatically by the program `genattrtab'\n\
6081from the machine description file `md'. */\n\n");
6082
6083 /* Read the machine description. */
6084
6085 while (1)
6086 {
a4cad544 6087 int lineno;
41299f41 6088
a4cad544 6089 desc = read_md_rtx (&lineno, &insn_code_number);
c88c0d42
CP
6090 if (desc == NULL)
6091 break;
ede7cd44 6092
c88c0d42 6093 switch (GET_CODE (desc))
41299f41 6094 {
c9541287
KH
6095 case DEFINE_INSN:
6096 case DEFINE_PEEPHOLE:
6097 case DEFINE_ASM_ATTRIBUTES:
6098 gen_insn (desc, lineno);
6099 break;
41299f41 6100
c9541287
KH
6101 case DEFINE_ATTR:
6102 gen_attr (desc, lineno);
6103 break;
41299f41 6104
c9541287
KH
6105 case DEFINE_DELAY:
6106 gen_delay (desc, lineno);
6107 break;
6108
6109 case DEFINE_FUNCTION_UNIT:
6110 gen_unit (desc, lineno);
6111 break;
6112
6113 default:
6114 break;
41299f41 6115 }
c88c0d42 6116 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
c9541287 6117 insn_index_number++;
41299f41
TW
6118 }
6119
a4cad544
RH
6120 if (have_error)
6121 return FATAL_EXIT_CODE;
6122
c88c0d42
CP
6123 insn_code_number++;
6124
41299f41
TW
6125 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6126 if (! got_define_asm_attributes)
6127 {
6128 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6129 XVEC (tem, 0) = rtvec_alloc (0);
a4cad544 6130 gen_insn (tem, 0);
41299f41
TW
6131 }
6132
6133 /* Expand DEFINE_DELAY information into new attribute. */
6134 if (num_delays)
6135 expand_delays ();
6136
6137 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6138 if (num_units)
6139 expand_units ();
6140
6141 printf ("#include \"config.h\"\n");
729da3f5 6142 printf ("#include \"system.h\"\n");
41299f41 6143 printf ("#include \"rtl.h\"\n");
6baf1cc8 6144 printf ("#include \"tm_p.h\"\n");
41299f41
TW
6145 printf ("#include \"insn-config.h\"\n");
6146 printf ("#include \"recog.h\"\n");
6147 printf ("#include \"regs.h\"\n");
6148 printf ("#include \"real.h\"\n");
6149 printf ("#include \"output.h\"\n");
6150 printf ("#include \"insn-attr.h\"\n");
114791ea 6151 printf ("#include \"toplev.h\"\n");
c9541287 6152 printf ("\n");
1ccbefce 6153 printf ("#define operands recog_data.operand\n\n");
41299f41
TW
6154
6155 /* Make `insn_alternatives'. */
0e9414fd 6156 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
41299f41
TW
6157 for (id = defs; id; id = id->next)
6158 if (id->insn_code >= 0)
6159 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6160
3715a518 6161 /* Make `insn_n_alternatives'. */
0e9414fd 6162 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
3715a518
RS
6163 for (id = defs; id; id = id->next)
6164 if (id->insn_code >= 0)
6165 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6166
41299f41
TW
6167 /* Prepare to write out attribute subroutines by checking everything stored
6168 away and building the attribute cases. */
6169
6170 check_defs ();
a4cad544 6171
3715a518
RS
6172 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6173 for (attr = attrs[i]; attr; attr = attr->next)
a4cad544
RH
6174 attr->default_val->value
6175 = check_attr_value (attr->default_val->value, attr);
6176
6177 if (have_error)
6178 return FATAL_EXIT_CODE;
6179
6180 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6181 for (attr = attrs[i]; attr; attr = attr->next)
6182 fill_attr (attr);
41299f41
TW
6183
6184 /* Construct extra attributes for `length'. */
6185 make_length_attrs ();
6186
0f41302f 6187 /* Perform any possible optimizations to speed up compilation. */
41299f41
TW
6188 optimize_attrs ();
6189
6190 /* Now write out all the `gen_attr_...' routines. Do these before the
6191 special routines (specifically before write_function_unit_info), so
6192 that they get defined before they are used. */
6193
3715a518
RS
6194 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6195 for (attr = attrs[i]; attr; attr = attr->next)
6196 {
71d9b493 6197 if (! attr->is_special && ! attr->is_const)
3715a518
RS
6198 write_attr_get (attr);
6199 }
41299f41
TW
6200
6201 /* Write out delay eligibility information, if DEFINE_DELAY present.
6202 (The function to compute the number of delay slots will be written
6203 below.) */
6204 if (num_delays)
6205 {
6206 write_eligible_delay ("delay");
6207 if (have_annul_true)
6208 write_eligible_delay ("annul_true");
6209 if (have_annul_false)
6210 write_eligible_delay ("annul_false");
6211 }
6212
6213 /* Write out information about function units. */
6214 if (num_units)
6215 write_function_unit_info ();
6216
a9ab5e00
TM
6217 /* Write out constant delay slot info */
6218 write_const_num_delay_slots ();
6219
fc470718
R
6220 write_length_unit_log ();
6221
41299f41 6222 fflush (stdout);
c1b59dce 6223 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
41299f41 6224}
a995e389
RH
6225
6226/* Define this so we can link with print-rtl.o to get debug_rtx function. */
6227const char *
6228get_insn_name (code)
c1b59dce 6229 int code ATTRIBUTE_UNUSED;
a995e389
RH
6230{
6231 return NULL;
6232}