OSDN Git Service

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