OSDN Git Service

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