*** empty log message ***
[platform/upstream/gcc.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 attribues 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 #include <stdio.h>
87 #include "gvarargs.h"
88 #include "config.h"
89 #include "rtl.h"
90 #include "obstack.h"
91 #include "insn-config.h"        /* For REGISTER_CONSTRAINTS */
92
93 static struct obstack obstack, obstack1, obstack2;
94 struct obstack *rtl_obstack = &obstack;
95 struct obstack *hash_obstack = &obstack1;
96 struct obstack *temp_obstack = &obstack2;
97
98 #define obstack_chunk_alloc xmalloc
99 #define obstack_chunk_free free
100
101 /* Define this so we can link with print-rtl.o to get debug_rtx function.  */
102 char **insn_name_ptr = 0;
103
104 extern void free ();
105 extern rtx read_rtx ();
106
107 static void fatal ();
108 void fancy_abort ();
109
110 /* Define structures used to record attributes and values.  */
111
112 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
113    encountered, we store all the relevant information into a
114    `struct insn_def'.  This is done to allow attribute definitions to occur
115    anywhere in the file.  */
116
117 struct insn_def
118 {
119   int insn_code;                /* Instruction number. */
120   int insn_index;               /* Expression numer in file, for errors. */
121   struct insn_def *next;        /* Next insn in chain. */
122   rtx def;                      /* The DEFINE_... */
123   int num_alternatives;         /* Number of alternatives.  */
124   int vec_idx;                  /* Index of attribute vector in `def'. */
125 };
126
127 /* Once everything has been read in, we store in each attribute value a list
128    of insn codes that have that value.  Here is the structure used for the
129    list.  */
130
131 struct insn_ent
132 {
133   int insn_code;                /* Instruction number.  */
134   int insn_index;               /* Index of definition in file */
135   struct insn_ent *next;        /* Next in chain.  */
136 };
137
138 /* Each value of an attribute (either constant or computed) is assigned a
139    structure which is used as the listhead of the insns that have that
140    value.  */
141
142 struct attr_value
143 {
144   rtx value;                    /* Value of attribute.  */
145   struct attr_value *next;      /* Next attribute value in chain.  */
146   struct insn_ent *first_insn;  /* First insn with this value.  */
147   int num_insns;                /* Number of insns with this value.  */
148   int has_asm_insn;             /* True if this value used for `asm' insns */
149 };
150
151 /* Structure for each attribute.  */
152
153 struct attr_desc
154 {
155   char *name;                   /* Name of attribute. */
156   struct attr_desc *next;       /* Next attribute. */
157   int is_numeric;               /* Values of this attribute are numeric. */
158   int is_const;                 /* Attribute value constant for each run.  */
159   int is_special;               /* Don't call `write_attr_set'. */
160   struct attr_value *first_value; /* First value of this attribute. */
161   struct attr_value *default_val; /* Default value for this attribute. */
162 };
163
164 /* Structure for each DEFINE_DELAY.  */
165
166 struct delay_desc
167 {
168   rtx def;                      /* DEFINE_DELAY expression.  */
169   struct delay_desc *next;      /* Next DEFINE_DELAY. */
170   int num;                      /* Number of DEFINE_DELAY, starting at 1.  */
171 };
172
173 /* Record information about each DEFINE_FUNCTION_UNIT.  */
174
175 struct function_unit_op
176 {
177   rtx condexp;                  /* Expression TRUE for applicable insn.  */
178   struct function_unit_op *next; /* Next operation for this function unit.  */
179   int num;                      /* Ordinal for this operation type in unit.  */
180   int ready;                    /* Cost until data is ready.  */
181   rtx busyexp;                  /* Expression computing conflict cost.  */
182 };
183
184 /* Record information about each function unit mentioned in a
185    DEFINE_FUNCTION_UNIT.  */
186
187 struct function_unit
188 {
189   char *name;                   /* Function unit name.  */
190   struct function_unit *next;   /* Next function unit.  */
191   int num;                      /* Ordinal of this unit type.  */
192   int multiplicity;             /* Number of units of this type.  */
193   int simultaneity;             /* Maximum number of simultaneous insns
194                                    on this function unit or 0 if unlimited.  */
195   rtx condexp;                  /* Expression TRUE for insn needing unit. */
196   rtx costexp;                  /* Worst-case cost as function of insn. */
197   int num_opclasses;            /* Number of different operation types.  */
198   struct function_unit_op *ops; /* Pointer to first operation type.  */
199   int needs_conflict_function;  /* Nonzero if a conflict function required.  */
200   rtx default_cost;             /* Conflict cost, if constant.  */
201 };
202
203 /* Listheads of above structures.  */
204
205 static struct attr_desc *attrs;
206 static struct insn_def *defs;
207 static struct delay_desc *delays;
208 static struct function_unit *units;
209
210 /* Other variables. */
211
212 static int insn_code_number;
213 static int insn_index_number;
214 static int got_define_asm_attributes;
215 static int must_extract;
216 static int must_constrain;
217 static int address_used;
218 static int num_delays;
219 static int have_annul_true, have_annul_false;
220 static int num_units;
221
222 /* Used as operand to `operate_exp':  */
223
224 enum operator {PLUS_OP, MINUS_OP, OR_OP, MAX_OP};
225
226 /* Stores, for each insn code, a bitmap that has bits on for each possible
227    alternative.  */
228
229 static int *insn_alternatives;
230
231 /* Used to simplify expressions.  */
232
233 static rtx true_rtx, false_rtx;
234
235 /* Used to reduce calls to `strcmp' */
236
237 static char *alternative_name;
238
239 /* Simplify an expression.  Only call the routine if there is something to
240    simplify.  */
241 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)     \
242   (RTX_UNCHANGING_P (EXP) ? (EXP)                       \
243    : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
244   
245 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
246    They won't actually be used.  */
247
248 rtx frame_pointer_rtx, stack_pointer_rtx, arg_pointer_rtx;
249
250 static rtx attr_rtx ();
251 static char *attr_printf ();
252 static char *attr_string ();
253 static rtx check_attr_test ();
254 static rtx check_attr_value ();
255 static rtx convert_set_attr_alternative ();
256 static rtx convert_set_attr ();
257 static void check_defs ();
258 static rtx convert_const_symbol_ref ();
259 static rtx make_canonical ();
260 static struct attr_value *get_attr_value ();
261 static rtx copy_rtx_unchanging ();
262 static rtx copy_boolean ();
263 static void expand_delays ();
264 static rtx operate_exp ();
265 static void expand_units ();
266 static void fill_attr ();
267 static rtx substitute_address ();
268 static void make_length_attrs ();
269 static rtx identity_fn ();
270 static rtx zero_fn ();
271 static rtx one_fn ();
272 static rtx max_fn ();
273 static rtx simplify_cond ();
274 static void remove_insn_ent ();
275 static void insert_insn_ent ();
276 static rtx insert_right_side ();
277 static rtx make_alternative_compare ();
278 static int compute_alternative_mask ();
279 static rtx evaluate_eq_attr ();
280 static rtx simplify_and_tree ();
281 static rtx simplify_or_tree ();
282 static rtx simplify_test_exp ();
283 static void optimize_attrs ();
284 static void gen_attr ();
285 static int count_alternatives ();
286 static int compares_alternatives_p ();
287 static int contained_in_p ();
288 static void gen_insn ();
289 static void gen_delay ();
290 static void gen_unit ();
291 static void write_test_expr ();
292 static int max_attr_value ();
293 static void walk_attr_value ();
294 static void write_attr_get ();
295 static rtx eliminate_known_true ();
296 static void write_attr_set ();
297 static void write_attr_case ();
298 static void write_attr_value ();
299 static void write_attr_valueq ();
300 static void write_upcase ();
301 static void write_indent ();
302 static void write_eligible_delay ();
303 static void write_function_unit_info ();
304 static int n_comma_elts ();
305 static char *next_comma_elt ();
306 static struct attr_desc *find_attr ();
307 static void make_internal_attr ();
308 static struct attr_value *find_most_used ();
309 static rtx find_single_value ();
310 static rtx make_numeric_value ();
311 char *xrealloc ();
312 char *xmalloc ();
313 static void fatal ();
314 \f
315 /* Hash table for sharing RTL and strings.  */
316
317 /* Each hash table slot is a bucket containing a chain of these structures.
318    Strings are given negative hash codes; RTL expressions are given positive
319    hash codes.  */
320
321 struct attr_hash
322 {
323   struct attr_hash *next;       /* Next structure in the bucket.  */
324   int hashcode;                 /* Hash code of this rtx or string.  */
325   union
326     {
327       char *str;                /* The string (negative hash codes) */
328       rtx rtl;                  /* or the RTL recorded here.  */
329     } u;
330 };
331
332 /* Now here is the hash table.  When recording an RTL, it is added to
333    the slot whose index is the hash code mod the table size.  Note
334    that the hash table is used for several kinds of RTL (see attr_rtx)
335    and for strings.  While all these live in the same table, they are
336    completely independent, and the hash code is computed differently
337    for each.  */
338
339 #define RTL_HASH_SIZE 4093
340 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
341
342 /* Here is how primitive or already-shared RTL's hash
343    codes are made.  */
344 #define RTL_HASH(RTL) ((int) (RTL) & 0777777)
345
346 /* Add an entry to the hash table for RTL with hash code HASHCODE.  */
347
348 static void
349 attr_hash_add_rtx (hashcode, rtl)
350      int hashcode;
351      rtx rtl;
352 {
353   register struct attr_hash *h;
354
355   h = (struct attr_hash *) obstack_alloc (hash_obstack,
356                                           sizeof (struct attr_hash));
357   h->hashcode = hashcode;
358   h->u.rtl = rtl;
359   h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
360   attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
361 }
362
363 /* Add an entry to the hash table for STRING with hash code HASHCODE.  */
364
365 static void
366 attr_hash_add_string (hashcode, str)
367      int hashcode;
368      char *str;
369 {
370   register struct attr_hash *h;
371
372   h = (struct attr_hash *) obstack_alloc (hash_obstack,
373                                           sizeof (struct attr_hash));
374   h->hashcode = -hashcode;
375   h->u.str = str;
376   h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
377   attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
378 }
379
380 /* Generate an RTL expression, but avoid duplicates.
381    Set the RTX_INTEGRATED_P flag for these permanent objects.
382
383    In some cases we cannot uniquify; then we return an ordinary
384    impermanent rtx with RTX_INTEGRATED_P clear.
385
386    Args are like gen_rtx, but without the mode:
387
388    rtx attr_rtx (code, [element1, ..., elementn])  */
389
390 /*VARARGS1*/
391 static rtx
392 attr_rtx (va_alist)
393      va_dcl
394 {
395   va_list p;
396   enum rtx_code code;
397   register int i;               /* Array indices...                     */
398   register char *fmt;           /* Current rtx's format...              */
399   register rtx rt_val;          /* RTX to return to caller...           */
400   int hashcode;
401   register struct attr_hash *h;
402   struct obstack *old_obstack = rtl_obstack;
403
404   va_start (p);
405   code = va_arg (p, enum rtx_code);
406
407   /* For each of several cases, search the hash table for an existing entry.
408      Use that entry if one is found; otherwise create a new RTL and add it
409      to the table.  */
410
411   if (GET_RTX_CLASS (code) == '1')
412     {
413       rtx arg0 = va_arg (p, rtx);
414
415       /* A permanent object cannot point to impermanent ones.  */
416       if (! RTX_INTEGRATED_P (arg0))
417         {
418           rt_val = rtx_alloc (code);
419           XEXP (rt_val, 0) = arg0;
420           va_end (p);
421           return rt_val;
422         }
423
424       hashcode = ((int) code + RTL_HASH (arg0));
425       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
426         if (h->hashcode == hashcode
427             && GET_CODE (h->u.rtl) == code
428             && XEXP (h->u.rtl, 0) == arg0)
429           goto found;
430
431       if (h == 0)
432         {
433           rtl_obstack = hash_obstack;
434           rt_val = rtx_alloc (code);
435           XEXP (rt_val, 0) = arg0;
436         }
437     }
438   else if (GET_RTX_CLASS (code) == 'c'
439            || GET_RTX_CLASS (code) == '2'
440            || GET_RTX_CLASS (code) == '<')
441     {
442       rtx arg0 = va_arg (p, rtx);
443       rtx arg1 = va_arg (p, rtx);
444
445       /* A permanent object cannot point to impermanent ones.  */
446       if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
447         {
448           rt_val = rtx_alloc (code);
449           XEXP (rt_val, 0) = arg0;
450           XEXP (rt_val, 1) = arg1;
451           va_end (p);
452           return rt_val;
453         }
454
455       hashcode = ((int) code + RTL_HASH (arg0) + RTL_HASH (arg1));
456       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
457         if (h->hashcode == hashcode
458             && GET_CODE (h->u.rtl) == code
459             && XEXP (h->u.rtl, 0) == arg0
460             && XEXP (h->u.rtl, 1) == arg1)
461           goto found;
462
463       if (h == 0)
464         {
465           rtl_obstack = hash_obstack;
466           rt_val = rtx_alloc (code);
467           XEXP (rt_val, 0) = arg0;
468           XEXP (rt_val, 1) = arg1;
469         }
470     }
471   else if (GET_RTX_LENGTH (code) == 1
472            && GET_RTX_FORMAT (code)[0] == 's')
473     {
474       char * arg0 = va_arg (p, char *);
475
476       if (code == SYMBOL_REF)
477         arg0 = attr_string (arg0, strlen (arg0));
478
479       hashcode = ((int) code + RTL_HASH (arg0));
480       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
481         if (h->hashcode == hashcode
482             && GET_CODE (h->u.rtl) == code
483             && XSTR (h->u.rtl, 0) == arg0)
484           goto found;
485
486       if (h == 0)
487         {
488           rtl_obstack = hash_obstack;
489           rt_val = rtx_alloc (code);
490           XSTR (rt_val, 0) = arg0;
491         }
492     }
493   else if (GET_RTX_LENGTH (code) == 2
494            && GET_RTX_FORMAT (code)[0] == 's'
495            && GET_RTX_FORMAT (code)[1] == 's')
496     {
497       char *arg0 = va_arg (p, char *);
498       char *arg1 = va_arg (p, char *);
499
500       hashcode = ((int) code + RTL_HASH (arg0) + RTL_HASH (arg1));
501       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
502         if (h->hashcode == hashcode
503             && GET_CODE (h->u.rtl) == code
504             && XSTR (h->u.rtl, 0) == arg0
505             && XSTR (h->u.rtl, 1) == arg1)
506           goto found;
507
508       if (h == 0)
509         {
510           rtl_obstack = hash_obstack;
511           rt_val = rtx_alloc (code);
512           XSTR (rt_val, 0) = arg0;
513           XSTR (rt_val, 1) = arg1;
514         }
515     }
516   else if (code == CONST_INT)
517     {
518       int arg0 = va_arg (p, int);
519       if (arg0 == 0)
520         return false_rtx;
521       if (arg0 == 1)
522         return true_rtx;
523       goto nohash;
524     }
525   else
526     {
527     nohash:
528       rt_val = rtx_alloc (code);        /* Allocate the storage space.  */
529       
530       fmt = GET_RTX_FORMAT (code);      /* Find the right format...  */
531       for (i = 0; i < GET_RTX_LENGTH (code); i++)
532         {
533           switch (*fmt++)
534             {
535             case '0':           /* Unused field.  */
536               break;
537
538             case 'i':           /* An integer?  */
539               XINT (rt_val, i) = va_arg (p, int);
540               break;
541
542             case 's':           /* A string?  */
543               XSTR (rt_val, i) = va_arg (p, char *);
544               break;
545
546             case 'e':           /* An expression?  */
547             case 'u':           /* An insn?  Same except when printing.  */
548               XEXP (rt_val, i) = va_arg (p, rtx);
549               break;
550
551             case 'E':           /* An RTX vector?  */
552               XVEC (rt_val, i) = va_arg (p, rtvec);
553               break;
554
555             default:
556               abort();
557             }
558         }
559       va_end (p);
560       return rt_val;
561     }
562
563   rtl_obstack = old_obstack;
564   va_end (p);
565   attr_hash_add_rtx (hashcode, rt_val);
566   RTX_INTEGRATED_P (rt_val) = 1;
567   return rt_val;
568
569  found:
570   va_end (p);
571   return h->u.rtl;
572 }
573
574 /* Create a new string printed with the printf line arguments into a space
575    of at most LEN bytes:
576
577    rtx attr_printf (len, format, [arg1, ..., argn])  */
578
579 #ifdef HAVE_VPRINTF
580
581 /*VARARGS2*/
582 static char *
583 attr_printf (va_alist)
584      va_dcl
585 {
586   va_list p;
587   register int len;
588   register char *fmt;
589   register char *str;
590
591   /* Print the string into a temporary location.  */
592   va_start (p);
593   len = va_arg (p, int);
594   str = (char *) alloca (len);
595   fmt = va_arg (p, char *);
596   vsprintf (str, fmt, p);
597   va_end (p);
598
599   return attr_string (str, strlen (str));
600 }
601
602 #else /* not HAVE_VPRINTF */
603
604 static char *
605 attr_printf (len, fmt, arg1, arg2, arg3)
606      int len;
607      char *fmt;
608      char *arg1, *arg2, *arg3; /* also int */
609 {
610   register char *str;
611
612   /* Print the string into a temporary location.  */
613   str = (char *) alloca (len);
614   sprintf (str, fmt, arg1, arg2, arg3);
615
616   return attr_string (str, strlen (str));
617 }
618 #endif /* not HAVE_VPRINTF */
619
620 rtx
621 attr_eq (name, value)
622      char *name, *value;
623 {
624   return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
625                    attr_string (value, strlen (value)));
626 }
627
628 char *
629 attr_numeral (n)
630      int n;
631 {
632   return XSTR (make_numeric_value (n), 0);
633 }
634
635 /* Return a permanent (possibly shared) copy of a string STR (not assumed
636    to be null terminated) with LEN bytes.  */
637
638 static char *
639 attr_string (str, len)
640      char *str;
641      int len;
642 {
643   register struct attr_hash *h;
644   int hashcode;
645   int i;
646   register char *new_str;
647
648   /* Compute the hash code.  */
649   hashcode = (len + 1) * 613 + (unsigned)str[0];
650   for (i = 1; i <= len; i += 2)
651     hashcode = ((hashcode * 613) + (unsigned)str[i]);
652   if (hashcode < 0)
653     hashcode = -hashcode;
654
655   /* Search the table for the string.  */
656   for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
657     if (h->hashcode == -hashcode && h->u.str[0] == str[0]
658         && !strncmp (h->u.str, str, len))
659       return h->u.str;                  /* <-- return if found.  */
660
661   /* Not found; create a permanent copy and add it to the hash table.  */
662   new_str = (char *) xmalloc (len + 1);
663   bcopy (str, new_str, len);
664   new_str[len] = '\0';
665   attr_hash_add_string (hashcode, new_str);
666
667   return new_str;                       /* Return the new string.  */
668 }
669
670 /* Check two rtx's for equality of contents,
671    taking advantage of the fact that if both are hashed
672    then they can't be equal unless they are the same object.  */
673
674 int
675 attr_equal_p (x, y)
676      rtx x, y;
677 {
678   return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
679                      && rtx_equal_p (x, y)));
680 }
681 \f
682 /* Copy an attribute value expression,
683    descending to all depths, but not copying any
684    permanent hashed subexpressions.  */
685
686 rtx
687 attr_copy_rtx (orig)
688      register rtx orig;
689 {
690   register rtx copy;
691   register int i, j;
692   register RTX_CODE code;
693   register char *format_ptr;
694
695   /* No need to copy a permanent object.  */
696   if (RTX_INTEGRATED_P (orig))
697     return orig;
698
699   code = GET_CODE (orig);
700
701   switch (code)
702     {
703     case REG:
704     case QUEUED:
705     case CONST_INT:
706     case CONST_DOUBLE:
707     case SYMBOL_REF:
708     case CODE_LABEL:
709     case PC:
710     case CC0:
711       return orig;
712     }
713
714   copy = rtx_alloc (code);
715   PUT_MODE (copy, GET_MODE (orig));
716   copy->in_struct = orig->in_struct;
717   copy->volatil = orig->volatil;
718   copy->unchanging = orig->unchanging;
719   copy->integrated = orig->integrated;
720   
721   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
722
723   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
724     {
725       switch (*format_ptr++)
726         {
727         case 'e':
728           XEXP (copy, i) = XEXP (orig, i);
729           if (XEXP (orig, i) != NULL)
730             XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
731           break;
732
733         case 'E':
734         case 'V':
735           XVEC (copy, i) = XVEC (orig, i);
736           if (XVEC (orig, i) != NULL)
737             {
738               XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
739               for (j = 0; j < XVECLEN (copy, i); j++)
740                 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
741             }
742           break;
743
744         default:
745           XINT (copy, i) = XINT (orig, i);
746           break;
747         }
748     }
749   return copy;
750 }
751 \f
752 /* Given a test expression for an attribute, ensure it is validly formed.
753    IS_CONST indicates whether the expression is constant for each compiler
754    run (a constant expression may not test any particular insn).
755
756    Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
757    and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")).  Do the latter
758    test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
759
760    Update the string address in EQ_ATTR expression to be the same used
761    in the attribute (or `alternative_name') to speed up subsequent
762    `find_attr' calls and eliminate most `strcmp' calls.
763
764    Return the new expression, if any.   */
765
766 static rtx
767 check_attr_test (exp, is_const)
768      rtx exp;
769      int is_const;
770 {
771   struct attr_desc *attr;
772   struct attr_value *av;
773   char *name_ptr, *p;
774   rtx orexp, newexp;
775
776   switch (GET_CODE (exp))
777     {
778     case EQ_ATTR:
779       /* Handle negation test.  */
780       if (XSTR (exp, 1)[0] == '!')
781         return check_attr_test (attr_rtx (NOT,
782                                           attr_eq (XSTR (exp, 0),
783                                                    &XSTR (exp, 1)[1])),
784                                 is_const);
785
786       else if (n_comma_elts (XSTR (exp, 1)) == 1)
787         {
788           attr = find_attr (XSTR (exp, 0), 0);
789           if (attr == NULL)
790             {
791               if (! strcmp (XSTR (exp, 0), "alternative"))
792                 {
793                   XSTR (exp, 0) = alternative_name;
794                   /* This can't be simplified any further.  */
795                   RTX_UNCHANGING_P (exp) = 1;
796                   return exp;
797                 }
798               else
799                 fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp, 0));
800             }
801
802           if (is_const && ! attr->is_const)
803             fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
804                    XEXP (exp, 0));
805
806           /* Copy this just to make it permanent,
807              so expressions using it can be permanent too.  */
808           exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
809
810           if (attr->is_numeric)
811             {
812               for (p = XSTR (exp, 1); *p; p++)
813                 if (*p < '0' || *p > '9')
814                    fatal ("Attribute `%s' takes only numeric values", 
815                           XEXP (exp, 0));
816             }
817           else
818             {
819               for (av = attr->first_value; av; av = av->next)
820                 if (GET_CODE (av->value) == CONST_STRING
821                     && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
822                   break;
823
824               if (av == NULL)
825                 fatal ("Unknown value `%s' for `%s' attribute",
826                        XEXP (exp, 1), XEXP (exp, 0));
827             }
828         }
829       else
830         {
831           /* Make an IOR tree of the possible values.  */
832           orexp = false_rtx;
833           name_ptr = XSTR (exp, 1);
834           while ((p = next_comma_elt (&name_ptr)) != NULL)
835             {
836               newexp = attr_eq (XSTR (exp, 0), p);
837               orexp = insert_right_side (IOR, orexp, newexp, -2);
838             }
839
840           return check_attr_test (orexp, is_const);
841         }
842       break;
843
844     case CONST_INT:
845       /* Either TRUE or FALSE.  */
846       if (XINT (exp, 0))
847         return true_rtx;
848       else
849         return false_rtx;
850
851     case IOR:
852     case AND:
853       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
854       XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const);
855       break;
856
857     case NOT:
858       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
859       break;
860
861     case MATCH_OPERAND:
862       if (is_const)
863         fatal ("RTL operator \"%s\" not valid in constant attribute test",
864                GET_RTX_NAME (MATCH_OPERAND));
865       /* These cases can't be simplified.  */
866       RTX_UNCHANGING_P (exp) = 1;
867       break;
868
869     case LE:  case LT:  case GT:  case GE:
870     case LEU: case LTU: case GTU: case GEU:
871     case NE:  case EQ:
872       if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
873           && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
874         exp = attr_rtx (GET_CODE (exp),
875                         attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
876                         attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
877       /* These cases can't be simplified.  */
878       RTX_UNCHANGING_P (exp) = 1;
879       break;
880
881     case SYMBOL_REF:
882       if (is_const)
883         {
884           /* These cases are valid for constant attributes, but can't be
885              simplified.  */
886           exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
887           RTX_UNCHANGING_P (exp) = 1;
888           break;
889         }
890     default:
891       fatal ("RTL operator \"%s\" not valid in attribute test",
892              GET_RTX_NAME (GET_CODE (exp)));
893     }
894
895   return exp;
896 }
897 \f
898 /* Given an expression, ensure that it is validly formed and that all named
899    attribute values are valid for the given attribute.  Issue a fatal error
900    if not.  If no attribute is specified, assume a numeric attribute.
901
902    Return a perhaps modified replacement expression for the value.  */
903
904 static rtx
905 check_attr_value (exp, attr)
906      rtx exp;
907      struct attr_desc *attr;
908 {
909   struct attr_value *av;
910   char *p;
911   int i;
912
913   switch (GET_CODE (exp))
914     {
915     case CONST_INT:
916       if (attr && ! attr->is_numeric)
917         fatal ("CONST_INT not valid for non-numeric `%s' attribute",
918                attr->name);
919
920       if (INTVAL (exp) < 0)
921         fatal ("Negative numeric value specified for `%s' attribute",
922                attr->name);
923
924       break;
925
926     case CONST_STRING:
927       if (! strcmp (XSTR (exp, 0), "*"))
928         break;
929
930       if (attr == 0 || attr->is_numeric)
931         {
932           for (p = XSTR (exp, 0); *p; p++)
933             if (*p > '9' || *p < '0')
934               fatal ("Non-numeric value for numeric `%s' attribute",
935                      attr ? attr->name : "internal");
936           break;
937         }
938
939       for (av = attr->first_value; av; av = av->next)
940         if (GET_CODE (av->value) == CONST_STRING
941             && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
942           break;
943
944       if (av == NULL)
945         fatal ("Unknown value `%s' for `%s' attribute",
946                XSTR (exp, 0), attr ? attr->name : "internal");
947
948       break;
949
950     case IF_THEN_ELSE:
951       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
952                                        attr ? attr->is_const : 0);
953       XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
954       XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
955       break;
956
957     case COND:
958       if (XVECLEN (exp, 0) % 2 != 0)
959         fatal ("First operand of COND must have even length");
960
961       for (i = 0; i < XVECLEN (exp, 0); i += 2)
962         {
963           XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
964                                                  attr ? attr->is_const : 0);
965           XVECEXP (exp, 0, i + 1)
966             = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
967         }
968
969       XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
970       break;
971
972     case SYMBOL_REF:
973       if (attr && attr->is_const)
974         /* A constant SYMBOL_REF is valid as a constant attribute test and
975            is expanded later by make_canonical into a COND.  */
976         return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
977       /* Otherwise, fall through... */
978
979     default:
980       fatal ("Illegal operation `%s' for attribute value",
981              GET_RTX_NAME (GET_CODE (exp)));
982     }
983
984   return exp;
985 }
986 \f
987 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
988    It becomes a COND with each test being (eq_attr "alternative "n") */
989
990 static rtx
991 convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
992      rtx exp;
993      int num_alt;
994      int insn_code, insn_index;
995 {
996   rtx newexp;
997   rtx condexp;
998   int i;
999
1000   if (XVECLEN (exp, 1) != num_alt)
1001     fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
1002            insn_index);
1003
1004   /* Make a COND with all tests but the last.  Select the last value via the
1005      default.  */
1006   condexp = rtx_alloc (COND);
1007   XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1008
1009   for (i = 0; i < num_alt - 1; i++)
1010     {
1011       char *p;
1012       p = attr_numeral (i);
1013
1014       XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1015 #if 0
1016       /* Sharing this EQ_ATTR rtl causes trouble.  */   
1017       XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
1018       XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
1019       XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p;
1020 #endif
1021       XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1022     }
1023
1024   XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1025
1026   return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1027 }
1028 \f
1029 /* Given a SET_ATTR, convert to the appropriate SET.  If a comma-separated
1030    list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */
1031
1032 static rtx
1033 convert_set_attr (exp, num_alt, insn_code, insn_index)
1034      rtx exp;
1035      int num_alt;
1036      int insn_code, insn_index;
1037 {
1038   rtx newexp;
1039   char *name_ptr;
1040   char *p;
1041   int n;
1042
1043   /* See how many alternative specified.  */
1044   n = n_comma_elts (XSTR (exp, 1));
1045   if (n == 1)
1046     return attr_rtx (SET,
1047                      attr_rtx (ATTR, XSTR (exp, 0)),
1048                      attr_rtx (CONST_STRING, XSTR (exp, 1)));
1049
1050   newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1051   XSTR (newexp, 0) = XSTR (exp, 0);
1052   XVEC (newexp, 1) = rtvec_alloc (n);
1053
1054   /* Process each comma-separated name.  */
1055   name_ptr = XSTR (exp, 1);
1056   n = 0;
1057   while ((p = next_comma_elt (&name_ptr)) != NULL)
1058     XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1059
1060   return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
1061 }
1062 \f
1063 /* Scan all definitions, checking for validity.  Also, convert any SET_ATTR
1064    and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1065    expressions. */
1066
1067 static void
1068 check_defs ()
1069 {
1070   struct insn_def *id;
1071   struct attr_desc *attr;
1072   int i;
1073   rtx value;
1074
1075   for (id = defs; id; id = id->next)
1076     {
1077       if (XVEC (id->def, id->vec_idx) == NULL)
1078         continue;
1079
1080       for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1081         {
1082           value = XVECEXP (id->def, id->vec_idx, i);
1083           switch (GET_CODE (value))
1084             {
1085             case SET:
1086               if (GET_CODE (XEXP (value, 0)) != ATTR)
1087                 fatal ("Bad attribute set in pattern %d", id->insn_index);
1088               break;
1089
1090             case SET_ATTR_ALTERNATIVE:
1091               value = convert_set_attr_alternative (value,
1092                                                     id->num_alternatives,
1093                                                     id->insn_code,
1094                                                     id->insn_index);
1095               break;
1096
1097             case SET_ATTR:
1098               value = convert_set_attr (value, id->num_alternatives,
1099                                         id->insn_code, id->insn_index);
1100               break;
1101
1102             default:
1103               fatal ("Invalid attribute code `%s' for pattern %d",
1104                      GET_RTX_NAME (GET_CODE (value)), id->insn_index);
1105             }
1106
1107           if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1108             fatal ("Unknown attribute `%s' for pattern number %d",
1109                    XSTR (XEXP (value, 0), 0), id->insn_index);
1110
1111           XVECEXP (id->def, id->vec_idx, i) = value;
1112           XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1113         }
1114     }
1115 }
1116 \f
1117 /* Given a constant SYMBOL_REF expression, convert to a COND that
1118    explicitly tests each enumerated value.  */
1119
1120 static rtx
1121 convert_const_symbol_ref (exp, attr)
1122      rtx exp;
1123      struct attr_desc *attr;
1124 {
1125   rtx condexp;
1126   struct attr_value *av;
1127   int i;
1128   int num_alt = 0;
1129
1130   for (av = attr->first_value; av; av = av->next)
1131     num_alt++;
1132
1133   /* Make a COND with all tests but the last, and in the original order.
1134      Select the last value via the default.  Note that the attr values
1135      are constructed in reverse order.  */
1136
1137   condexp = rtx_alloc (COND);
1138   XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1139   av = attr->first_value;
1140   XEXP (condexp, 1) = av->value;
1141
1142   for (i = num_alt - 2; av = av->next, i >= 0; i--)
1143     {
1144       char *p, *string;
1145       rtx value;
1146
1147       string = p = (char *) xmalloc (2
1148                                      + strlen (attr->name)
1149                                      + strlen (XSTR (av->value, 0)));
1150       strcpy (p, attr->name);
1151       strcat (p, "_");
1152       strcat (p, XSTR (av->value, 0));
1153       for (; *p != '\0'; p++)
1154         if (*p >= 'a' && *p <= 'z')
1155           *p -= 'a' - 'A';
1156
1157       value = attr_rtx (SYMBOL_REF, string);
1158       RTX_UNCHANGING_P (value) = 1;
1159       
1160       XVECEXP (condexp, 0, 2 * i) = attr_eq (exp, value);
1161
1162       XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1163     }
1164
1165   return condexp;
1166 }
1167 \f
1168 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1169    expressions by converting them into a COND.  This removes cases from this
1170    program.  Also, replace an attribute value of "*" with the default attribute
1171    value.  */
1172
1173 static rtx
1174 make_canonical (attr, exp)
1175      struct attr_desc *attr;
1176      rtx exp;
1177 {
1178   int i;
1179   rtx newexp;
1180
1181   switch (GET_CODE (exp))
1182     {
1183     case CONST_INT:
1184       exp = make_numeric_value (INTVAL (exp));
1185       break;
1186
1187     case CONST_STRING:
1188       if (! strcmp (XSTR (exp, 0), "*"))
1189         {
1190           if (attr == 0 || attr->default_val == 0)
1191             fatal ("(attr_value \"*\") used in invalid context.");
1192           exp = attr->default_val->value;
1193         }
1194
1195       break;
1196
1197     case SYMBOL_REF:
1198       if (!attr->is_const || RTX_UNCHANGING_P (exp))
1199         break;
1200       exp = convert_const_symbol_ref (exp, attr);
1201       RTX_UNCHANGING_P (exp) = 1;
1202       exp = check_attr_value (exp, attr);
1203       /* Goto COND case since this is now a COND.  Note that while the
1204          new expression is rescanned, all symbol_ref notes are mared as
1205          unchanging.  */
1206       goto cond;
1207
1208     case IF_THEN_ELSE:
1209       newexp = rtx_alloc (COND);
1210       XVEC (newexp, 0) = rtvec_alloc (2);
1211       XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1212       XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1213
1214       XEXP (newexp, 1) = XEXP (exp, 2);
1215
1216       exp = newexp;
1217       /* Fall through to COND case since this is now a COND.  */
1218
1219     case COND:
1220     cond:
1221       {
1222         int allsame = 1;
1223         rtx defval;
1224
1225         /* First, check for degenerate COND. */
1226         if (XVECLEN (exp, 0) == 0)
1227           return make_canonical (attr, XEXP (exp, 1));
1228         defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1229
1230         for (i = 0; i < XVECLEN (exp, 0); i += 2)
1231           {
1232             XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1233             XVECEXP (exp, 0, i + 1)
1234               = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1235             if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1236               allsame = 0;
1237           }
1238         if (allsame)
1239           return defval;
1240         break;
1241       }
1242     }
1243
1244   return exp;
1245 }
1246
1247 static rtx
1248 copy_boolean (exp)
1249      rtx exp;
1250 {
1251   if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1252     return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1253                      copy_boolean (XEXP (exp, 1)));
1254   return exp;
1255 }
1256 \f
1257 /* Given a value and an attribute description, return a `struct attr_value *'
1258    that represents that value.  This is either an existing structure, if the
1259    value has been previously encountered, or a newly-created structure.
1260
1261    `insn_code' is the code of an insn whose attribute has the specified
1262    value (-2 if not processing an insn).  We ensure that all insns for
1263    a given value have the same number of alternatives if the value checks
1264    alternatives.  */
1265
1266 static struct attr_value *
1267 get_attr_value (value, attr, insn_code)
1268      rtx value;
1269      struct attr_desc *attr;
1270      int insn_code;
1271 {
1272   struct attr_value *av;
1273   int num_alt = 0;
1274
1275   value = make_canonical (attr, value);
1276   if (compares_alternatives_p (value))
1277     {
1278       if (insn_code < 0 || insn_alternatives == NULL)
1279         fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1280       else
1281         num_alt = insn_alternatives[insn_code];
1282     }
1283
1284   for (av = attr->first_value; av; av = av->next)
1285     if (rtx_equal_p (value, av->value)
1286         && (num_alt == 0 || av->first_insn == NULL
1287             || insn_alternatives[av->first_insn->insn_code]))
1288       return av;
1289
1290   av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
1291   av->value = value;
1292   av->next = attr->first_value;
1293   attr->first_value = av;
1294   av->first_insn = NULL;
1295   av->num_insns = 0;
1296   av->has_asm_insn = 0;
1297
1298   return av;
1299 }
1300 \f
1301 /* After all DEFINE_DELAYs have been read in, create internal attributes
1302    to generate the required routines.
1303
1304    First, we compute the number of delay slots for each insn (as a COND of
1305    each of the test expressions in DEFINE_DELAYs).  Then, if more than one
1306    delay type is specified, we compute a similar function giving the
1307    DEFINE_DELAY ordinal for each insn.
1308
1309    Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1310    tells whether a given insn can be in that delay slot.
1311
1312    Normal attrbute filling and optimization expands these to contain the
1313    information needed to handle delay slots.  */
1314
1315 static void
1316 expand_delays ()
1317 {
1318   struct delay_desc *delay;
1319   rtx condexp;
1320   rtx newexp;
1321   int i;
1322   char *p;
1323
1324   /* First, generate data for `num_delay_slots' function.  */
1325
1326   condexp = rtx_alloc (COND);
1327   XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1328   XEXP (condexp, 1) = make_numeric_value (0);
1329
1330   for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1331     {
1332       XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1333       XVECEXP (condexp, 0, i + 1)
1334         = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1335     }
1336
1337   make_internal_attr ("*num_delay_slots", condexp, 0);
1338
1339   /* If more than one delay type, do the same for computing the delay type.  */
1340   if (num_delays > 1)
1341     {
1342       condexp = rtx_alloc (COND);
1343       XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1344       XEXP (condexp, 1) = make_numeric_value (0);
1345
1346       for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1347         {
1348           XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1349           XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1350         }
1351
1352       make_internal_attr ("*delay_type", condexp, 1);
1353     }
1354
1355   /* For each delay possibility and delay slot, compute an eligability
1356      attribute for non-anulled insns and for each type of annulled (annul
1357      if true and annul if false).  */
1358  for (delay = delays; delay; delay = delay->next)
1359    {
1360      for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1361        {
1362          condexp = XVECEXP (delay->def, 1, i);
1363          if (condexp == 0) condexp = false_rtx;
1364          newexp = attr_rtx (IF_THEN_ELSE, condexp,
1365                             make_numeric_value (1), make_numeric_value (0));
1366
1367          p = attr_printf (13, "*delay_%d_%d", delay->num, i / 3);
1368          make_internal_attr (p, newexp, 1);
1369
1370          if (have_annul_true)
1371            {
1372              condexp = XVECEXP (delay->def, 1, i + 1);
1373              if (condexp == 0) condexp = false_rtx;
1374              newexp = attr_rtx (IF_THEN_ELSE, condexp,
1375                                 make_numeric_value (1),
1376                                 make_numeric_value (0));
1377              p = attr_printf (18, "*annul_true_%d_%d", delay->num, i / 3);
1378              make_internal_attr (p, newexp, 1);
1379            }
1380
1381          if (have_annul_false)
1382            {
1383              condexp = XVECEXP (delay->def, 1, i + 2);
1384              if (condexp == 0) condexp = false_rtx;
1385              newexp = attr_rtx (IF_THEN_ELSE, condexp,
1386                                 make_numeric_value (1),
1387                                 make_numeric_value (0));
1388              p = attr_printf (18, "*annul_false_%d_%d", delay->num, i / 3);
1389              make_internal_attr (p, newexp, 1);
1390            }
1391        }
1392    }
1393 }
1394 \f
1395 /* This function is given a left and right side expression and an operator.
1396    Each side is a conditional expression, each alternative of which has a
1397    numerical value.  The function returns another conditional expression
1398    which, for every possible set of condition values, returns a value that is
1399    the operator applied to the values of the two sides.
1400
1401    Since this is called early, it must also support IF_THEN_ELSE.  */
1402
1403 static rtx
1404 operate_exp (op, left, right)
1405      enum operator op;
1406      rtx left, right;
1407 {
1408   int left_value, right_value;
1409   rtx newexp;
1410   int i;
1411
1412   /* If left is a string, apply operator to it and the right side.  */
1413   if (GET_CODE (left) == CONST_STRING)
1414     {
1415       /* If right is also a string, just perform the operation.  */
1416       if (GET_CODE (right) == CONST_STRING)
1417         {
1418           left_value = atoi (XSTR (left, 0));
1419           right_value = atoi (XSTR (right, 0));
1420           switch (op)
1421             {
1422             case PLUS_OP:
1423               i = left_value + right_value;
1424               break;
1425
1426             case MINUS_OP:
1427               i = left_value - right_value;
1428               break;
1429
1430             case OR_OP:
1431               i = left_value | right_value;
1432               break;
1433
1434             case MAX_OP:
1435               if (left_value > right_value)
1436                 i = left_value;
1437               else
1438                 i = right_value;
1439               break;
1440
1441             default:
1442               abort ();
1443             }
1444
1445           return make_numeric_value (i);
1446         }
1447       else if (GET_CODE (right) == IF_THEN_ELSE)
1448         {
1449           /* Apply recursively to all values within.  */
1450           rtx newleft = operate_exp (op, left, XEXP (right, 1));
1451           rtx newright = operate_exp (op, left, XEXP (right, 2));
1452           if (rtx_equal_p (newleft, newright))
1453             return newleft;
1454           return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1455         }
1456       else if (GET_CODE (right) == COND)
1457         {
1458           int allsame = 1;
1459           rtx defval;
1460
1461           newexp = rtx_alloc (COND);
1462           XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1463           defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1464
1465           for (i = 0; i < XVECLEN (right, 0); i += 2)
1466             {
1467               XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1468               XVECEXP (newexp, 0, i + 1)
1469                 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1470               if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1471                                  defval))     
1472                 allsame = 0;
1473             }
1474
1475           /* If the resulting cond is trivial (all alternatives
1476              give the same value), optimize it away.  */
1477           if (allsame)
1478             {
1479               obstack_free (rtl_obstack, newexp);
1480               return operate_exp (op, left, XEXP (right, 1));
1481             }
1482
1483           /* If the result is the same as the RIGHT operand,
1484              just use that.  */
1485           if (rtx_equal_p (newexp, right))
1486             {
1487               obstack_free (rtl_obstack, newexp);
1488               return right;
1489             }
1490
1491           return newexp;
1492         }
1493       else
1494         fatal ("Badly formed attribute value");
1495     }
1496
1497   /* Otherwise, do recursion the other way.  */
1498   else if (GET_CODE (left) == IF_THEN_ELSE)
1499     {
1500       rtx newleft = operate_exp (op, XEXP (left, 1), right);
1501       rtx newright = operate_exp (op, XEXP (left, 2), right);
1502       if (rtx_equal_p (newleft, newright))
1503         return newleft;
1504       return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1505     }
1506   else if (GET_CODE (left) == COND)
1507     {
1508       int allsame = 1;
1509       rtx defval;
1510
1511       newexp = rtx_alloc (COND);
1512       XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1513       defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1514
1515       for (i = 0; i < XVECLEN (left, 0); i += 2)
1516         {
1517           XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1518           XVECEXP (newexp, 0, i + 1)
1519             = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1520           if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1521                              defval))     
1522             allsame = 0;
1523         }
1524
1525       /* If the cond is trivial (all alternatives give the same value),
1526          optimize it away.  */
1527       if (allsame)
1528         {
1529           obstack_free (rtl_obstack, newexp);
1530           return operate_exp (op, XEXP (left, 1), right);
1531         }
1532
1533       /* If the result is the same as the LEFT operand,
1534          just use that.  */
1535       if (rtx_equal_p (newexp, left))
1536         {
1537           obstack_free (rtl_obstack, newexp);
1538           return left;
1539         }
1540
1541       return newexp;
1542     }
1543
1544   else
1545     fatal ("Badly formed attribute value.");
1546   /* NOTREACHED */
1547   return NULL;
1548 }
1549 \f
1550 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1551    construct a number of attributes.
1552
1553    The first produces a function `function_units_used' which is given an
1554    insn and produces a mask showing which function units are required for
1555    the execution of that insn.
1556
1557    The second produces a function `result_ready_cost' which is used to
1558    determine the time that the result of an insn will be ready and hence
1559    a worst-case schedule.
1560
1561    Both of these produce quite complex expressions which are then set as the
1562    default value of internal attributes.  Normal attribute simplification
1563    should produce reasonable expressions.
1564
1565    For each unit, a `<name>_unit_ready_cost' function will take an
1566    insn and give the delay until that unit will be ready with the result
1567    and a `<name>_unit_busy_delay' function is given an insn already
1568    executing on the unit and a candidate to execute and will give the
1569    cost from the time the executing insn started until the candidate
1570    can start (ignore limitations on the number of simultaneous insns).  */
1571
1572 static void
1573 expand_units ()
1574 {
1575   struct function_unit *unit;
1576   struct function_unit_op *op;
1577   rtx unitsmask;
1578   rtx readycost;
1579   rtx newexp;
1580   char *str;
1581
1582   /* Initially, cost and masks are zero.  */
1583   unitsmask = readycost = make_numeric_value (0);
1584
1585   /* Set up a conditional for costs and unit mask.  */
1586   newexp = rtx_alloc (IF_THEN_ELSE);
1587   XEXP (newexp, 2) = make_numeric_value (0);
1588
1589   /* For each unit, insert its contribution to the above three values.  */
1590   for (unit = units; unit; unit = unit->next)
1591     {
1592       /* An expression that computes the ready cost for this unit.  */
1593       rtx readyexp = rtx_alloc (COND);
1594       /* An expression that maps insns to operation number for conflicts.  */
1595       rtx caseexp = rtx_alloc (COND);
1596
1597       XVEC (readyexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
1598       XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
1599
1600       for (op = unit->ops; op; op = op->next)
1601         {
1602           /* Validate the expressions we were given for the conditions
1603              and busy cost.  Then make an attribute for use in the conflict
1604              function.  */
1605           op->condexp = check_attr_test (op->condexp, 0);
1606           op->busyexp = check_attr_value (op->busyexp, 0);
1607           str = attr_printf (strlen (unit->name) + 11, "*%s_case_%d",
1608                              unit->name, op->num);
1609           make_internal_attr (str, make_canonical (0, op->busyexp));
1610
1611           /* Make our adjustment to the two COND's being computed.  If we are
1612              the last operation class, place our values into the default of
1613              the COND.  */
1614           if (op->num == unit->num_opclasses - 1)
1615             {
1616               XEXP (readyexp, 1) = make_numeric_value (op->ready);
1617               XEXP (caseexp, 1) = make_numeric_value (op->num);
1618             }
1619           else
1620             {
1621               XVECEXP (readyexp, 0, op->num * 2) = op->condexp;
1622               XVECEXP (readyexp, 0, op->num * 2 + 1)
1623                 = make_numeric_value (op->ready);
1624               XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
1625               XVECEXP (caseexp, 0, op->num * 2 + 1)
1626                 = make_numeric_value (op->num);
1627             }
1628         }
1629
1630       /* Make an attribute for the case number and ready delay.  */
1631       str = attr_printf (strlen (unit->name) + 8, "*%s_cases", unit->name);
1632       make_internal_attr (str, caseexp, 1);
1633
1634       str = attr_printf (strlen (unit->name) + 20, "*%s_unit_ready_cost",
1635                          unit->name);
1636       make_internal_attr (str, readyexp, 0);
1637
1638       /* Merge this function unit into the ready cost and unit mask
1639          attributes.  */
1640       XEXP (newexp, 0) = check_attr_test (unit->condexp, 0);
1641       XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1642       unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1643
1644       XEXP (newexp, 1) = readyexp;
1645       readycost = operate_exp (MAX_OP, readycost, newexp);
1646     }
1647
1648   make_internal_attr ("*function_units_used", unitsmask, 0);
1649   make_internal_attr ("*result_ready_cost", readycost, 0);
1650 }
1651 \f
1652 /* Once all attributes and insns have been read and checked, we construct for
1653    each attribute value a list of all the insns that have that value for
1654    the attribute.  */
1655
1656 static void
1657 fill_attr (attr)
1658      struct attr_desc *attr;
1659 {
1660   struct attr_value *av;
1661   struct insn_ent *ie;
1662   struct insn_def *id;
1663   int i;
1664   rtx value;
1665
1666   for (id = defs; id; id = id->next)
1667     {
1668       /* If no value is specified for this insn for this attribute, use the
1669          default.  */
1670       value = NULL;
1671       if (XVEC (id->def, id->vec_idx))
1672         for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1673           if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0), 
1674                         attr->name))
1675             value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1676
1677       if (value == NULL)
1678         av = attr->default_val;
1679       else
1680         av = get_attr_value (value, attr, id->insn_code);
1681
1682       ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1683       ie->insn_code = id->insn_code;
1684       ie->insn_index = id->insn_code;
1685       insert_insn_ent (av, ie);
1686     }
1687 }
1688 \f
1689 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1690    test that checks relative positions of insns (uses MATCH_DUP or PC).
1691    If so, replace it with what is obtained by passing the expression to
1692    ADDRESS_FN.  If not but it is a COND or IF_THEN_ELSE, call this routine
1693    recursively on each value (including the default value).  Otherwise,
1694    return the value returned by NO_ADDRESS_FN applied to EXP.  */
1695
1696 static rtx
1697 substitute_address (exp, no_address_fn, address_fn)
1698      rtx exp;
1699      rtx (*no_address_fn) ();
1700      rtx (*address_fn) ();
1701 {
1702   int i;
1703   rtx newexp;
1704
1705   if (GET_CODE (exp) == COND)
1706     {
1707       /* See if any tests use addresses.  */
1708       address_used = 0;
1709       for (i = 0; i < XVECLEN (exp, 0); i += 2)
1710         walk_attr_value (XVECEXP (exp, 0, i));
1711
1712       if (address_used)
1713         return (*address_fn) (exp);
1714
1715       /* Make a new copy of this COND, replacing each element.  */
1716       newexp = rtx_alloc (COND);
1717       XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1718       for (i = 0; i < XVECLEN (exp, 0); i += 2)
1719         {
1720           XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1721           XVECEXP (newexp, 0, i + 1)
1722             = substitute_address (XVECEXP (exp, 0, i + 1),
1723                                   no_address_fn, address_fn);
1724         }
1725
1726       XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1727                                              no_address_fn, address_fn);
1728
1729       return newexp;
1730     }
1731
1732   else if (GET_CODE (exp) == IF_THEN_ELSE)
1733     {
1734       address_used = 0;
1735       walk_attr_value (XEXP (exp, 0));
1736       if (address_used)
1737         return (*address_fn) (exp);
1738
1739       return attr_rtx (IF_THEN_ELSE,
1740                        substitute_address (XEXP (exp, 0),
1741                                            no_address_fn, address_fn),
1742                        substitute_address (XEXP (exp, 1),
1743                                            no_address_fn, address_fn),
1744                        substitute_address (XEXP (exp, 2),
1745                                            no_address_fn, address_fn));
1746     }
1747
1748   return (*no_address_fn) (exp);
1749 }
1750 \f
1751 /* Make new attributes from the `length' attribute.  The following are made,
1752    each corresponding to a function called from `shorten_branches' or
1753    `get_attr_length':
1754
1755    *insn_default_length         This is the length of the insn to be returned
1756                                 by `get_attr_length' before `shorten_branches'
1757                                 has been called.  In each case where the length
1758                                 depends on relative addresses, the largest
1759                                 possible is used.  This routine is also used
1760                                 to compute the initial size of the insn.
1761
1762    *insn_variable_length_p      This returns 1 if the insn's length depends
1763                                 on relative addresses, zero otherwise.
1764
1765    *insn_current_length         This is only called when it is known that the
1766                                 insn has a variable length and returns the
1767                                 current length, based on relative addresses.
1768   */
1769
1770 static void
1771 make_length_attrs ()
1772 {
1773   static char *new_names[] = {"*insn_default_length",
1774                               "*insn_variable_length_p",
1775                               "*insn_current_length"};
1776   static rtx (*no_address_fn[]) () = {identity_fn, zero_fn, zero_fn};
1777   static rtx (*address_fn[]) () = {max_fn, one_fn, identity_fn};
1778   int i;
1779   struct attr_desc *length_attr, *new_attr;
1780   struct attr_value *av, *new_av;
1781   struct insn_ent *ie, *new_ie;
1782
1783   /* See if length attribute is defined.  If so, it must be numeric.  Make
1784      it special so we don't output anything for it.  */
1785   length_attr = find_attr ("length", 0);
1786   if (length_attr == 0)
1787     return;
1788
1789   if (! length_attr->is_numeric)
1790     fatal ("length attribute must be numeric.");
1791
1792   length_attr->is_const = 0;
1793   length_attr->is_special = 1;
1794
1795   /* Make each new attribute, in turn.  */
1796   for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
1797     {
1798       make_internal_attr (new_names[i],
1799                           substitute_address (length_attr->default_val->value,
1800                                               no_address_fn[i], address_fn[i]),
1801                           0);
1802       new_attr = find_attr (new_names[i], 0);
1803       for (av = length_attr->first_value; av; av = av->next)
1804         for (ie = av->first_insn; ie; ie = ie->next)
1805           {
1806             new_av = get_attr_value (substitute_address (av->value,
1807                                                          no_address_fn[i],
1808                                                          address_fn[i]),
1809                                      new_attr, ie->insn_code);
1810             new_ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1811             new_ie->insn_code = ie->insn_code;
1812             new_ie->insn_index = ie->insn_index;
1813             insert_insn_ent (new_av, new_ie);
1814           }
1815     }
1816 }
1817
1818 /* Utility functions called from above routine.  */
1819
1820 static rtx
1821 identity_fn (exp)
1822      rtx exp;
1823 {
1824   return exp;
1825 }
1826
1827 static rtx
1828 zero_fn (exp)
1829      rtx exp;
1830 {
1831   return make_numeric_value (0);
1832 }
1833
1834 static rtx
1835 one_fn (exp)
1836      rtx exp;
1837 {
1838   return make_numeric_value (1);
1839 }
1840
1841 static rtx
1842 max_fn (exp)
1843      rtx exp;
1844 {
1845   return make_numeric_value (max_attr_value (exp));
1846 }
1847 \f
1848 /* Take a COND expression and see if any of the conditions in it can be
1849    simplified.  If any are known true or known false for the particular insn
1850    code, the COND can be further simplified.
1851
1852    Also call ourselves on any COND operations that are values of this COND.
1853
1854    We do not modify EXP; rather, we make and return a new rtx.  */
1855
1856 static rtx
1857 simplify_cond (exp, insn_code, insn_index)
1858      rtx exp;
1859      int insn_code, insn_index;
1860 {
1861   int i, j;
1862   /* We store the desired contents here,
1863      then build a new expression if they don't match EXP.  */
1864   rtx defval = XEXP (exp, 1);
1865   rtx new_defval = XEXP (exp, 1);
1866
1867   int len = XVECLEN (exp, 0);
1868   rtx *tests = (rtx *) alloca (len * sizeof (rtx));
1869   int allsame = 1;
1870   char *spacer, *first_spacer;
1871
1872   /* This lets us free all storage allocated below, if appropriate.  */
1873   first_spacer = (char *) obstack_finish (rtl_obstack);
1874
1875   bcopy (&XVECEXP (exp, 0, 0), tests, len * sizeof (rtx));
1876
1877   /* See if default value needs simplification.  */
1878   if (GET_CODE (defval) == COND)
1879     new_defval = simplify_cond (defval, insn_code, insn_index);
1880
1881   /* Simplify the subexpressions, and see what tests we can get rid of.  */
1882
1883   for (i = 0; i < len; i += 2)
1884     {
1885       rtx newtest, newval;
1886
1887       /* Simplify this test.  */
1888       newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index);
1889       tests[i] = newtest;
1890
1891       newval = tests[i + 1];
1892       /* See if this value may need simplification.  */
1893       if (GET_CODE (newval) == COND)
1894         newval = simplify_cond (newval, insn_code, insn_index);
1895
1896       /* Look for ways to delete or combine this test.  */
1897       if (newtest == true_rtx)
1898         {
1899           /* If test is true, make this value the default
1900              and discard this + any following tests.  */
1901           len = i;
1902           defval = tests[i + 1];
1903           new_defval = newval;
1904         }
1905
1906       else if (newtest == false_rtx)
1907         {
1908           /* If test is false, discard it and its value.  */
1909           for (j = i; j < len - 2; j++)
1910             tests[j] = tests[j + 2];
1911           len -= 2;
1912         }
1913
1914       else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1915         {
1916           /* If this value and the value for the prev test are the same,
1917              merge the tests.  */
1918
1919           tests[i - 2]
1920             = insert_right_side (IOR, tests[i - 2], newtest,
1921                                  insn_code, insn_index);
1922
1923           /* Delete this test/value.  */
1924           for (j = i; j < len - 2; j++)
1925             tests[j] = tests[j + 2];
1926           len -= 2;
1927         }
1928
1929       else
1930         tests[i + 1] = newval;
1931     }
1932
1933   /* If the last test in a COND has the same value
1934      as the default value, that test isn't needed.  */
1935
1936   while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1937     len -= 2;
1938
1939   /* See if we changed anything.  */
1940   if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1941     allsame = 0;
1942   else
1943     for (i = 0; i < len; i++)
1944       if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1945         {
1946           allsame = 0;
1947           break;
1948         }
1949
1950   if (len == 0)
1951     {
1952       obstack_free (rtl_obstack, first_spacer);
1953       if (GET_CODE (defval) == COND)
1954         return simplify_cond (defval, insn_code, insn_index);
1955       return defval;
1956     }
1957   else if (allsame)
1958     {
1959       obstack_free (rtl_obstack, first_spacer);
1960       return exp;
1961     }
1962   else
1963     {
1964       rtx newexp = rtx_alloc (COND);
1965
1966       XVEC (newexp, 0) = rtvec_alloc (len);
1967       bcopy (tests, &XVECEXP (newexp, 0, 0), len * sizeof (rtx));
1968       XEXP (newexp, 1) = new_defval;
1969       return newexp;
1970     }
1971 }
1972 \f
1973 /* Remove an insn entry from an attribute value.  */
1974
1975 static void
1976 remove_insn_ent (av, ie)
1977      struct attr_value *av;
1978      struct insn_ent *ie;
1979 {
1980   struct insn_ent *previe;
1981
1982   if (av->first_insn == ie)
1983     av->first_insn = ie->next;
1984   else
1985     {
1986       for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1987         ;
1988       previe->next = ie->next;
1989     }
1990
1991   av->num_insns--;
1992   if (ie->insn_code == -1)
1993     av->has_asm_insn = 0;
1994 }
1995
1996 /* Insert an insn entry in an attribute value list.  */
1997
1998 static void
1999 insert_insn_ent (av, ie)
2000      struct attr_value *av;
2001      struct insn_ent *ie;
2002 {
2003   ie->next = av->first_insn;
2004   av->first_insn = ie;
2005   av->num_insns++;
2006   if (ie->insn_code == -1)
2007     av->has_asm_insn = 1;
2008 }
2009 \f
2010 /* This is a utility routine to take an expression that is a tree of either
2011    AND or IOR expressions and insert a new term.  The new term will be
2012    inserted at the right side of the first node whose code does not match
2013    the root.  A new node will be created with the root's code.  Its left
2014    side will be the old right side and its right side will be the new
2015    term.
2016
2017    If the `term' is itself a tree, all its leaves will be inserted.  */
2018
2019 static rtx
2020 insert_right_side (code, exp, term, insn_code, insn_index)
2021      RTX_CODE code;
2022      rtx exp;
2023      rtx term;
2024      int insn_code, insn_index;
2025 {
2026   rtx newexp;
2027
2028   /* Avoid consing in some special cases.  */
2029   if (code == AND && term == true_rtx)
2030     return exp;
2031   if (code == AND && term == false_rtx)
2032     return false_rtx;
2033   if (code == AND && exp == true_rtx)
2034     return term;
2035   if (code == AND && exp == false_rtx)
2036     return false_rtx;
2037   if (code == IOR && term == true_rtx)
2038     return true_rtx;
2039   if (code == IOR && term == false_rtx)
2040     return exp;
2041   if (code == IOR && exp == true_rtx)
2042     return true_rtx;
2043   if (code == IOR && exp == false_rtx)
2044     return term;
2045   if (attr_equal_p (exp, term))
2046     return exp;
2047
2048   if (GET_CODE (term) == code)
2049     {
2050       exp = insert_right_side (code, exp, XEXP (term, 0),
2051                                insn_code, insn_index);
2052       exp = insert_right_side (code, exp, XEXP (term, 1),
2053                                insn_code, insn_index);
2054
2055       return exp;
2056     }
2057
2058   if (GET_CODE (exp) == code)
2059     {
2060       rtx new = insert_right_side (code, XEXP (exp, 1),
2061                                    term, insn_code, insn_index);
2062       if (new != XEXP (exp, 1))
2063         /* Make a copy of this expression and call recursively.  */
2064         newexp = attr_rtx (code, XEXP (exp, 0), new);
2065       else
2066         newexp = exp;
2067     }
2068   else
2069     {
2070       /* Insert the new term.  */
2071       newexp = attr_rtx (code, exp, term);
2072     }
2073
2074   return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2075 }
2076 \f
2077 /* If we have an expression which AND's a bunch of
2078         (not (eq_attrq "alternative" "n"))
2079    terms, we may have covered all or all but one of the possible alternatives.
2080    If so, we can optimize.  Similarly for IOR's of EQ_ATTR.
2081
2082    This routine is passed an expression and either AND or IOR.  It returns a
2083    bitmask indicating which alternatives are present.  */
2084
2085 static int
2086 compute_alternative_mask (exp, code)
2087      rtx exp;
2088      RTX_CODE code;
2089 {
2090   if (GET_CODE (exp) == code)
2091     return compute_alternative_mask (XEXP (exp, 0), code)
2092            | compute_alternative_mask (XEXP (exp, 1), code);
2093
2094   else if (code == AND && GET_CODE (exp) == NOT
2095            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2096            && XSTR (XEXP (exp, 0), 0) == alternative_name)
2097     return 1 << atoi (XSTR (XEXP (exp, 0), 1));
2098
2099   else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2100            && XSTR (exp, 0) == alternative_name)
2101     return 1 << atoi (XSTR (exp, 1));
2102
2103   else
2104     return 0;
2105 }
2106
2107 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2108    attribute with the value represented by that bit.  */
2109
2110 static rtx
2111 make_alternative_compare (mask)
2112      int mask;
2113 {
2114   rtx newexp;
2115   int i;
2116   char *alternative;
2117
2118   /* Find the bit.  */
2119   for (i = 0; (mask & (1 << i)) == 0; i++)
2120     ;
2121
2122   newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2123   RTX_UNCHANGING_P (newexp) = 1;
2124
2125   return newexp;
2126 }
2127 \f
2128 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2129    of "attr" for this insn code.  From that value, we can compute a test
2130    showing when the EQ_ATTR will be true.  This routine performs that
2131    computation.  If a test condition involves an address, we leave the EQ_ATTR
2132    intact because addresses are only valid for the `length' attribute.  */
2133
2134 /* ??? Kenner, document the meanings of the arguments!!!  */
2135
2136 static rtx
2137 evaluate_eq_attr (exp, value, insn_code, insn_index)
2138      rtx exp;
2139      rtx value;
2140      int insn_code, insn_index;
2141 {
2142   rtx orexp, andexp;
2143   rtx right;
2144   rtx newexp;
2145   int i;
2146
2147   if (GET_CODE (value) == CONST_STRING)
2148     {
2149       if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2150         newexp = true_rtx;
2151       else
2152         newexp = false_rtx;
2153     }
2154   else if (GET_CODE (value) == COND)
2155     {
2156       /* We construct an IOR of all the cases for which the requested attribute
2157          value is present.  Since we start with FALSE, if it is not present,
2158          FALSE will be returned.
2159
2160          Each case is the AND of the NOT's of the previous conditions with the
2161          current condition; in the default case the current condition is TRUE. 
2162
2163          For each possible COND value, call ourselves recursively.
2164
2165          The extra TRUE and FALSE expressions will be eliminated by another
2166          call to the simplification routine. */
2167
2168       orexp = false_rtx;
2169       andexp = true_rtx;
2170
2171       for (i = 0; i < XVECLEN (value, 0); i += 2)
2172         {
2173           rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
2174                                         insn_code, insn_index);
2175
2176           right = insert_right_side (AND, andexp, this,
2177                                      insn_code, insn_index);
2178           right = insert_right_side (AND, right,
2179                         evaluate_eq_attr (exp, XVECEXP (value, 0, i + 1),
2180                                            insn_code, insn_index),
2181                                      insn_code, insn_index);
2182           orexp = insert_right_side (IOR, orexp, right,
2183                                      insn_code, insn_index);
2184
2185           /* Add this condition into the AND expression.  */
2186           newexp = attr_rtx (NOT, this);
2187           andexp = insert_right_side (AND, andexp, newexp,
2188                                       insn_code, insn_index);
2189         }
2190
2191       /* Handle the default case.  */
2192       right = insert_right_side (AND, andexp,
2193                                  evaluate_eq_attr (exp, XEXP (value, 1),
2194                                                     insn_code, insn_index),
2195                                  insn_code, insn_index);
2196       newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2197     }
2198   else
2199     abort ();
2200
2201   /* If uses an address, must return original expression.  But set the
2202      RTX_UNCHANGING_P bit so we don't try to simplify it again.  */
2203
2204   address_used = 0;
2205   walk_attr_value (newexp);
2206
2207   if (address_used)
2208     {
2209       if (! RTX_UNCHANGING_P (exp))
2210         return copy_rtx_unchanging (exp);
2211       return exp;
2212     }
2213   else
2214     return newexp;
2215 }
2216 \f
2217 /* This routine is called when an AND of a term with a tree of AND's is
2218    encountered.  If the term or its complement is present in the tree, it
2219    can be replaced with TRUE or FALSE, respectively.
2220
2221    Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2222    be true and hence are complementary.  
2223
2224    There is one special case:  If we see
2225         (and (not (eq_attr "att" "v1"))
2226              (eq_attr "att" "v2"))
2227    this can be replaced by (eq_attr "att" "v2").  To do this we need to
2228    replace the term, not anything in the AND tree.  So we pass a pointer to
2229    the term.  */
2230
2231 static rtx
2232 simplify_and_tree (exp, pterm, insn_code, insn_index)
2233      rtx exp;
2234      rtx *pterm;
2235      int insn_code, insn_index;
2236 {
2237   rtx left, right;
2238   rtx newexp;
2239   rtx temp;
2240   int left_eliminates_term, right_eliminates_term;
2241
2242   if (GET_CODE (exp) == AND)
2243     {
2244       left = simplify_and_tree (XEXP (exp, 0), pterm,  insn_code, insn_index);
2245       right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2246       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2247         {
2248           newexp = attr_rtx (GET_CODE (exp), left, right);
2249
2250           exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2251         }
2252     }
2253
2254   else if (GET_CODE (exp) == IOR)
2255     {
2256       /* For the IOR case, we do the same as above, except that we can
2257          only eliminate `term' if both sides of the IOR would do so.  */
2258       temp = *pterm;
2259       left = simplify_and_tree (XEXP (exp, 0), &temp,  insn_code, insn_index);
2260       left_eliminates_term = (temp == true_rtx);
2261
2262       temp = *pterm;
2263       right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2264       right_eliminates_term = (temp == true_rtx);
2265
2266       if (left_eliminates_term && right_eliminates_term)
2267         *pterm = true_rtx;
2268
2269       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2270         {
2271           newexp = attr_rtx (GET_CODE (exp), left, right);
2272
2273           exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2274         }
2275     }
2276
2277   /* Check for simplifications.  Do some extra checking here since this
2278      routine is called so many times.  */
2279
2280   if (exp == *pterm)
2281     return true_rtx;
2282
2283   else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2284     return false_rtx;
2285
2286   else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2287     return false_rtx;
2288
2289   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2290     {
2291       if (XSTR (exp, 0) != XSTR (*pterm, 0))
2292         return exp;
2293
2294       if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
2295         return true_rtx;
2296       else
2297         return false_rtx;
2298     }
2299
2300   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2301            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2302     {
2303       if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2304         return exp;
2305
2306       if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2307         return false_rtx;
2308       else
2309         return true_rtx;
2310     }
2311
2312   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2313            && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2314     {
2315       if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2316         return exp;
2317
2318       if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2319         return false_rtx;
2320       else
2321         *pterm = true_rtx;
2322     }
2323
2324   else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2325     {
2326       if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2327         return true_rtx;
2328     }
2329
2330   else if (GET_CODE (exp) == NOT)
2331     {
2332       if (attr_equal_p (XEXP (exp, 0), *pterm))
2333         return false_rtx;
2334     }
2335
2336   else if (GET_CODE (*pterm) == NOT)
2337     {
2338       if (attr_equal_p (XEXP (*pterm, 0), exp))
2339         return false_rtx;
2340     }
2341
2342   else if (attr_equal_p (exp, *pterm))
2343     return true_rtx;
2344
2345   return exp;
2346 }
2347 \f
2348 /* Similiar to `simplify_and_tree', but for IOR trees.  */
2349
2350 static rtx
2351 simplify_or_tree (exp, pterm, insn_code, insn_index)
2352      rtx exp;
2353      rtx *pterm;
2354      int insn_code, insn_index;
2355 {
2356   rtx left, right;
2357   rtx newexp;
2358   rtx temp;
2359   int left_eliminates_term, right_eliminates_term;
2360
2361   if (GET_CODE (exp) == IOR)
2362     {
2363       left = simplify_or_tree (XEXP (exp, 0), pterm,  insn_code, insn_index);
2364       right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2365       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2366         {
2367           newexp = attr_rtx (GET_CODE (exp), left, right);
2368
2369           exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2370         }
2371     }
2372
2373   else if (GET_CODE (exp) == AND)
2374     {
2375       /* For the AND case, we do the same as above, except that we can
2376          only eliminate `term' if both sides of the AND would do so.  */
2377       temp = *pterm;
2378       left = simplify_or_tree (XEXP (exp, 0), &temp,  insn_code, insn_index);
2379       left_eliminates_term = (temp == false_rtx);
2380
2381       temp = *pterm;
2382       right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2383       right_eliminates_term = (temp == false_rtx);
2384
2385       if (left_eliminates_term && right_eliminates_term)
2386         *pterm = false_rtx;
2387
2388       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2389         {
2390           newexp = attr_rtx (GET_CODE (exp), left, right);
2391
2392           exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2393         }
2394     }
2395
2396   if (attr_equal_p (exp, *pterm))
2397     return false_rtx;
2398
2399   else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2400     return true_rtx;
2401
2402   else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2403     return true_rtx;
2404
2405   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2406            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2407            && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2408     *pterm = false_rtx;
2409
2410   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2411            && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2412            && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2413     return false_rtx;
2414
2415   return exp;
2416 }
2417 \f
2418 /* Given an expression, see if it can be simplified for a particular insn
2419    code based on the values of other attributes being tested.  This can
2420    eliminate nested get_attr_... calls.
2421
2422    Note that if an endless recursion is specified in the patterns, the 
2423    optimization will loop.  However, it will do so in precisely the cases where
2424    an infinite recursion loop could occur during compilation.  It's better that
2425    it occurs here!  */
2426
2427 static rtx
2428 simplify_test_exp (exp, insn_code, insn_index)
2429      rtx exp;
2430      int insn_code, insn_index;
2431 {
2432   rtx left, right;
2433   struct attr_desc *attr;
2434   struct attr_value *av;
2435   struct insn_ent *ie;
2436   int i;
2437   rtx newexp = exp;
2438   char *spacer = (char *) obstack_finish (rtl_obstack);
2439
2440   static rtx loser = 0;
2441   static int count = 0;
2442   static stopcount = 0;
2443
2444   if (exp == loser)
2445     do_nothing ();
2446   count++;
2447   if (count == stopcount)
2448     do_nothing ();
2449
2450   /* Don't re-simplify something we already simplified.  */
2451   if (RTX_UNCHANGING_P (exp))
2452     return exp;
2453
2454   switch (GET_CODE (exp))
2455     {
2456     case AND:
2457       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2458       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2459
2460       /* If either side is an IOR and we have (eq_attr "alternative" ..")
2461          present on both sides, apply the distributive law since this will
2462          yield simplifications.  */
2463       if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2464           && compute_alternative_mask (left, IOR)
2465           && compute_alternative_mask (right, IOR))
2466         {
2467           if (GET_CODE (left) == IOR)
2468             {
2469               rtx tem = left;
2470               left = right;
2471               right = tem;
2472             }
2473
2474           newexp = attr_rtx (IOR,
2475                              attr_rtx (AND, left, XEXP (right, 0)),
2476                              attr_rtx (AND, left, XEXP (right, 1)));
2477
2478           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2479         }
2480
2481       /* Try with the term on both sides.  */
2482       right = simplify_and_tree (right, &left, insn_code, insn_index);
2483       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2484         left = simplify_and_tree (left, &right, insn_code, insn_index);
2485
2486       if (left == false_rtx || right == false_rtx)
2487         {
2488           obstack_free (rtl_obstack, spacer);
2489           return false_rtx;
2490         }
2491       else if (left == true_rtx)
2492         {
2493           obstack_free (rtl_obstack, spacer);
2494           return SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2495         }
2496       else if (right == true_rtx)
2497         {
2498           obstack_free (rtl_obstack, spacer);
2499           return SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2500         }
2501
2502       /* See if all or all but one of the insn's alternatives are specified
2503          in this tree.  Optimize if so.  */
2504
2505       else if (insn_code >= 0
2506                && (GET_CODE (left) == AND
2507                    || (GET_CODE (left) == NOT
2508                        && GET_CODE (XEXP (left, 0)) == EQ_ATTR
2509                        && XSTR (XEXP (left, 0), 0) == alternative_name)
2510                    || GET_CODE (right) == AND
2511                    || (GET_CODE (right) == NOT
2512                        && GET_CODE (XEXP (right, 0)) == EQ_ATTR
2513                        && XSTR (XEXP (right, 0), 0) == alternative_name)))
2514         {
2515           i = compute_alternative_mask (exp, AND);
2516           if (i & ~insn_alternatives[insn_code])
2517             fatal ("Illegal alternative specified for pattern number %d",
2518                    insn_index);
2519
2520           /* If all alternatives are excluded, this is false. */
2521           i ^= insn_alternatives[insn_code];
2522           if (i == 0)
2523             return false_rtx;
2524           else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2525             {
2526               /* If just one excluded, AND a comparison with that one to the
2527                  front of the tree.  The others will be eliminated by
2528                  optimization.  We do not want to do this if the insn has one
2529                  alternative and we have tested none of them!  */
2530               left = make_alternative_compare (i);
2531               right = simplify_and_tree (exp, &left, insn_code, insn_index);
2532               newexp = attr_rtx (AND, left, right);
2533
2534               return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2535             }
2536         }
2537
2538       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2539         {
2540           newexp = attr_rtx (AND, left, right);
2541           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2542         }
2543       break;
2544
2545     case IOR:
2546       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2547       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2548
2549       right = simplify_or_tree (right, &left, insn_code, insn_index);
2550       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2551         left = simplify_or_tree (left, &right, insn_code, insn_index);
2552
2553       if (right == true_rtx || left == true_rtx)
2554         {
2555           obstack_free (rtl_obstack, spacer);
2556           return true_rtx;
2557         }
2558       else if (left == false_rtx)
2559         {
2560           obstack_free (rtl_obstack, spacer);
2561           return SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2562         }
2563       else if (right == false_rtx)
2564         {
2565           obstack_free (rtl_obstack, spacer);
2566           return SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2567         }
2568
2569       /* Test for simple cases where the distributive law is useful.  I.e.,
2570             convert (ior (and (x) (y))
2571                          (and (x) (z)))
2572             to      (and (x)
2573                          (ior (y) (z)))
2574        */
2575
2576       else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2577           && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2578         {
2579           newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2580
2581           left = XEXP (left, 0);
2582           right = newexp;
2583           newexp = attr_rtx (AND, left, right);
2584           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2585         }
2586
2587       /* See if all or all but one of the insn's alternatives are specified
2588          in this tree.  Optimize if so.  */
2589
2590       else if (insn_code >= 0
2591           && (GET_CODE (left) == IOR
2592               || (GET_CODE (left) == EQ_ATTR
2593                   && XSTR (left, 0) == alternative_name)
2594               || GET_CODE (right) == IOR
2595               || (GET_CODE (right) == EQ_ATTR
2596                   && XSTR (right, 0) == alternative_name)))
2597         {
2598           i = compute_alternative_mask (exp, IOR);
2599           if (i & ~insn_alternatives[insn_code])
2600             fatal ("Illegal alternative specified for pattern number %d",
2601                    insn_index);
2602
2603           /* If all alternatives are included, this is true. */
2604           i ^= insn_alternatives[insn_code];
2605           if (i == 0)
2606             return true_rtx;
2607           else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2608             {
2609               /* If just one excluded, IOR a comparison with that one to the
2610                  front of the tree.  The others will be eliminated by
2611                  optimization.  We do not want to do this if the insn has one
2612                  alternative and we have tested none of them!  */
2613               left = make_alternative_compare (i);
2614               right = simplify_and_tree (exp, &left, insn_code, insn_index);
2615               newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2616
2617               return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2618             }
2619         }
2620
2621       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2622         {
2623           newexp = attr_rtx (IOR, left, right);
2624           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2625         }
2626       break;
2627
2628     case NOT:
2629       if (GET_CODE (XEXP (exp, 0)) == NOT)
2630         return SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2631                                   insn_code, insn_index);
2632       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2633       if (GET_CODE (left) == NOT)
2634         return XEXP (left, 0);
2635
2636       if (left == false_rtx)
2637         {
2638           obstack_free (rtl_obstack, spacer);
2639           return true_rtx;
2640         }
2641       else if (left == true_rtx)
2642         {
2643           obstack_free (rtl_obstack, spacer);
2644           return false_rtx;
2645         }
2646
2647       /* Try to apply De`Morgan's laws.  */
2648       else if (GET_CODE (left) == IOR)
2649         {
2650           newexp = attr_rtx (AND,
2651                              attr_rtx (NOT, XEXP (left, 0)),
2652                              attr_rtx (NOT, XEXP (left, 1)));
2653
2654           newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2655         }
2656       else if (GET_CODE (left) == AND)
2657         {
2658           newexp = attr_rtx (IOR,
2659                              attr_rtx (NOT, XEXP (left, 0)),
2660                              attr_rtx (NOT, XEXP (left, 1)));
2661
2662           newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2663         }
2664       else if (left != XEXP (exp, 0))
2665         {
2666           newexp = attr_rtx (NOT, left);
2667         }
2668       break;
2669
2670     case EQ_ATTR:
2671       /* Look at the value for this insn code in the specified attribute.
2672          We normally can replace this comparison with the condition that
2673          would give this insn the values being tested for.   */
2674       if (XSTR (exp, 0) != alternative_name
2675           && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
2676         for (av = attr->first_value; av; av = av->next)
2677           for (ie = av->first_insn; ie; ie = ie->next)
2678             if (ie->insn_code == insn_code)
2679               return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2680     }
2681
2682   /* We have already simplified this expression.  Simplifying it again
2683      won't buy anything unless we weren't given a valid insn code
2684      to process (i.e., we are canonicalizing something.).  */
2685   if (insn_code != -2 && ! RTX_UNCHANGING_P (newexp))
2686     {
2687       return copy_rtx_unchanging (newexp);
2688     }
2689
2690   return newexp;
2691 }
2692
2693 do_nothing ()
2694 {}
2695 \f
2696 /* Optimize the attribute lists by seeing if we can determine conditional
2697    values from the known values of other attributes.  This will save subroutine
2698    calls during the compilation.  */
2699
2700 static void
2701 optimize_attrs ()
2702 {
2703   struct attr_desc *attr;
2704   struct attr_value *av;
2705   struct insn_ent *ie, *nextie;
2706   rtx newexp;
2707   int something_changed = 1;
2708
2709   /* Loop until nothing changes for one iteration.  */
2710   while (something_changed)
2711     {
2712       something_changed = 0;
2713       for (attr = attrs; attr; attr = attr->next)
2714         for (av = attr->first_value; av; av = av->next)
2715             for (ie = av->first_insn; ie; ie = nextie)
2716               {
2717                 struct obstack *old = rtl_obstack;
2718                 char *spacer = (char *) obstack_finish (temp_obstack);
2719
2720                 nextie = ie->next;
2721                 if (GET_CODE (av->value) != COND)
2722                   continue;
2723
2724                 rtl_obstack = temp_obstack;
2725                 newexp = simplify_cond (av->value, ie->insn_code,
2726                                         ie->insn_index);
2727                 rtl_obstack = old;
2728                 if (newexp != av->value)
2729                   {
2730                     newexp = attr_copy_rtx (newexp);
2731                     remove_insn_ent (av, ie);
2732                     insert_insn_ent (get_attr_value (newexp, attr,
2733                                                      ie->insn_code), ie);
2734                     something_changed = 1;
2735                   }
2736                 obstack_free (temp_obstack, spacer);
2737               }
2738     }
2739 }
2740 \f
2741 /* Create table entries for DEFINE_ATTR.  */
2742
2743 static void
2744 gen_attr (exp)
2745      rtx exp;
2746 {
2747   struct attr_desc *attr;
2748   struct attr_value *av;
2749   char *name_ptr;
2750   char *p;
2751
2752   /* Make a new attribute structure.  Check for duplicate by looking at
2753      attr->default_val, since it is initialized by this routine.  */
2754   attr = find_attr (XSTR (exp, 0), 1);
2755   if (attr->default_val)
2756     fatal ("Duplicate definition for `%s' attribute", attr->name);
2757
2758   if (*XSTR (exp, 1) == '\0')
2759       attr->is_numeric = 1;
2760   else
2761     {
2762       name_ptr = XSTR (exp, 1);
2763       while ((p = next_comma_elt (&name_ptr)) != NULL)
2764         {
2765           av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
2766           av->value = attr_rtx (CONST_STRING, p);
2767           av->next = attr->first_value;
2768           attr->first_value = av;
2769           av->first_insn = NULL;
2770           av->num_insns = 0;
2771           av->has_asm_insn = 0;
2772         }
2773     }
2774
2775   if (GET_CODE (XEXP (exp, 2)) == CONST)
2776     {
2777       attr->is_const = 1;
2778       if (attr->is_numeric)
2779         fatal ("Constant attributes may not take numeric values");
2780       /* Get rid of the CONST node.  It is allowed only at top-level.  */
2781       XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
2782     }
2783
2784   if (! strcmp (attr->name, "length") && ! attr->is_numeric)
2785     fatal ("`length' attribute must take numeric values");
2786
2787   /* Set up the default value. */
2788   XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
2789   attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
2790 }
2791 \f
2792 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2793    alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
2794    number of alternatives as this should be checked elsewhere.  */
2795
2796 static int
2797 count_alternatives (exp)
2798      rtx exp;
2799 {
2800   int i, j, n;
2801   char *fmt;
2802   
2803   if (GET_CODE (exp) == MATCH_OPERAND)
2804     return n_comma_elts (XSTR (exp, 2));
2805
2806   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2807        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2808     switch (*fmt++)
2809       {
2810       case 'e':
2811       case 'u':
2812         n = count_alternatives (XEXP (exp, i));
2813         if (n)
2814           return n;
2815         break;
2816
2817       case 'E':
2818       case 'V':
2819         if (XVEC (exp, i) != NULL)
2820           for (j = 0; j < XVECLEN (exp, i); j++)
2821             {
2822               n = count_alternatives (XVECEXP (exp, i, j));
2823               if (n)
2824                 return n;
2825             }
2826       }
2827
2828   return 0;
2829 }
2830 \f
2831 /* Returns non-zero if the given expression contains an EQ_ATTR with the
2832    `alternative' attribute.  */
2833
2834 static int
2835 compares_alternatives_p (exp)
2836      rtx exp;
2837 {
2838   int i, j;
2839   char *fmt;
2840
2841   if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
2842     return 1;
2843
2844   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2845        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2846     switch (*fmt++)
2847       {
2848       case 'e':
2849       case 'u':
2850         if (compares_alternatives_p (XEXP (exp, i)))
2851           return 1;
2852         break;
2853
2854       case 'E':
2855         for (j = 0; j < XVECLEN (exp, i); j++)
2856           if (compares_alternatives_p (XVECEXP (exp, i, j)))
2857             return 1;
2858         break;
2859       }
2860
2861   return 0;
2862 }
2863 \f
2864 /* Returns non-zero is INNER is contained in EXP.  */
2865
2866 static int
2867 contained_in_p (inner, exp)
2868      rtx inner;
2869      rtx exp;
2870 {
2871   int i, j;
2872   char *fmt;
2873
2874   if (rtx_equal_p (inner, exp))
2875     return 1;
2876
2877   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2878        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2879     switch (*fmt++)
2880       {
2881       case 'e':
2882       case 'u':
2883         if (contained_in_p (inner, XEXP (exp, i)))
2884           return 1;
2885         break;
2886
2887       case 'E':
2888         for (j = 0; j < XVECLEN (exp, i); j++)
2889           if (contained_in_p (inner, XVECEXP (exp, i, j)))
2890             return 1;
2891         break;
2892       }
2893
2894   return 0;
2895 }
2896 \f       
2897 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
2898
2899 static void
2900 gen_insn (exp)
2901      rtx exp;
2902 {
2903   struct insn_def *id;
2904
2905   id = (struct insn_def *) xmalloc (sizeof (struct insn_def));
2906   id->next = defs;
2907   defs = id;
2908   id->def = exp;
2909
2910   switch (GET_CODE (exp))
2911     {
2912     case DEFINE_INSN:
2913       id->insn_code = insn_code_number++;
2914       id->insn_index = insn_index_number++;
2915       id->num_alternatives = count_alternatives (exp);
2916       if (id->num_alternatives == 0)
2917         id->num_alternatives = 1;
2918       id->vec_idx = 4;
2919       break;
2920
2921     case DEFINE_PEEPHOLE:
2922       id->insn_code = insn_code_number++;
2923       id->insn_index = insn_index_number++;
2924       id->num_alternatives = count_alternatives (exp);
2925       if (id->num_alternatives == 0)
2926         id->num_alternatives = 1;
2927       id->vec_idx = 3;
2928       break;
2929
2930     case DEFINE_ASM_ATTRIBUTES:
2931       id->insn_code = -1;
2932       id->insn_index = -1;
2933       id->num_alternatives = 1;
2934       id->vec_idx = 0;
2935       got_define_asm_attributes = 1;
2936       break;
2937     }
2938 }
2939 \f
2940 /* Process a DEFINE_DELAY.  Validate the vector length, check if annul
2941    true or annul false is specified, and make a `struct delay_desc'.  */
2942
2943 static void
2944 gen_delay (def)
2945      rtx def;
2946 {
2947   struct delay_desc *delay;
2948   int i;
2949
2950   if (XVECLEN (def, 1) % 3 != 0)
2951     fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
2952
2953   for (i = 0; i < XVECLEN (def, 1); i += 3)
2954     {
2955       if (XVECEXP (def, 1, i + 1))
2956         have_annul_true = 1;
2957       if (XVECEXP (def, 1, i + 2))
2958         have_annul_false = 1;
2959     }
2960   
2961   delay = (struct delay_desc *) xmalloc (sizeof (struct delay_desc));
2962   delay->def = def;
2963   delay->num = ++num_delays;
2964   delay->next = delays;
2965   delays = delay;
2966 }
2967 \f
2968 /* Process a DEFINE_FUNCTION_UNIT.  
2969
2970    This gives information about a function unit contained in the CPU.
2971    We fill in a `struct function_unit_op' and a `struct function_unit'
2972    with information used later by `expand_unit'.  */
2973
2974 static void
2975 gen_unit (def)
2976      rtx def;
2977 {
2978   struct function_unit *unit;
2979   struct function_unit_op *op;
2980
2981   /* See if we have already seen this function unit.  If so, check that
2982      the multipicity and simultaneity values are the same.  If not, make
2983      a structure for this function unit.  */
2984   for (unit = units; unit; unit = unit->next)
2985     if (! strcmp (unit->name, XSTR (def, 0)))
2986       {
2987         if (unit->multiplicity != XINT (def, 1)
2988             || unit->simultaneity != XINT (def, 2))
2989           fatal ("Differing specifications given for `%s' function unit.",
2990                  unit->name);
2991         break;
2992       }
2993
2994   if (unit == 0)
2995     {
2996       unit = (struct function_unit *) xmalloc (sizeof (struct function_unit));
2997       unit->name = XSTR (def, 0);
2998       unit->multiplicity = XINT (def, 1);
2999       unit->simultaneity = XINT (def, 2);
3000       unit->num = num_units++;
3001       unit->num_opclasses = 0;
3002       unit->condexp = false_rtx;
3003       unit->ops = 0;
3004       unit->next = units;
3005       units = unit;
3006     }
3007
3008   /* Make a new operation class structure entry and initialize it.  */
3009   op = (struct function_unit_op *) xmalloc (sizeof (struct function_unit_op));
3010   op->condexp = XEXP (def, 3);
3011   op->num = unit->num_opclasses++;
3012   op->ready = XINT (def, 4);
3013   op->next = unit->ops;
3014   unit->ops = op;
3015
3016   /* Set our busy expression based on whether or not an optional conflict
3017      vector was specified.  */
3018   if (XVEC (def, 6))
3019     {
3020       /* Compute the IOR of all the specified expressions.  */
3021       rtx orexp = false_rtx;
3022       int i;
3023
3024       for (i = 0; i < XVECLEN (def, 6); i++)
3025         orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2);
3026
3027       op->busyexp = attr_rtx (IF_THEN_ELSE, orexp,
3028                               make_numeric_value (XINT (def, 5)),
3029                               make_numeric_value (0));
3030     }
3031   else
3032     op->busyexp = make_numeric_value (XINT (def, 5));
3033
3034   /* Merge our conditional into that of the function unit so we can determine
3035      which insns are used by the function unit.  */
3036   unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2);
3037 }
3038 \f
3039 /* Given a piece of RTX, print a C expression to test it's truth value.
3040    We use AND and IOR both for logical and bit-wise operations, so 
3041    interpret them as logical unless they are inside a comparison expression.
3042    The second operand of this function will be non-zero in that case.  */
3043
3044 static void
3045 write_test_expr (exp, in_comparison)
3046      rtx exp;
3047      int in_comparison;
3048 {
3049   int comparison_operator = 0;
3050   RTX_CODE code;
3051   struct attr_desc *attr;
3052
3053   /* In order not to worry about operator precedence, surround our part of
3054      the expression with parentheses.  */
3055
3056   printf ("(");
3057   code = GET_CODE (exp);
3058   switch (code)
3059     {
3060     /* Binary operators.  */
3061     case EQ: case NE:
3062     case GE: case GT: case GEU: case GTU:
3063     case LE: case LT: case LEU: case LTU:
3064       comparison_operator = 1;
3065
3066     case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
3067     case AND:    case IOR:    case XOR:
3068     case LSHIFT: case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3069       write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator);
3070       switch (code)
3071         {
3072         case EQ:
3073           printf (" == ");
3074           break;
3075         case NE:
3076           printf (" != ");
3077           break;
3078         case GE:
3079           printf (" >= ");
3080           break;
3081         case GT:
3082           printf (" > ");
3083           break;
3084         case GEU:
3085           printf (" >= (unsigned) ");
3086           break;
3087         case GTU:
3088           printf (" > (unsigned) ");
3089           break;
3090         case LE:
3091           printf (" <= ");
3092           break;
3093         case LT:
3094           printf (" < ");
3095           break;
3096         case LEU:
3097           printf (" <= (unsigned) ");
3098           break;
3099         case LTU:
3100           printf (" < (unsigned) ");
3101           break;
3102         case PLUS:
3103           printf (" + ");
3104           break;
3105         case MINUS:
3106           printf (" - ");
3107           break;
3108         case MULT:
3109           printf (" * ");
3110           break;
3111         case DIV:
3112           printf (" / ");
3113           break;
3114         case MOD:
3115           printf (" %% ");
3116           break;
3117         case AND:
3118           if (in_comparison)
3119             printf (" & ");
3120           else
3121             printf (" && ");
3122           break;
3123         case IOR:
3124           if (in_comparison)
3125             printf (" | ");
3126           else
3127             printf (" || ");
3128           break;
3129         case XOR:
3130           printf (" ^ ");
3131           break;
3132         case LSHIFT:
3133         case ASHIFT:
3134           printf (" << ");
3135           break;
3136         case LSHIFTRT:
3137         case ASHIFTRT:
3138           printf (" >> ");
3139           break;
3140         }
3141
3142       write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator);
3143       break;
3144
3145     case NOT:
3146       /* Special-case (not (eq_attrq "alternative" "x")) */
3147       if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3148           && XSTR (XEXP (exp, 0), 0) == alternative_name)
3149         {
3150           printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3151           break;
3152         }
3153
3154       /* Otherwise, fall through to normal unary operator.  */
3155
3156     /* Unary operators.  */   
3157     case ABS:  case NEG:
3158       switch (code)
3159         {
3160         case NOT:
3161           if (in_comparison)
3162             printf ("~ ");
3163           else
3164             printf ("! ");
3165           break;
3166         case ABS:
3167           printf ("abs ");
3168           break;
3169         case NEG:
3170           printf ("-");
3171           break;
3172         }
3173
3174       write_test_expr (XEXP (exp, 0), in_comparison);
3175       break;
3176
3177     /* Comparison test of an attribute with a value.  Most of these will
3178        have been removed by optimization.   Handle "alternative"
3179        specially and give error if EQ_ATTR present inside a comparison.  */
3180     case EQ_ATTR:
3181       if (in_comparison)
3182         fatal ("EQ_ATTR not valid inside comparison");
3183
3184       if (XSTR (exp, 0) == alternative_name)
3185         {
3186           printf ("which_alternative == %s", XSTR (exp, 1));
3187           break;
3188         }
3189
3190       attr = find_attr (XSTR (exp, 0), 0);
3191       if (! attr) abort ();
3192       printf ("get_attr_%s (insn) == ", attr->name);
3193       write_attr_valueq (attr, XSTR (exp, 1)); 
3194       break;
3195
3196     /* See if an operand matches a predicate.  */
3197     case MATCH_OPERAND:
3198       /* If only a mode is given, just ensure the mode matches the operand.
3199          If neither a mode nor predicate is given, error.  */
3200      if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3201         {
3202           if (GET_MODE (exp) == VOIDmode)
3203             fatal ("Null MATCH_OPERAND specified as test");
3204           else
3205             printf ("GET_MODE (operands[%d]) == %smode",
3206                     XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3207         }
3208       else
3209         printf ("%s (operands[%d], %smode)",
3210                 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3211       break;
3212
3213     /* Constant integer. */
3214     case CONST_INT:
3215       printf ("%d", XINT (exp, 0));
3216       break;
3217
3218     /* A random C expression. */
3219     case SYMBOL_REF:
3220       printf ("%s", XSTR (exp, 0));
3221       break;
3222
3223     /* The address of the branch target.  */
3224     case MATCH_DUP:
3225       printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
3226       break;
3227
3228     /* The address of the current insn.  It would be more consistent with
3229        other usage to make this the address of the NEXT insn, but this gets
3230        too confusing because of the ambiguity regarding the length of the
3231        current insn.  */
3232     case PC:
3233       printf ("insn_current_address");
3234       break;
3235
3236     default:
3237       fatal ("bad RTX code `%s' in attribute calculation\n",
3238              GET_RTX_NAME (code));
3239     }
3240
3241   printf (")");
3242 }
3243 \f
3244 /* Given an attribute value, return the maximum CONST_STRING argument
3245    encountered.  It is assumed that they are all numeric.  */
3246
3247 static int
3248 max_attr_value (exp)
3249      rtx exp;
3250 {
3251   int current_max = 0;
3252   int n;
3253   int i;
3254
3255   if (GET_CODE (exp) == CONST_STRING)
3256     return atoi (XSTR (exp, 0));
3257
3258   else if (GET_CODE (exp) == COND)
3259     {
3260       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3261         {
3262           n = max_attr_value (XVECEXP (exp, 0, i + 1));
3263           if (n > current_max)
3264             current_max = n;
3265         }
3266
3267       n = max_attr_value (XEXP (exp, 1));
3268       if (n > current_max)
3269         current_max = n;
3270     }
3271
3272   else
3273     abort ();
3274
3275   return current_max;
3276 }
3277 \f
3278 /* Scan an attribute value, possibly a conditional, and record what actions
3279    will be required to do any conditional tests in it.
3280
3281    Specifically, set
3282         `must_extract'    if we need to extract the insn operands
3283         `must_constrain'  if we must compute `which_alternative'
3284         `address_used'    if an address expression was used
3285  */
3286
3287 static void
3288 walk_attr_value (exp)
3289      rtx exp;
3290 {
3291   register int i, j;
3292   register char *fmt;
3293   RTX_CODE code;
3294
3295   if (exp == NULL)
3296     return;
3297
3298   code = GET_CODE (exp);
3299   switch (code)
3300     {
3301     case SYMBOL_REF:
3302       if (! RTX_UNCHANGING_P (exp))
3303         /* Since this is an arbitrary expression, it can look at anything.
3304            However, constant expressions do not depend on any particular
3305            insn.  */
3306         must_extract = must_constrain = 1;
3307       return;
3308
3309     case MATCH_OPERAND:
3310       must_extract = 1;
3311       return;
3312
3313     case EQ_ATTR:
3314       if (XSTR (exp, 0) == alternative_name)
3315         must_extract = must_constrain = 1;
3316       return;
3317
3318     case MATCH_DUP:
3319     case PC:
3320       address_used = 1;
3321       return;
3322     }
3323
3324   for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3325     switch (*fmt++)
3326       {
3327       case 'e':
3328       case 'u':
3329         walk_attr_value (XEXP (exp, i));
3330         break;
3331
3332       case 'E':
3333         if (XVEC (exp, i) != NULL)
3334           for (j = 0; j < XVECLEN (exp, i); j++)
3335             walk_attr_value (XVECEXP (exp, i, j));
3336         break;
3337       }
3338 }
3339 \f
3340 /* Write out a function to obtain the attribute for a given INSN.  */
3341
3342 static void
3343 write_attr_get (attr)
3344      struct attr_desc *attr;
3345 {
3346   struct attr_value *av, *common_av;
3347
3348   /* Find the most used attribute value.  Handle that as the `default' of the
3349      switch we will generate. */
3350   common_av = find_most_used (attr);
3351
3352   /* Write out start of function, then all values with explicit `case' lines,
3353      then a `default', then the value with the most uses.  */
3354   if (attr->is_numeric)
3355     printf ("int\n");
3356   else
3357     printf ("enum attr_%s\n", attr->name);
3358
3359   /* If the attribute name starts with a star, the remainder is the name of
3360      the subroutine to use, instead of `get_attr_...'.  */
3361   if (attr->name[0] == '*')
3362     printf ("%s (insn)\n", &attr->name[1]);
3363   else if (attr->is_const == 0)
3364     printf ("get_attr_%s (insn)\n", attr->name);
3365   else
3366     {
3367       printf ("get_attr_%s ()\n", attr->name);
3368       printf ("{\n");
3369
3370       for (av = attr->first_value; av; av = av->next)
3371         if (av->num_insns != 0)
3372           write_attr_set (attr, 2, av->value, "return", ";",
3373                           true_rtx, av->first_insn->insn_code,
3374                           av->first_insn->insn_index);
3375
3376       printf ("}\n\n");
3377       return;
3378     }
3379   printf ("     rtx insn;\n");
3380   printf ("{\n");
3381   printf ("  switch (recog_memoized (insn))\n");
3382   printf ("    {\n");
3383
3384   for (av = attr->first_value; av; av = av->next)
3385     if (av != common_av)
3386       write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3387
3388   write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3389   printf ("    }\n}\n\n");
3390 }
3391 \f
3392 /* Given an AND tree of known true terms (because we are inside an `if' with
3393    that as the condition or are in an `else' clause) and an expression,
3394    replace any known true terms with TRUE.  Use `simplify_and_tree' to do
3395    the bulk of the work.  */
3396
3397 static rtx
3398 eliminate_known_true (known_true, exp, insn_code, insn_index)
3399      rtx known_true;
3400      rtx exp;
3401      int insn_code, insn_index;
3402 {
3403   rtx term;
3404
3405   known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3406
3407   if (GET_CODE (known_true) == AND)
3408     {
3409       exp = eliminate_known_true (XEXP (known_true, 0), exp,
3410                                   insn_code, insn_index);
3411       exp = eliminate_known_true (XEXP (known_true, 1), exp,
3412                                   insn_code, insn_index);
3413     }
3414   else
3415     {
3416       term = known_true;
3417       exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3418     }
3419
3420   return exp;
3421 }
3422 \f
3423 /* Write out a series of tests and assignment statements to perform tests and
3424    sets of an attribute value.  We are passed an indentation amount and prefix
3425    and suffix strings to write around each attribute value (e.g., "return"
3426    and ";").  */
3427
3428 static void
3429 write_attr_set (attr, indent, value, prefix, suffix, known_true,
3430                 insn_code, insn_index)
3431      struct attr_desc *attr;
3432      int indent;
3433      rtx value;
3434      char *prefix;
3435      char *suffix;
3436      rtx known_true;
3437      int insn_code, insn_index;
3438 {
3439   if (GET_CODE (value) == CONST_STRING)
3440     {
3441       write_indent (indent);
3442       printf ("%s ", prefix);
3443       write_attr_value (attr, value);
3444       printf ("%s\n", suffix);
3445     }
3446   else if (GET_CODE (value) == COND)
3447     {
3448       /* Assume the default value will be the default of the COND unless we
3449          find an always true expression.  */
3450       rtx default_val = XEXP (value, 1);
3451       rtx our_known_true = known_true;
3452       rtx newexp;
3453       int first_if = 1;
3454       int i;
3455
3456       for (i = 0; i < XVECLEN (value, 0); i += 2)
3457         {
3458           rtx testexp;
3459           rtx inner_true;
3460
3461           testexp = eliminate_known_true (our_known_true,
3462                                           XVECEXP (value, 0, i),
3463                                           insn_code, insn_index);
3464           newexp = attr_rtx (NOT, testexp);
3465           newexp  = insert_right_side (AND, our_known_true, newexp,
3466                                        insn_code, insn_index);
3467
3468           /* If the test expression is always true or if the next `known_true'
3469              expression is always false, this is the last case, so break
3470              out and let this value be the `else' case.  */
3471           if (testexp == true_rtx || newexp == false_rtx)
3472             {
3473               default_val = XVECEXP (value, 0, i + 1);
3474               break;
3475             }
3476
3477           /* Compute the expression to pass to our recursive call as being
3478              known true.  */
3479           inner_true = insert_right_side (AND, our_known_true,
3480                                           testexp, insn_code, insn_index);
3481
3482           /* If this is always false, skip it.  */
3483           if (inner_true == false_rtx)
3484             continue;
3485
3486           write_indent (indent);
3487           printf ("%sif ", first_if ? "" : "else ");
3488           first_if = 0;
3489           write_test_expr (testexp, 0);
3490           printf ("\n");
3491           write_indent (indent + 2);
3492           printf ("{\n");
3493
3494           write_attr_set (attr, indent + 4,  
3495                           XVECEXP (value, 0, i + 1), prefix, suffix,
3496                           inner_true, insn_code, insn_index);
3497           write_indent (indent + 2);
3498           printf ("}\n");
3499           our_known_true = newexp;
3500         }
3501
3502       if (! first_if)
3503         {
3504           write_indent (indent);
3505           printf ("else\n");
3506           write_indent (indent + 2);
3507           printf ("{\n");
3508         }
3509
3510       write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3511                       prefix, suffix, our_known_true, insn_code, insn_index);
3512
3513       if (! first_if)
3514         {
3515           write_indent (indent + 2);
3516           printf ("}\n");
3517         }
3518     }
3519   else
3520     abort ();
3521 }
3522 \f
3523 /* Write out the computation for one attribute value.  */
3524
3525 static void
3526 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, known_true)
3527      struct attr_desc *attr;
3528      struct attr_value *av;
3529      int write_case_lines;
3530      char *prefix, *suffix;
3531      int indent;
3532      rtx known_true;
3533 {
3534   struct insn_ent *ie;
3535
3536   if (av->num_insns == 0)
3537     return;
3538
3539   if (av->has_asm_insn)
3540     {
3541       write_indent (indent);
3542       printf ("case -1:\n");
3543       write_indent (indent + 2);
3544       printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3545       write_indent (indent + 2);
3546       printf ("    && asm_noperands (PATTERN (insn)) < 0)\n");
3547       write_indent (indent + 2);
3548       printf ("  fatal_insn_not_found (insn);\n");
3549     }
3550
3551   if (write_case_lines)
3552     {
3553       for (ie = av->first_insn; ie; ie = ie->next)
3554         if (ie->insn_code != -1)
3555           {
3556             write_indent (indent);
3557             printf ("case %d:\n", ie->insn_code);
3558           }
3559     }
3560   else
3561     {
3562       write_indent (indent);
3563       printf ("default:\n");
3564     }
3565
3566   /* See what we have to do to handle output this value.  */
3567   must_extract = must_constrain = address_used = 0;
3568   walk_attr_value (av->value);
3569
3570   if (must_extract)
3571     {
3572       write_indent (indent + 2);
3573       printf ("insn_extract (insn);\n");
3574     }
3575
3576   if (must_constrain)
3577     {
3578 #ifdef REGISTER_CONSTRAINTS
3579       write_indent (indent + 2);
3580       printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
3581       write_indent (indent + 2);
3582       printf ("  fatal_insn_not_found (insn);\n");
3583 #endif
3584     }
3585
3586   write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3587                   known_true, av->first_insn->insn_code,
3588                   av->first_insn->insn_index);
3589
3590   if (strncmp (prefix, "return", 6))
3591     {
3592       write_indent (indent + 2);
3593       printf ("break;\n");
3594     }
3595   printf ("\n");
3596 }
3597 \f
3598 /* Utilities to write names in various forms.  */
3599
3600 static void
3601 write_attr_valueq (attr, s)
3602      struct attr_desc *attr;
3603      char *s;
3604 {
3605   if (attr->is_numeric)
3606     printf ("%s", s);
3607   else
3608     {
3609       write_upcase (attr->name);
3610       printf ("_");
3611       write_upcase (s);
3612     }
3613 }
3614
3615 static void
3616 write_attr_value (attr, value)
3617      struct attr_desc *attr;
3618      rtx value;
3619 {
3620   if (GET_CODE (value) != CONST_STRING)
3621     abort ();
3622
3623   write_attr_valueq (attr, XSTR (value, 0));
3624 }
3625
3626 static void
3627 write_upcase (str)
3628      char *str;
3629 {
3630   while (*str)
3631     if (*str < 'a' || *str > 'z')
3632       printf ("%c", *str++);
3633     else
3634       printf ("%c", *str++ - 'a' + 'A');
3635 }
3636
3637 static void
3638 write_indent (indent)
3639      int indent;
3640 {
3641   for (; indent > 8; indent -= 8)
3642     printf ("\t");
3643
3644   for (; indent; indent--)
3645     printf (" ");
3646 }
3647 \f
3648 /* Write a subroutine that is given an insn that requires a delay slot, a
3649    delay slot ordinal, and a candidate insn.  It returns non-zero if the
3650    candidate can be placed in the specified delay slot of the insn.
3651
3652    We can write as many as three subroutines.  `eligible_for_delay'
3653    handles normal delay slots, `eligible_for_annul_true' indicates that
3654    the specified insn can be annulled if the branch is true, and likewise
3655    for `eligible_for_annul_false'.
3656
3657    KIND is a string distingushing these three cases ("delay", "annul_true",
3658    or "annul_false").  */
3659
3660 static void
3661 write_eligible_delay (kind)
3662      char *kind;
3663 {
3664   struct delay_desc *delay;
3665   int max_slots;
3666   char str[50];
3667   struct attr_desc *attr;
3668   struct attr_value *av, *common_av;
3669   int i;
3670
3671   /* Compute the maximum number of delay slots required.  We use the delay
3672      ordinal times this number plus one, plus the slot number as an index into
3673      the appropriate predicate to test.  */
3674
3675   for (delay = delays, max_slots = 0; delay; delay = delay->next)
3676     if (XVECLEN (delay->def, 1) / 3 > max_slots)
3677       max_slots = XVECLEN (delay->def, 1) / 3;
3678
3679   /* Write function prelude.  */
3680
3681   printf ("int\n");
3682   printf ("eligible_for_%s (delay_insn, slot, candidate_insn)\n", kind);
3683   printf ("     rtx delay_insn;\n");
3684   printf ("     int slot;\n");
3685   printf ("     rtx candidate_insn;\n");
3686   printf ("{\n");
3687   printf ("  rtx insn;\n");
3688   printf ("\n");
3689   printf ("  if (slot >= %d)\n", max_slots);
3690   printf ("    abort ();\n");
3691   printf ("\n");
3692
3693   /* If more than one delay type, find out which type the delay insn is.  */
3694
3695   if (num_delays > 1)
3696     {
3697       attr = find_attr ("*delay_type", 0);
3698       if (! attr) abort ();
3699       common_av = find_most_used (attr);
3700
3701       printf ("  insn = delay_insn;\n");
3702       printf ("  switch (recog_memoized (insn))\n");
3703       printf ("    {\n");
3704
3705       sprintf (str, " * %d;\n      break;", max_slots);
3706       for (av = attr->first_value; av; av = av->next)
3707         if (av != common_av)
3708           write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
3709
3710       write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
3711       printf ("    }\n\n");
3712
3713       /* Ensure matched.  Otherwise, shouldn't have been called.  */
3714       printf ("  if (slot < %d)\n", max_slots);
3715       printf ("    abort ();\n\n");
3716     }
3717
3718   /* If just one type of delay slot, write simple switch.  */
3719   if (num_delays == 1 && max_slots == 1)
3720     {
3721       printf ("  insn = candidate_insn;\n");
3722       printf ("  switch (recog_memoized (insn))\n");
3723       printf ("    {\n");
3724
3725       attr = find_attr ("*delay_1_0", 0);
3726       if (! attr) abort ();
3727       common_av = find_most_used (attr);
3728
3729       for (av = attr->first_value; av; av = av->next)
3730         if (av != common_av)
3731           write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3732
3733       write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3734       printf ("    }\n");
3735     }
3736
3737   else
3738     {
3739       /* Write a nested CASE.  The first indicates which condition we need to
3740          test, and the inner CASE tests the condition.  */
3741       printf ("  insn = candidate_insn;\n");
3742       printf ("  switch (slot)\n");
3743       printf ("    {\n");
3744
3745       for (delay = delays; delay; delay = delay->next)
3746         for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
3747           {
3748             printf ("    case %d:\n",
3749                     (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
3750             printf ("      switch (recog_memoized (insn))\n");
3751             printf ("\t{\n");
3752
3753             sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
3754             attr = find_attr (str, 0);
3755             if (! attr) abort ();
3756             common_av = find_most_used (attr);
3757
3758             for (av = attr->first_value; av; av = av->next)
3759               if (av != common_av)
3760                 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
3761
3762             write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
3763             printf ("      }\n");
3764           }
3765
3766       printf ("    default:\n");
3767       printf ("      abort ();\n");     
3768       printf ("    }\n");
3769     }
3770
3771   printf ("}\n\n");
3772 }
3773 \f
3774 /* Write routines to compute conflict cost for function units.  Then write a
3775    table describing the available function units.  */
3776
3777 static void
3778 write_function_unit_info ()
3779 {
3780   struct function_unit *unit;
3781   struct attr_desc *case_attr, *attr;
3782   struct attr_value *av, *common_av;
3783   rtx value;
3784   char *str;
3785   int using_case;
3786   int i;
3787
3788   /* Write out conflict routines for function units.  Don't bother writing
3789      one if there is only one busy value.  */
3790
3791   for (unit = units; unit; unit = unit->next)
3792     {
3793       /* See if only one case exists and if there is a constant value for
3794          that case.  If so, we don't need a function.  */
3795       str = (char *) alloca (strlen (unit->name) + 10);
3796       sprintf (str, "*%s_cases", unit->name);
3797       attr = find_attr (str, 0);
3798       if (! attr) abort ();
3799       value = find_single_value (attr);
3800       if (value && GET_CODE (value) == CONST_STRING)
3801         {
3802           sprintf (str, "*%s_case_%s", unit->name, XSTR (value, 0));
3803           attr = find_attr (str, 0);
3804           if (! attr) abort ();
3805           value = find_single_value (attr);
3806           if (value && GET_CODE (value) == CONST_STRING)
3807             {
3808               unit->needs_conflict_function = 0;
3809               unit->default_cost = value;
3810               continue;
3811             }
3812         }
3813
3814       /* The function first computes the case from the candidate insn.  */
3815       unit->needs_conflict_function = 1;
3816       unit->default_cost = make_numeric_value (0);
3817
3818       printf ("static int\n");
3819       printf ("%s_unit_conflict_cost (executing_insn, candidate_insn)\n",
3820               unit->name);
3821       printf ("     rtx executing_insn;\n");
3822       printf ("     rtx candidate_insn;\n");
3823       printf ("{\n");
3824       printf ("  rtx insn;\n");
3825       printf ("  int casenum;\n\n");
3826       printf ("  insn = candidate_insn;\n");
3827       printf ("  switch (recog_memoized (insn))\n");
3828       printf ("    {\n");
3829
3830       /* Write the `switch' statement to get the case value.  */
3831       sprintf (str, "*%s_cases", unit->name);
3832       case_attr = find_attr (str, 0);
3833       if (! case_attr) abort ();
3834       common_av = find_most_used (case_attr);
3835
3836       for (av = case_attr->first_value; av; av = av->next)
3837         if (av != common_av)
3838           write_attr_case (case_attr, av, 1,
3839                            "casenum =", ";", 4, unit->condexp);
3840
3841       write_attr_case (case_attr, common_av, 0,
3842                        "casenum =", ";", 4, unit->condexp);
3843       printf ("    }\n\n");
3844
3845       /* Now write an outer switch statement on each case.  Then write
3846          the tests on the executing function within each.  */
3847       printf ("  insn = executing_insn;\n");
3848       printf ("  switch (casenum)\n");
3849       printf ("    {\n");
3850
3851       for (i = 0; i < unit->num_opclasses; i++)
3852         {
3853           /* Ensure using this case.  */
3854           using_case = 0;
3855           for (av = case_attr->first_value; av; av = av->next)
3856             if (av->num_insns
3857                 && contained_in_p (make_numeric_value (i), av->value))
3858               using_case = 1;
3859
3860           if (! using_case)
3861             continue;
3862
3863           printf ("    case %d:\n", i);
3864           sprintf (str, "*%s_case_%d", unit->name, i);
3865           attr = find_attr (str, 0);
3866           if (! attr) abort ();
3867
3868           /* If single value, just write it.  */
3869           value = find_single_value (attr);
3870           if (value)
3871             write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2);
3872           else
3873             {
3874               common_av = find_most_used (attr);
3875               printf ("      switch (recog_memoized (insn))\n");
3876               printf ("\t{\n");
3877
3878               for (av = attr->first_value; av; av = av->next)
3879                 if (av != common_av)
3880                   write_attr_case (attr, av, 1,
3881                                    "return", ";", 8, unit->condexp);
3882
3883               write_attr_case (attr, common_av, 0,
3884                                "return", ";", 8, unit->condexp);
3885               printf ("      }\n\n");
3886             }
3887         }
3888
3889       printf ("    }\n}\n\n");
3890     }
3891
3892   /* Now that all functions have been written, write the table describing
3893      the function units.   The name is included for documenation purposes
3894      only.  */
3895
3896   printf ("struct function_unit_desc function_units[] = {\n");
3897
3898   for (unit = units; unit; unit = unit->next)
3899     {
3900       printf ("  {\"%s\", %d, %d, %d, %s, %s_unit_ready_cost, ",
3901               unit->name, 1 << unit->num, unit->multiplicity,
3902               unit->simultaneity, XSTR (unit->default_cost, 0), unit->name);
3903
3904       if (unit->needs_conflict_function)
3905         printf ("%s_unit_conflict_cost", unit->name);
3906       else
3907         printf ("0");
3908
3909       printf ("}, \n");
3910     }
3911
3912   printf ("};\n\n");
3913 }
3914 \f
3915 /* This page contains miscellaneous utility routines.  */
3916
3917 /* Given a string, return the number of comma-separated elements in it.
3918    Return 0 for the null string.  */
3919
3920 static int
3921 n_comma_elts (s)
3922      char *s;
3923 {
3924   int n;
3925
3926   if (*s == '\0')
3927     return 0;
3928
3929   for (n = 1; *s; s++)
3930     if (*s == ',')
3931       n++;
3932
3933   return n;
3934 }
3935
3936 /* Given a pointer to a (char *), return a malloc'ed string containing the
3937    next comma-separated element.  Advance the pointer to after the string
3938    scanned, or the end-of-string.  Return NULL if at end of string.  */
3939
3940 static char *
3941 next_comma_elt (pstr)
3942      char **pstr;
3943 {
3944   char *out_str;
3945   char *p;
3946
3947   if (**pstr == '\0')
3948     return NULL;
3949
3950   /* Find end of string to compute length.  */
3951   for (p = *pstr; *p != ',' && *p != '\0'; p++)
3952     ;
3953
3954   out_str = attr_string (*pstr, p - *pstr);
3955   *pstr = p;
3956
3957   if (**pstr == ',')
3958     (*pstr)++;
3959
3960   return out_str;
3961 }
3962
3963 /* Return a `struct attr_desc' pointer for a given named attribute.  If CREATE
3964    is non-zero, build a new attribute, if one does not exist.  */
3965
3966 static struct attr_desc *
3967 find_attr (name, create)
3968      char *name;
3969      int create;
3970 {
3971   struct attr_desc *attr;
3972   char *new_name;
3973
3974   /* Before we resort to using `strcmp', see if the string address matches
3975      anywhere.  In most cases, it should have been canonicalized to do so.  */
3976   if (name == alternative_name)
3977     return NULL;
3978
3979   for (attr = attrs; attr; attr = attr->next)
3980     if (name == attr->name)
3981       return attr;
3982
3983   /* Otherwise, do it the slow way.  */
3984   for (attr = attrs; attr; attr = attr->next)
3985     if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
3986       return attr;
3987
3988   if (! create)
3989     return NULL;
3990
3991   new_name = (char *) xmalloc (strlen (name) + 1);
3992   strcpy (new_name, name);
3993
3994   attr = (struct attr_desc *) xmalloc (sizeof (struct attr_desc));
3995   attr->name = new_name;
3996   attr->first_value = attr->default_val = NULL;
3997   attr->is_numeric = attr->is_const = attr->is_special = 0;
3998   attr->next = attrs;
3999   attrs = attr;
4000
4001   return attr;
4002 }
4003
4004 /* Create internal attribute with the given default value.  */
4005
4006 static void
4007 make_internal_attr (name, value, special)
4008      char *name;
4009      rtx value;
4010      int special;
4011 {
4012   struct attr_desc *attr;
4013
4014   attr = find_attr (name, 1);
4015   if (attr->default_val)
4016     abort ();
4017
4018   attr->is_numeric = 1;
4019   attr->is_const = 0;
4020   attr->is_special = special;
4021   attr->default_val = get_attr_value (value, attr, -2);
4022 }
4023
4024 /* Find the most used value of an attribute.  */
4025
4026 static struct attr_value *
4027 find_most_used (attr)
4028      struct attr_desc *attr;
4029 {
4030   struct attr_value *av;
4031   struct attr_value *most_used;
4032   int nuses;
4033
4034   most_used = NULL;
4035   nuses = -1;
4036
4037   for (av = attr->first_value; av; av = av->next)
4038     if (av->num_insns > nuses)
4039       nuses = av->num_insns, most_used = av;
4040
4041   return most_used;
4042 }
4043
4044 /* If an attribute only has a single value used, return it.  Otherwise
4045    return NULL.  */
4046
4047 static rtx
4048 find_single_value (attr)
4049      struct attr_desc *attr;
4050 {
4051   struct attr_value *av;
4052   rtx unique_value;
4053
4054   unique_value = NULL;
4055   for (av = attr->first_value; av; av = av->next)
4056     if (av->num_insns)
4057       {
4058         if (unique_value)
4059           return NULL;
4060         else
4061           unique_value = av->value;
4062       }
4063
4064   return unique_value;
4065 }
4066
4067 /* Return (attr_value "n") */
4068
4069 static rtx
4070 make_numeric_value (n)
4071      int n;
4072 {
4073   static rtx int_values[20];
4074   rtx exp;
4075   char *p;
4076
4077   if (n < 0)
4078     abort ();
4079
4080   if (n < 20 && int_values[n])
4081     return int_values[n];
4082
4083   p = attr_printf ((n < 1000 ? 4 : HOST_BITS_PER_INT * 3 / 10 + 3), "%d", n);
4084   exp = attr_rtx (CONST_STRING, p);
4085
4086   if (n < 20)
4087     int_values[n] = exp;
4088
4089   return exp;
4090 }
4091 \f
4092 char *
4093 xrealloc (ptr, size)
4094      char *ptr;
4095      unsigned size;
4096 {
4097   char *result = (char *) realloc (ptr, size);
4098   if (!result)
4099     fatal ("virtual memory exhausted");
4100   return result;
4101 }
4102
4103 char *
4104 xmalloc (size)
4105      unsigned size;
4106 {
4107   register char *val = (char *) malloc (size);
4108
4109   if (val == 0)
4110     fatal ("virtual memory exhausted");
4111   return val;
4112 }
4113
4114 static rtx
4115 copy_rtx_unchanging (orig)
4116      register rtx orig;
4117 {
4118   register rtx copy;
4119   register RTX_CODE code;
4120
4121   if (RTX_UNCHANGING_P (orig))
4122     return orig;
4123
4124   code = GET_CODE (orig);
4125
4126   switch (code)
4127     {
4128     case CONST_INT:
4129     case CONST_DOUBLE:
4130     case SYMBOL_REF:
4131     case CODE_LABEL:
4132       return orig;
4133     }
4134
4135   copy = rtx_alloc (code);
4136   PUT_MODE (copy, GET_MODE (orig));
4137   RTX_UNCHANGING_P (copy) = 1;
4138   
4139   bcopy (&XEXP (orig, 0), &XEXP (copy, 0),
4140          GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
4141   return copy;
4142 }
4143
4144 static void
4145 fatal (s, a1, a2)
4146      char *s;
4147 {
4148   fprintf (stderr, "genattrtab: ");
4149   fprintf (stderr, s, a1, a2);
4150   fprintf (stderr, "\n");
4151   exit (FATAL_EXIT_CODE);
4152 }
4153
4154 /* More 'friendly' abort that prints the line and file.
4155    config.h can #define abort fancy_abort if you like that sort of thing.  */
4156
4157 void
4158 fancy_abort ()
4159 {
4160   fatal ("Internal gcc abort.");
4161 }
4162 \f
4163 int
4164 main (argc, argv)
4165      int argc;
4166      char **argv;
4167 {
4168   rtx desc;
4169   FILE *infile;
4170   register int c;
4171   struct attr_desc *attr;
4172   struct attr_value *av;
4173   struct insn_def *id;
4174   rtx tem;
4175
4176   obstack_init (rtl_obstack);
4177   obstack_init (hash_obstack);
4178   obstack_init (temp_obstack);
4179
4180   if (argc <= 1)
4181     fatal ("No input file name.");
4182
4183   infile = fopen (argv[1], "r");
4184   if (infile == 0)
4185     {
4186       perror (argv[1]);
4187       exit (FATAL_EXIT_CODE);
4188     }
4189
4190   init_rtl ();
4191
4192   /* Set up true and false rtx's */
4193   true_rtx = rtx_alloc (CONST_INT);
4194   XINT (true_rtx, 0) = 1;
4195   false_rtx = rtx_alloc (CONST_INT);
4196   XINT (false_rtx, 0) = 0;
4197   RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
4198   RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
4199
4200   alternative_name = attr_string ("alternative", strlen ("alternative"));
4201
4202   printf ("/* Generated automatically by the program `genattrtab'\n\
4203 from the machine description file `md'.  */\n\n");
4204
4205   /* Read the machine description.  */
4206
4207   while (1)
4208     {
4209       c = read_skip_spaces (infile);
4210       if (c == EOF)
4211         break;
4212       ungetc (c, infile);
4213
4214       desc = read_rtx (infile);
4215       if (GET_CODE (desc) == DEFINE_INSN
4216           || GET_CODE (desc) == DEFINE_PEEPHOLE
4217           || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
4218         gen_insn (desc);
4219
4220       else if (GET_CODE (desc) == DEFINE_EXPAND)
4221         insn_code_number++, insn_index_number++;
4222
4223       else if (GET_CODE (desc) == DEFINE_SPLIT)
4224         insn_code_number++, insn_index_number++;
4225
4226       else if (GET_CODE (desc) == DEFINE_ATTR)
4227         {
4228           gen_attr (desc);
4229           insn_index_number++;
4230         }
4231
4232       else if (GET_CODE (desc) == DEFINE_DELAY)
4233         {
4234           gen_delay (desc);
4235           insn_index_number++;
4236         }
4237
4238       else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
4239         {
4240           gen_unit (desc);
4241           insn_index_number++;
4242         }
4243     }
4244
4245   /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
4246   if (! got_define_asm_attributes)
4247     {
4248       tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4249       XVEC (tem, 0) = rtvec_alloc (0);
4250       gen_insn (tem);
4251     }
4252
4253   /* Expand DEFINE_DELAY information into new attribute.  */
4254   if (num_delays)
4255     expand_delays ();
4256
4257   /* Expand DEFINE_FUNCTION_UNIT information into new attributes.  */
4258   if (num_units)
4259     expand_units ();
4260
4261   printf ("#include \"config.h\"\n");
4262   printf ("#include \"rtl.h\"\n");
4263   printf ("#include \"insn-config.h\"\n");
4264   printf ("#include \"recog.h\"\n");
4265   printf ("#include \"regs.h\"\n");
4266   printf ("#include \"real.h\"\n");
4267   printf ("#include \"output.h\"\n");
4268   printf ("#include \"insn-attr.h\"\n");
4269   printf ("\n");  
4270   printf ("#define operands recog_operand\n\n");
4271
4272   /* Make `insn_alternatives'.  */
4273   insn_alternatives = (int *) xmalloc (insn_code_number * sizeof (int));
4274   for (id = defs; id; id = id->next)
4275     if (id->insn_code >= 0)
4276       insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4277
4278   /* Prepare to write out attribute subroutines by checking everything stored
4279      away and building the attribute cases.  */
4280
4281   check_defs ();
4282   for (attr = attrs; attr; attr = attr->next)
4283     {
4284       attr->default_val->value
4285         = check_attr_value (attr->default_val->value, attr);
4286       fill_attr (attr);
4287     }
4288
4289   /* Construct extra attributes for `length'.  */
4290   make_length_attrs ();
4291
4292   /* Perform any possible optimizations to speed up compilation. */
4293   optimize_attrs ();
4294
4295   /* Now write out all the `gen_attr_...' routines.  Do these before the
4296      special routines (specifically before write_function_unit_info), so
4297      that they get defined before they are used.  */
4298
4299   for (attr = attrs; attr; attr = attr->next)
4300     {
4301       if (! attr->is_special)
4302         write_attr_get (attr);
4303     }
4304
4305   /* Write out delay eligibility information, if DEFINE_DELAY present.
4306      (The function to compute the number of delay slots will be written
4307      below.)  */
4308   if (num_delays)
4309     {
4310       write_eligible_delay ("delay");
4311       if (have_annul_true)
4312         write_eligible_delay ("annul_true");
4313       if (have_annul_false)
4314         write_eligible_delay ("annul_false");
4315     }
4316
4317   /* Write out information about function units.  */
4318   if (num_units)
4319     write_function_unit_info ();
4320
4321   fflush (stdout);
4322   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
4323   /* NOTREACHED */
4324   return 0;
4325 }