OSDN Git Service

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