OSDN Git Service

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