OSDN Git Service

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