OSDN Git Service

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