OSDN Git Service

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