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