OSDN Git Service

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