OSDN Git Service

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