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