OSDN Git Service

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