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