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