OSDN Git Service

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