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