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