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