OSDN Git Service

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