OSDN Git Service

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