OSDN Git Service

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