OSDN Git Service

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