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