OSDN Git Service

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