OSDN Git Service

bacdafb8e12dbd76a5ce73f92b864d051fd59c43
[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 /* varargs must always be included after *config.h.  */
99 #ifdef __STDC__
100 #include <stdarg.h>
101 #else
102 #include <varargs.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             PVPROTO((enum rtx_code, ...));
363 #ifdef HAVE_VPRINTF
364 static char *attr_printf        PVPROTO((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, 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       unit->condexp = check_attr_test (unit->condexp, 0);
1806
1807       for (op = unit->ops; op; op = op->next)
1808         {
1809           rtx issue_delay = make_numeric_value (op->issue_delay);
1810           rtx issue_exp = issue_delay;
1811
1812           /* Build, validate, and simplify the issue delay expression.  */
1813           if (op->conflict_exp != true_rtx)
1814             issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1815                                   issue_exp, make_numeric_value (0));
1816           issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1817                                                         issue_exp),
1818                                         NULL_ATTR);
1819           issue_exp = simplify_knowing (issue_exp, unit->condexp);
1820           op->issue_exp = issue_exp;
1821
1822           /* Make an attribute for use in the conflict function if needed.  */
1823           unit->needs_conflict_function = (unit->issue_delay.min
1824                                            != unit->issue_delay.max);
1825           if (unit->needs_conflict_function)
1826             {
1827               str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1828                                  "*%s_cost_%d", unit->name, op->num);
1829               make_internal_attr (str, issue_exp, 1);
1830             }
1831
1832           /* Validate the condition.  */
1833           op->condexp = check_attr_test (op->condexp, 0);
1834         }
1835     }
1836
1837   /* Compute the mask of function units used.  Initially, the unitsmask is
1838      zero.   Set up a conditional to compute each unit's contribution.  */
1839   unitsmask = make_numeric_value (0);
1840   newexp = rtx_alloc (IF_THEN_ELSE);
1841   XEXP (newexp, 2) = make_numeric_value (0);
1842
1843   /* Merge each function unit into the unit mask attributes.  */
1844   for (unit = units; unit; unit = unit->next)
1845     {
1846       XEXP (newexp, 0) = unit->condexp;
1847       XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1848       unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1849     }
1850
1851   /* Simplify the unit mask expression, encode it, and make an attribute
1852      for the function_units_used function.  */
1853   unitsmask = simplify_by_exploding (unitsmask);
1854   unitsmask = encode_units_mask (unitsmask);
1855   make_internal_attr ("*function_units_used", unitsmask, 2);
1856
1857   /* Create an array of ops for each unit.  Add an extra unit for the
1858      result_ready_cost function that has the ops of all other units.  */
1859   unit_ops = (struct function_unit_op ***)
1860     alloca ((num_units + 1) * sizeof (struct function_unit_op **));
1861   unit_num = (struct function_unit **)
1862     alloca ((num_units + 1) * sizeof (struct function_unit *));
1863
1864   unit_num[num_units] = unit = (struct function_unit *)
1865     alloca (sizeof (struct function_unit));
1866   unit->num = num_units;
1867   unit->num_opclasses = 0;
1868
1869   for (unit = units; unit; unit = unit->next)
1870     {
1871       unit_num[num_units]->num_opclasses += unit->num_opclasses;
1872       unit_num[unit->num] = unit;
1873       unit_ops[unit->num] = op_array = (struct function_unit_op **)
1874         alloca (unit->num_opclasses * sizeof (struct function_unit_op *));
1875
1876       for (op = unit->ops; op; op = op->next)
1877         op_array[op->num] = op;
1878     }
1879
1880   /* Compose the array of ops for the extra unit.  */
1881   unit_ops[num_units] = op_array = (struct function_unit_op **)
1882     alloca (unit_num[num_units]->num_opclasses
1883             * sizeof (struct function_unit_op *));
1884
1885   for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
1886     bcopy (unit_ops[unit->num], &op_array[i],
1887            unit->num_opclasses * sizeof (struct function_unit_op *));
1888
1889   /* Compute the ready cost function for each unit by computing the
1890      condition for each non-default value.  */
1891   for (u = 0; u <= num_units; u++)
1892     {
1893       rtx orexp;
1894       int value;
1895
1896       unit = unit_num[u];
1897       op_array = unit_ops[unit->num];
1898       num = unit->num_opclasses;
1899
1900       /* Sort the array of ops into increasing ready cost order.  */
1901       for (i = 0; i < num; i++)
1902         for (j = num - 1; j > i; j--)
1903           if (op_array[j-1]->ready < op_array[j]->ready)
1904             {
1905               op = op_array[j];
1906               op_array[j] = op_array[j-1];
1907               op_array[j-1] = op;
1908             }
1909
1910       /* Determine how many distinct non-default ready cost values there
1911          are.  We use a default ready cost value of 1.  */
1912       nvalues = 0; value = 1;
1913       for (i = num - 1; i >= 0; i--)
1914         if (op_array[i]->ready > value)
1915           {
1916             value = op_array[i]->ready;
1917             nvalues++;
1918           }
1919
1920       if (nvalues == 0)
1921         readycost = make_numeric_value (1);
1922       else
1923         {
1924           /* Construct the ready cost expression as a COND of each value from
1925              the largest to the smallest.  */
1926           readycost = rtx_alloc (COND);
1927           XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
1928           XEXP (readycost, 1) = make_numeric_value (1);
1929
1930           nvalues = 0; orexp = false_rtx; value = op_array[0]->ready;
1931           for (i = 0; i < num; i++)
1932             {
1933               op = op_array[i];
1934               if (op->ready <= 1)
1935                 break;
1936               else if (op->ready == value)
1937                 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
1938               else
1939                 {
1940                   XVECEXP (readycost, 0, nvalues * 2) = orexp;
1941                   XVECEXP (readycost, 0, nvalues * 2 + 1)
1942                     = make_numeric_value (value);
1943                   nvalues++;
1944                   value = op->ready;
1945                   orexp = op->condexp;
1946                 }
1947             }
1948           XVECEXP (readycost, 0, nvalues * 2) = orexp;
1949           XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
1950         }
1951
1952       if (u < num_units)
1953         {
1954           rtx max_blockage = 0, min_blockage = 0;
1955
1956           /* Simplify the readycost expression by only considering insns
1957              that use the unit.  */
1958           readycost = simplify_knowing (readycost, unit->condexp);
1959
1960           /* Determine the blockage cost the executing insn (E) given
1961              the candidate insn (C).  This is the maximum of the issue
1962              delay, the pipeline delay, and the simultaneity constraint.
1963              Each function_unit_op represents the characteristics of the
1964              candidate insn, so in the expressions below, C is a known
1965              term and E is an unknown term.
1966
1967              We compute the blockage cost for each E for every possible C.
1968              Thus OP represents E, and READYCOST is a list of values for
1969              every possible C.
1970
1971              The issue delay function for C is op->issue_exp and is used to
1972              write the `<name>_unit_conflict_cost' function.  Symbolicly
1973              this is "ISSUE-DELAY (E,C)".
1974
1975              The pipeline delay results form the FIFO constraint on the
1976              function unit and is "READY-COST (E) + 1 - READY-COST (C)".
1977
1978              The simultaneity constraint is based on how long it takes to
1979              fill the unit given the minimum issue delay.  FILL-TIME is the
1980              constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
1981              the simultaneity constraint is "READY-COST (E) - FILL-TIME"
1982              if SIMULTANEITY is non-zero and zero otherwise.
1983
1984              Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
1985
1986                  MAX (ISSUE-DELAY (E,C),
1987                       READY-COST (E) - (READY-COST (C) - 1))
1988
1989              and otherwise
1990
1991                  MAX (ISSUE-DELAY (E,C),
1992                       READY-COST (E) - (READY-COST (C) - 1),
1993                       READY-COST (E) - FILL-TIME)
1994
1995              The `<name>_unit_blockage' function is computed by determining
1996              this value for each candidate insn.  As these values are
1997              computed, we also compute the upper and lower bounds for
1998              BLOCKAGE (E,*).  These are combined to form the function
1999              `<name>_unit_blockage_range'.  Finally, the maximum blockage
2000              cost, MAX (BLOCKAGE (*,*)), is computed.  */
2001
2002           for (op = unit->ops; op; op = op->next)
2003             {
2004               rtx blockage = operate_exp (POS_MINUS_OP, readycost,
2005                                           make_numeric_value (1));
2006
2007               if (unit->simultaneity != 0)
2008                 {
2009                   rtx filltime = make_numeric_value ((unit->simultaneity - 1)
2010                                                      * unit->issue_delay.min);
2011                   blockage = operate_exp (MIN_OP, blockage, filltime);
2012                 }
2013
2014               blockage = operate_exp (POS_MINUS_OP,
2015                                       make_numeric_value (op->ready),
2016                                       blockage);
2017
2018               blockage = operate_exp (MAX_OP, blockage, op->issue_exp);
2019               blockage = simplify_knowing (blockage, unit->condexp);
2020
2021               /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2022                  MIN (BLOCKAGE (E,*)).  */
2023               if (max_blockage == 0)
2024                 max_blockage = min_blockage = blockage;
2025               else
2026                 {
2027                   max_blockage
2028                     = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2029                                                      blockage),
2030                                         unit->condexp);
2031                   min_blockage
2032                     = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2033                                                      blockage),
2034                                         unit->condexp);
2035                 }
2036
2037               /* Make an attribute for use in the blockage function.  */
2038               str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2039                                  "*%s_block_%d", unit->name, op->num);
2040               make_internal_attr (str, blockage, 1);
2041             }
2042
2043           /* Record MAX (BLOCKAGE (*,*)).  */
2044           unit->max_blockage = max_attr_value (max_blockage);
2045
2046           /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2047              same.  If so, the blockage function carries no additional
2048              information and is not written.  */
2049           newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2050           newexp = simplify_knowing (newexp, unit->condexp);
2051           unit->needs_blockage_function
2052             = (GET_CODE (newexp) != CONST_STRING
2053                || atoi (XSTR (newexp, 0)) != 1);
2054
2055           /* If the all values of BLOCKAGE (E,C) have the same value,
2056              neither blockage function is written.  */    
2057           unit->needs_range_function
2058             = (unit->needs_blockage_function
2059                || GET_CODE (max_blockage) != CONST_STRING);
2060
2061           if (unit->needs_range_function)
2062             {
2063               /* Compute the blockage range function and make an attribute
2064                  for writing it's value.  */
2065               newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2066               newexp = simplify_knowing (newexp, unit->condexp);
2067
2068               str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
2069                                  "*%s_unit_blockage_range", unit->name);
2070               make_internal_attr (str, newexp, 4);
2071             }
2072
2073           str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2074                              "*%s_unit_ready_cost", unit->name);
2075         }
2076       else
2077         str = "*result_ready_cost";
2078
2079       /* Make an attribute for the ready_cost function.  Simplifying
2080          further with simplify_by_exploding doesn't win.  */
2081       make_internal_attr (str, readycost, 0);
2082     }
2083
2084   /* For each unit that requires a conflict cost function, make an attribute
2085      that maps insns to the operation number.  */
2086   for (unit = units; unit; unit = unit->next)
2087     {
2088       rtx caseexp;
2089
2090       if (! unit->needs_conflict_function
2091           && ! unit->needs_blockage_function)
2092         continue;
2093
2094       caseexp = rtx_alloc (COND);
2095       XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2096
2097       for (op = unit->ops; op; op = op->next)
2098         {
2099           /* Make our adjustment to the COND being computed.  If we are the
2100              last operation class, place our values into the default of the
2101              COND.  */
2102           if (op->num == unit->num_opclasses - 1)
2103             {
2104               XEXP (caseexp, 1) = make_numeric_value (op->num);
2105             }
2106           else
2107             {
2108               XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2109               XVECEXP (caseexp, 0, op->num * 2 + 1)
2110                 = make_numeric_value (op->num);
2111             }
2112         }
2113
2114       /* Simplifying caseexp with simplify_by_exploding doesn't win.  */
2115       str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2116                          "*%s_cases", unit->name);
2117       make_internal_attr (str, caseexp, 1);
2118     }
2119 }
2120
2121 /* Simplify EXP given KNOWN_TRUE.  */
2122
2123 static rtx
2124 simplify_knowing (exp, known_true)
2125      rtx exp, known_true;
2126 {
2127   if (GET_CODE (exp) != CONST_STRING)
2128     {
2129       exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2130                       make_numeric_value (max_attr_value (exp)));
2131       exp = simplify_by_exploding (exp);
2132     }
2133   return exp;
2134 }
2135
2136 /* Translate the CONST_STRING expressions in X to change the encoding of
2137    value.  On input, the value is a bitmask with a one bit for each unit
2138    used; on output, the value is the unit number (zero based) if one
2139    and only one unit is used or the one's compliment of the bitmask.  */
2140
2141 static rtx
2142 encode_units_mask (x)
2143      rtx x;
2144 {
2145   register int i;
2146   register int j;
2147   register enum rtx_code code;
2148   register char *fmt;
2149
2150   code = GET_CODE (x);
2151
2152   switch (code)
2153     {
2154     case CONST_STRING:
2155       i = atoi (XSTR (x, 0));
2156       if (i < 0)
2157         abort (); /* The sign bit encodes a one's compliment mask.  */
2158       else if (i != 0 && i == (i & -i))
2159         /* Only one bit is set, so yield that unit number.  */
2160         for (j = 0; (i >>= 1) != 0; j++)
2161           ;
2162       else
2163         j = ~i;
2164       return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2165
2166     case REG:
2167     case QUEUED:
2168     case CONST_INT:
2169     case CONST_DOUBLE:
2170     case SYMBOL_REF:
2171     case CODE_LABEL:
2172     case PC:
2173     case CC0:
2174     case EQ_ATTR:
2175       return x;
2176     }
2177
2178   /* Compare the elements.  If any pair of corresponding elements
2179      fail to match, return 0 for the whole things.  */
2180
2181   fmt = GET_RTX_FORMAT (code);
2182   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2183     {
2184       switch (fmt[i])
2185         {
2186         case 'V':
2187         case 'E':
2188           for (j = 0; j < XVECLEN (x, i); j++)
2189             XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2190           break;
2191
2192         case 'e':
2193           XEXP (x, i) = encode_units_mask (XEXP (x, i));
2194           break;
2195         }
2196     }
2197   return x;
2198 }
2199 \f
2200 /* Once all attributes and insns have been read and checked, we construct for
2201    each attribute value a list of all the insns that have that value for
2202    the attribute.  */
2203
2204 static void
2205 fill_attr (attr)
2206      struct attr_desc *attr;
2207 {
2208   struct attr_value *av;
2209   struct insn_ent *ie;
2210   struct insn_def *id;
2211   int i;
2212   rtx value;
2213
2214   /* Don't fill constant attributes.  The value is independent of
2215      any particular insn.  */
2216   if (attr->is_const)
2217     return;
2218
2219   for (id = defs; id; id = id->next)
2220     {
2221       /* If no value is specified for this insn for this attribute, use the
2222          default.  */
2223       value = NULL;
2224       if (XVEC (id->def, id->vec_idx))
2225         for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2226           if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0), 
2227                         attr->name))
2228             value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2229
2230       if (value == NULL)
2231         av = attr->default_val;
2232       else
2233         av = get_attr_value (value, attr, id->insn_code);
2234
2235       ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2236       ie->insn_code = id->insn_code;
2237       ie->insn_index = id->insn_code;
2238       insert_insn_ent (av, ie);
2239     }
2240 }
2241 \f
2242 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2243    test that checks relative positions of insns (uses MATCH_DUP or PC).
2244    If so, replace it with what is obtained by passing the expression to
2245    ADDRESS_FN.  If not but it is a COND or IF_THEN_ELSE, call this routine
2246    recursively on each value (including the default value).  Otherwise,
2247    return the value returned by NO_ADDRESS_FN applied to EXP.  */
2248
2249 static rtx
2250 substitute_address (exp, no_address_fn, address_fn)
2251      rtx exp;
2252      rtx (*no_address_fn) ();
2253      rtx (*address_fn) ();
2254 {
2255   int i;
2256   rtx newexp;
2257
2258   if (GET_CODE (exp) == COND)
2259     {
2260       /* See if any tests use addresses.  */
2261       address_used = 0;
2262       for (i = 0; i < XVECLEN (exp, 0); i += 2)
2263         walk_attr_value (XVECEXP (exp, 0, i));
2264
2265       if (address_used)
2266         return (*address_fn) (exp);
2267
2268       /* Make a new copy of this COND, replacing each element.  */
2269       newexp = rtx_alloc (COND);
2270       XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2271       for (i = 0; i < XVECLEN (exp, 0); i += 2)
2272         {
2273           XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2274           XVECEXP (newexp, 0, i + 1)
2275             = substitute_address (XVECEXP (exp, 0, i + 1),
2276                                   no_address_fn, address_fn);
2277         }
2278
2279       XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2280                                              no_address_fn, address_fn);
2281
2282       return newexp;
2283     }
2284
2285   else if (GET_CODE (exp) == IF_THEN_ELSE)
2286     {
2287       address_used = 0;
2288       walk_attr_value (XEXP (exp, 0));
2289       if (address_used)
2290         return (*address_fn) (exp);
2291
2292       return attr_rtx (IF_THEN_ELSE,
2293                        substitute_address (XEXP (exp, 0),
2294                                            no_address_fn, address_fn),
2295                        substitute_address (XEXP (exp, 1),
2296                                            no_address_fn, address_fn),
2297                        substitute_address (XEXP (exp, 2),
2298                                            no_address_fn, address_fn));
2299     }
2300
2301   return (*no_address_fn) (exp);
2302 }
2303 \f
2304 /* Make new attributes from the `length' attribute.  The following are made,
2305    each corresponding to a function called from `shorten_branches' or
2306    `get_attr_length':
2307
2308    *insn_default_length         This is the length of the insn to be returned
2309                                 by `get_attr_length' before `shorten_branches'
2310                                 has been called.  In each case where the length
2311                                 depends on relative addresses, the largest
2312                                 possible is used.  This routine is also used
2313                                 to compute the initial size of the insn.
2314
2315    *insn_variable_length_p      This returns 1 if the insn's length depends
2316                                 on relative addresses, zero otherwise.
2317
2318    *insn_current_length         This is only called when it is known that the
2319                                 insn has a variable length and returns the
2320                                 current length, based on relative addresses.
2321   */
2322
2323 static void
2324 make_length_attrs ()
2325 {
2326   static char *new_names[] = {"*insn_default_length",
2327                               "*insn_variable_length_p",
2328                               "*insn_current_length"};
2329   static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
2330   static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
2331   int i;
2332   struct attr_desc *length_attr, *new_attr;
2333   struct attr_value *av, *new_av;
2334   struct insn_ent *ie, *new_ie;
2335
2336   /* See if length attribute is defined.  If so, it must be numeric.  Make
2337      it special so we don't output anything for it.  */
2338   length_attr = find_attr ("length", 0);
2339   if (length_attr == 0)
2340     return;
2341
2342   if (! length_attr->is_numeric)
2343     fatal ("length attribute must be numeric.");
2344
2345   length_attr->is_const = 0;
2346   length_attr->is_special = 1;
2347
2348   /* Make each new attribute, in turn.  */
2349   for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
2350     {
2351       make_internal_attr (new_names[i],
2352                           substitute_address (length_attr->default_val->value,
2353                                               no_address_fn[i], address_fn[i]),
2354                           0);
2355       new_attr = find_attr (new_names[i], 0);
2356       for (av = length_attr->first_value; av; av = av->next)
2357         for (ie = av->first_insn; ie; ie = ie->next)
2358           {
2359             new_av = get_attr_value (substitute_address (av->value,
2360                                                          no_address_fn[i],
2361                                                          address_fn[i]),
2362                                      new_attr, ie->insn_code);
2363             new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2364             new_ie->insn_code = ie->insn_code;
2365             new_ie->insn_index = ie->insn_index;
2366             insert_insn_ent (new_av, new_ie);
2367           }
2368     }
2369 }
2370
2371 /* Utility functions called from above routine.  */
2372
2373 static rtx
2374 identity_fn (exp)
2375      rtx exp;
2376 {
2377   return exp;
2378 }
2379
2380 static rtx
2381 zero_fn (exp)
2382      rtx exp;
2383 {
2384   return make_numeric_value (0);
2385 }
2386
2387 static rtx
2388 one_fn (exp)
2389      rtx exp;
2390 {
2391   return make_numeric_value (1);
2392 }
2393
2394 static rtx
2395 max_fn (exp)
2396      rtx exp;
2397 {
2398   return make_numeric_value (max_attr_value (exp));
2399 }
2400 \f
2401 /* Take a COND expression and see if any of the conditions in it can be
2402    simplified.  If any are known true or known false for the particular insn
2403    code, the COND can be further simplified.
2404
2405    Also call ourselves on any COND operations that are values of this COND.
2406
2407    We do not modify EXP; rather, we make and return a new rtx.  */
2408
2409 static rtx
2410 simplify_cond (exp, insn_code, insn_index)
2411      rtx exp;
2412      int insn_code, insn_index;
2413 {
2414   int i, j;
2415   /* We store the desired contents here,
2416      then build a new expression if they don't match EXP.  */
2417   rtx defval = XEXP (exp, 1);
2418   rtx new_defval = XEXP (exp, 1);
2419
2420   int len = XVECLEN (exp, 0);
2421   rtx *tests = (rtx *) alloca (len * sizeof (rtx));
2422   int allsame = 1;
2423   char *first_spacer;
2424
2425   /* This lets us free all storage allocated below, if appropriate.  */
2426   first_spacer = (char *) obstack_finish (rtl_obstack);
2427
2428   bcopy (&XVECEXP (exp, 0, 0), tests, len * sizeof (rtx));
2429
2430   /* See if default value needs simplification.  */
2431   if (GET_CODE (defval) == COND)
2432     new_defval = simplify_cond (defval, insn_code, insn_index);
2433
2434   /* Simplify the subexpressions, and see what tests we can get rid of.  */
2435
2436   for (i = 0; i < len; i += 2)
2437     {
2438       rtx newtest, newval;
2439
2440       /* Simplify this test.  */
2441       newtest = SIMPLIFY_TEST_EXP (tests[i], insn_code, insn_index);
2442       tests[i] = newtest;
2443
2444       newval = tests[i + 1];
2445       /* See if this value may need simplification.  */
2446       if (GET_CODE (newval) == COND)
2447         newval = simplify_cond (newval, insn_code, insn_index);
2448
2449       /* Look for ways to delete or combine this test.  */
2450       if (newtest == true_rtx)
2451         {
2452           /* If test is true, make this value the default
2453              and discard this + any following tests.  */
2454           len = i;
2455           defval = tests[i + 1];
2456           new_defval = newval;
2457         }
2458
2459       else if (newtest == false_rtx)
2460         {
2461           /* If test is false, discard it and its value.  */
2462           for (j = i; j < len - 2; j++)
2463             tests[j] = tests[j + 2];
2464           len -= 2;
2465         }
2466
2467       else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
2468         {
2469           /* If this value and the value for the prev test are the same,
2470              merge the tests.  */
2471
2472           tests[i - 2]
2473             = insert_right_side (IOR, tests[i - 2], newtest,
2474                                  insn_code, insn_index);
2475
2476           /* Delete this test/value.  */
2477           for (j = i; j < len - 2; j++)
2478             tests[j] = tests[j + 2];
2479           len -= 2;
2480         }
2481
2482       else
2483         tests[i + 1] = newval;
2484     }
2485
2486   /* If the last test in a COND has the same value
2487      as the default value, that test isn't needed.  */
2488
2489   while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
2490     len -= 2;
2491
2492   /* See if we changed anything.  */
2493   if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2494     allsame = 0;
2495   else
2496     for (i = 0; i < len; i++)
2497       if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
2498         {
2499           allsame = 0;
2500           break;
2501         }
2502
2503   if (len == 0)
2504     {
2505       obstack_free (rtl_obstack, first_spacer);
2506       if (GET_CODE (defval) == COND)
2507         return simplify_cond (defval, insn_code, insn_index);
2508       return defval;
2509     }
2510   else if (allsame)
2511     {
2512       obstack_free (rtl_obstack, first_spacer);
2513       return exp;
2514     }
2515   else
2516     {
2517       rtx newexp = rtx_alloc (COND);
2518
2519       XVEC (newexp, 0) = rtvec_alloc (len);
2520       bcopy (tests, &XVECEXP (newexp, 0, 0), len * sizeof (rtx));
2521       XEXP (newexp, 1) = new_defval;
2522       return newexp;
2523     }
2524 }
2525 \f
2526 /* Remove an insn entry from an attribute value.  */
2527
2528 static void
2529 remove_insn_ent (av, ie)
2530      struct attr_value *av;
2531      struct insn_ent *ie;
2532 {
2533   struct insn_ent *previe;
2534
2535   if (av->first_insn == ie)
2536     av->first_insn = ie->next;
2537   else
2538     {
2539       for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2540         ;
2541       previe->next = ie->next;
2542     }
2543
2544   av->num_insns--;
2545   if (ie->insn_code == -1)
2546     av->has_asm_insn = 0;
2547 }
2548
2549 /* Insert an insn entry in an attribute value list.  */
2550
2551 static void
2552 insert_insn_ent (av, ie)
2553      struct attr_value *av;
2554      struct insn_ent *ie;
2555 {
2556   ie->next = av->first_insn;
2557   av->first_insn = ie;
2558   av->num_insns++;
2559   if (ie->insn_code == -1)
2560     av->has_asm_insn = 1;
2561 }
2562 \f
2563 /* This is a utility routine to take an expression that is a tree of either
2564    AND or IOR expressions and insert a new term.  The new term will be
2565    inserted at the right side of the first node whose code does not match
2566    the root.  A new node will be created with the root's code.  Its left
2567    side will be the old right side and its right side will be the new
2568    term.
2569
2570    If the `term' is itself a tree, all its leaves will be inserted.  */
2571
2572 static rtx
2573 insert_right_side (code, exp, term, insn_code, insn_index)
2574      enum rtx_code code;
2575      rtx exp;
2576      rtx term;
2577      int insn_code, insn_index;
2578 {
2579   rtx newexp;
2580
2581   /* Avoid consing in some special cases.  */
2582   if (code == AND && term == true_rtx)
2583     return exp;
2584   if (code == AND && term == false_rtx)
2585     return false_rtx;
2586   if (code == AND && exp == true_rtx)
2587     return term;
2588   if (code == AND && exp == false_rtx)
2589     return false_rtx;
2590   if (code == IOR && term == true_rtx)
2591     return true_rtx;
2592   if (code == IOR && term == false_rtx)
2593     return exp;
2594   if (code == IOR && exp == true_rtx)
2595     return true_rtx;
2596   if (code == IOR && exp == false_rtx)
2597     return term;
2598   if (attr_equal_p (exp, term))
2599     return exp;
2600
2601   if (GET_CODE (term) == code)
2602     {
2603       exp = insert_right_side (code, exp, XEXP (term, 0),
2604                                insn_code, insn_index);
2605       exp = insert_right_side (code, exp, XEXP (term, 1),
2606                                insn_code, insn_index);
2607
2608       return exp;
2609     }
2610
2611   if (GET_CODE (exp) == code)
2612     {
2613       rtx new = insert_right_side (code, XEXP (exp, 1),
2614                                    term, insn_code, insn_index);
2615       if (new != XEXP (exp, 1))
2616         /* Make a copy of this expression and call recursively.  */
2617         newexp = attr_rtx (code, XEXP (exp, 0), new);
2618       else
2619         newexp = exp;
2620     }
2621   else
2622     {
2623       /* Insert the new term.  */
2624       newexp = attr_rtx (code, exp, term);
2625     }
2626
2627   return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2628 }
2629 \f
2630 /* If we have an expression which AND's a bunch of
2631         (not (eq_attrq "alternative" "n"))
2632    terms, we may have covered all or all but one of the possible alternatives.
2633    If so, we can optimize.  Similarly for IOR's of EQ_ATTR.
2634
2635    This routine is passed an expression and either AND or IOR.  It returns a
2636    bitmask indicating which alternatives are mentioned within EXP.  */
2637
2638 static int
2639 compute_alternative_mask (exp, code)
2640      rtx exp;
2641      enum rtx_code code;
2642 {
2643   char *string;
2644   if (GET_CODE (exp) == code)
2645     return compute_alternative_mask (XEXP (exp, 0), code)
2646            | compute_alternative_mask (XEXP (exp, 1), code);
2647
2648   else if (code == AND && GET_CODE (exp) == NOT
2649            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2650            && XSTR (XEXP (exp, 0), 0) == alternative_name)
2651     string = XSTR (XEXP (exp, 0), 1);
2652
2653   else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2654            && XSTR (exp, 0) == alternative_name)
2655     string = XSTR (exp, 1);
2656
2657   else
2658     return 0;
2659
2660   if (string[1] == 0)
2661     return 1 << (string[0] - '0');
2662   return 1 << atoi (string);
2663 }
2664
2665 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2666    attribute with the value represented by that bit.  */
2667
2668 static rtx
2669 make_alternative_compare (mask)
2670      int mask;
2671 {
2672   rtx newexp;
2673   int i;
2674
2675   /* Find the bit.  */
2676   for (i = 0; (mask & (1 << i)) == 0; i++)
2677     ;
2678
2679   newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2680   RTX_UNCHANGING_P (newexp) = 1;
2681
2682   return newexp;
2683 }
2684 \f
2685 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2686    of "attr" for this insn code.  From that value, we can compute a test
2687    showing when the EQ_ATTR will be true.  This routine performs that
2688    computation.  If a test condition involves an address, we leave the EQ_ATTR
2689    intact because addresses are only valid for the `length' attribute. 
2690
2691    EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2692    for the insn corresponding to INSN_CODE and INSN_INDEX.  */
2693
2694 static rtx
2695 evaluate_eq_attr (exp, value, insn_code, insn_index)
2696      rtx exp;
2697      rtx value;
2698      int insn_code, insn_index;
2699 {
2700   rtx orexp, andexp;
2701   rtx right;
2702   rtx newexp;
2703   int i;
2704
2705   if (GET_CODE (value) == CONST_STRING)
2706     {
2707       if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2708         newexp = true_rtx;
2709       else
2710         newexp = false_rtx;
2711     }
2712   else if (GET_CODE (value) == COND)
2713     {
2714       /* We construct an IOR of all the cases for which the requested attribute
2715          value is present.  Since we start with FALSE, if it is not present,
2716          FALSE will be returned.
2717
2718          Each case is the AND of the NOT's of the previous conditions with the
2719          current condition; in the default case the current condition is TRUE. 
2720
2721          For each possible COND value, call ourselves recursively.
2722
2723          The extra TRUE and FALSE expressions will be eliminated by another
2724          call to the simplification routine. */
2725
2726       orexp = false_rtx;
2727       andexp = true_rtx;
2728
2729       if (current_alternative_string)
2730         clear_struct_flag (value);
2731
2732       for (i = 0; i < XVECLEN (value, 0); i += 2)
2733         {
2734           rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
2735                                         insn_code, insn_index);
2736
2737           SIMPLIFY_ALTERNATIVE (this);
2738
2739           right = insert_right_side (AND, andexp, this,
2740                                      insn_code, insn_index);
2741           right = insert_right_side (AND, right,
2742                                      evaluate_eq_attr (exp,
2743                                                        XVECEXP (value, 0,
2744                                                                 i + 1),
2745                                                        insn_code, insn_index),
2746                                      insn_code, insn_index);
2747           orexp = insert_right_side (IOR, orexp, right,
2748                                      insn_code, insn_index);
2749
2750           /* Add this condition into the AND expression.  */
2751           newexp = attr_rtx (NOT, this);
2752           andexp = insert_right_side (AND, andexp, newexp,
2753                                       insn_code, insn_index);
2754         }
2755
2756       /* Handle the default case.  */
2757       right = insert_right_side (AND, andexp,
2758                                  evaluate_eq_attr (exp, XEXP (value, 1),
2759                                                    insn_code, insn_index),
2760                                  insn_code, insn_index);
2761       newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2762     }
2763   else
2764     abort ();
2765
2766   /* If uses an address, must return original expression.  But set the
2767      RTX_UNCHANGING_P bit so we don't try to simplify it again.  */
2768
2769   address_used = 0;
2770   walk_attr_value (newexp);
2771
2772   if (address_used)
2773     {
2774       /* This had `&& current_alternative_string', which seems to be wrong.  */
2775       if (! RTX_UNCHANGING_P (exp))
2776         return copy_rtx_unchanging (exp);
2777       return exp;
2778     }
2779   else
2780     return newexp;
2781 }
2782 \f
2783 /* This routine is called when an AND of a term with a tree of AND's is
2784    encountered.  If the term or its complement is present in the tree, it
2785    can be replaced with TRUE or FALSE, respectively.
2786
2787    Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2788    be true and hence are complementary.  
2789
2790    There is one special case:  If we see
2791         (and (not (eq_attr "att" "v1"))
2792              (eq_attr "att" "v2"))
2793    this can be replaced by (eq_attr "att" "v2").  To do this we need to
2794    replace the term, not anything in the AND tree.  So we pass a pointer to
2795    the term.  */
2796
2797 static rtx
2798 simplify_and_tree (exp, pterm, insn_code, insn_index)
2799      rtx exp;
2800      rtx *pterm;
2801      int insn_code, insn_index;
2802 {
2803   rtx left, right;
2804   rtx newexp;
2805   rtx temp;
2806   int left_eliminates_term, right_eliminates_term;
2807
2808   if (GET_CODE (exp) == AND)
2809     {
2810       left = simplify_and_tree (XEXP (exp, 0), pterm,  insn_code, insn_index);
2811       right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2812       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2813         {
2814           newexp = attr_rtx (GET_CODE (exp), left, right);
2815
2816           exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2817         }
2818     }
2819
2820   else if (GET_CODE (exp) == IOR)
2821     {
2822       /* For the IOR case, we do the same as above, except that we can
2823          only eliminate `term' if both sides of the IOR would do so.  */
2824       temp = *pterm;
2825       left = simplify_and_tree (XEXP (exp, 0), &temp,  insn_code, insn_index);
2826       left_eliminates_term = (temp == true_rtx);
2827
2828       temp = *pterm;
2829       right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2830       right_eliminates_term = (temp == true_rtx);
2831
2832       if (left_eliminates_term && right_eliminates_term)
2833         *pterm = true_rtx;
2834
2835       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2836         {
2837           newexp = attr_rtx (GET_CODE (exp), left, right);
2838
2839           exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2840         }
2841     }
2842
2843   /* Check for simplifications.  Do some extra checking here since this
2844      routine is called so many times.  */
2845
2846   if (exp == *pterm)
2847     return true_rtx;
2848
2849   else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2850     return false_rtx;
2851
2852   else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2853     return false_rtx;
2854
2855   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2856     {
2857       if (XSTR (exp, 0) != XSTR (*pterm, 0))
2858         return exp;
2859
2860       if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
2861         return true_rtx;
2862       else
2863         return false_rtx;
2864     }
2865
2866   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2867            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2868     {
2869       if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2870         return exp;
2871
2872       if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2873         return false_rtx;
2874       else
2875         return true_rtx;
2876     }
2877
2878   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2879            && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2880     {
2881       if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2882         return exp;
2883
2884       if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2885         return false_rtx;
2886       else
2887         *pterm = true_rtx;
2888     }
2889
2890   else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2891     {
2892       if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2893         return true_rtx;
2894     }
2895
2896   else if (GET_CODE (exp) == NOT)
2897     {
2898       if (attr_equal_p (XEXP (exp, 0), *pterm))
2899         return false_rtx;
2900     }
2901
2902   else if (GET_CODE (*pterm) == NOT)
2903     {
2904       if (attr_equal_p (XEXP (*pterm, 0), exp))
2905         return false_rtx;
2906     }
2907
2908   else if (attr_equal_p (exp, *pterm))
2909     return true_rtx;
2910
2911   return exp;
2912 }
2913 \f
2914 /* Similar to `simplify_and_tree', but for IOR trees.  */
2915
2916 static rtx
2917 simplify_or_tree (exp, pterm, insn_code, insn_index)
2918      rtx exp;
2919      rtx *pterm;
2920      int insn_code, insn_index;
2921 {
2922   rtx left, right;
2923   rtx newexp;
2924   rtx temp;
2925   int left_eliminates_term, right_eliminates_term;
2926
2927   if (GET_CODE (exp) == IOR)
2928     {
2929       left = simplify_or_tree (XEXP (exp, 0), pterm,  insn_code, insn_index);
2930       right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2931       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2932         {
2933           newexp = attr_rtx (GET_CODE (exp), left, right);
2934
2935           exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2936         }
2937     }
2938
2939   else if (GET_CODE (exp) == AND)
2940     {
2941       /* For the AND case, we do the same as above, except that we can
2942          only eliminate `term' if both sides of the AND would do so.  */
2943       temp = *pterm;
2944       left = simplify_or_tree (XEXP (exp, 0), &temp,  insn_code, insn_index);
2945       left_eliminates_term = (temp == false_rtx);
2946
2947       temp = *pterm;
2948       right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2949       right_eliminates_term = (temp == false_rtx);
2950
2951       if (left_eliminates_term && right_eliminates_term)
2952         *pterm = false_rtx;
2953
2954       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2955         {
2956           newexp = attr_rtx (GET_CODE (exp), left, right);
2957
2958           exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2959         }
2960     }
2961
2962   if (attr_equal_p (exp, *pterm))
2963     return false_rtx;
2964
2965   else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2966     return true_rtx;
2967
2968   else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2969     return true_rtx;
2970
2971   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2972            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2973            && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2974     *pterm = false_rtx;
2975
2976   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2977            && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2978            && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2979     return false_rtx;
2980
2981   return exp;
2982 }
2983 \f
2984 /* Given an expression, see if it can be simplified for a particular insn
2985    code based on the values of other attributes being tested.  This can
2986    eliminate nested get_attr_... calls.
2987
2988    Note that if an endless recursion is specified in the patterns, the 
2989    optimization will loop.  However, it will do so in precisely the cases where
2990    an infinite recursion loop could occur during compilation.  It's better that
2991    it occurs here!  */
2992
2993 static rtx
2994 simplify_test_exp (exp, insn_code, insn_index)
2995      rtx exp;
2996      int insn_code, insn_index;
2997 {
2998   rtx left, right;
2999   struct attr_desc *attr;
3000   struct attr_value *av;
3001   struct insn_ent *ie;
3002   int i;
3003   rtx newexp = exp;
3004   char *spacer = (char *) obstack_finish (rtl_obstack);
3005
3006   /* Don't re-simplify something we already simplified.  */
3007   if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3008     return exp;
3009
3010   switch (GET_CODE (exp))
3011     {
3012     case AND:
3013       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3014       SIMPLIFY_ALTERNATIVE (left);
3015       if (left == false_rtx)
3016         {
3017           obstack_free (rtl_obstack, spacer);
3018           return false_rtx;
3019         }
3020       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3021       SIMPLIFY_ALTERNATIVE (right);
3022       if (left == false_rtx)
3023         {
3024           obstack_free (rtl_obstack, spacer);
3025           return false_rtx;
3026         }
3027
3028       /* If either side is an IOR and we have (eq_attr "alternative" ..")
3029          present on both sides, apply the distributive law since this will
3030          yield simplifications.  */
3031       if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3032           && compute_alternative_mask (left, IOR)
3033           && compute_alternative_mask (right, IOR))
3034         {
3035           if (GET_CODE (left) == IOR)
3036             {
3037               rtx tem = left;
3038               left = right;
3039               right = tem;
3040             }
3041
3042           newexp = attr_rtx (IOR,
3043                              attr_rtx (AND, left, XEXP (right, 0)),
3044                              attr_rtx (AND, left, XEXP (right, 1)));
3045
3046           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3047         }
3048
3049       /* Try with the term on both sides.  */
3050       right = simplify_and_tree (right, &left, insn_code, insn_index);
3051       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3052         left = simplify_and_tree (left, &right, insn_code, insn_index);
3053
3054       if (left == false_rtx || right == false_rtx)
3055         {
3056           obstack_free (rtl_obstack, spacer);
3057           return false_rtx;
3058         }
3059       else if (left == true_rtx)
3060         {
3061           return right;
3062         }
3063       else if (right == true_rtx)
3064         {
3065           return left;
3066         }
3067       /* See if all or all but one of the insn's alternatives are specified
3068          in this tree.  Optimize if so.  */
3069
3070       else if (insn_code >= 0
3071                && (GET_CODE (left) == AND
3072                    || (GET_CODE (left) == NOT
3073                        && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3074                        && XSTR (XEXP (left, 0), 0) == alternative_name)
3075                    || GET_CODE (right) == AND
3076                    || (GET_CODE (right) == NOT
3077                        && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3078                        && XSTR (XEXP (right, 0), 0) == alternative_name)))
3079         {
3080           i = compute_alternative_mask (exp, AND);
3081           if (i & ~insn_alternatives[insn_code])
3082             fatal ("Illegal alternative specified for pattern number %d",
3083                    insn_index);
3084
3085           /* If all alternatives are excluded, this is false. */
3086           i ^= insn_alternatives[insn_code];
3087           if (i == 0)
3088             return false_rtx;
3089           else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3090             {
3091               /* If just one excluded, AND a comparison with that one to the
3092                  front of the tree.  The others will be eliminated by
3093                  optimization.  We do not want to do this if the insn has one
3094                  alternative and we have tested none of them!  */
3095               left = make_alternative_compare (i);
3096               right = simplify_and_tree (exp, &left, insn_code, insn_index);
3097               newexp = attr_rtx (AND, left, right);
3098
3099               return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3100             }
3101         }
3102
3103       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3104         {
3105           newexp = attr_rtx (AND, left, right);
3106           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3107         }
3108       break;
3109
3110     case IOR:
3111       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3112       SIMPLIFY_ALTERNATIVE (left);
3113       if (left == true_rtx)
3114         {
3115           obstack_free (rtl_obstack, spacer);
3116           return true_rtx;
3117         }
3118       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3119       SIMPLIFY_ALTERNATIVE (right);
3120       if (right == true_rtx)
3121         {
3122           obstack_free (rtl_obstack, spacer);
3123           return true_rtx;
3124         }
3125
3126       right = simplify_or_tree (right, &left, insn_code, insn_index);
3127       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3128         left = simplify_or_tree (left, &right, insn_code, insn_index);
3129
3130       if (right == true_rtx || left == true_rtx)
3131         {
3132           obstack_free (rtl_obstack, spacer);
3133           return true_rtx;
3134         }
3135       else if (left == false_rtx)
3136         {
3137           return right;
3138         }
3139       else if (right == false_rtx)
3140         {
3141           return left;
3142         }
3143
3144       /* Test for simple cases where the distributive law is useful.  I.e.,
3145             convert (ior (and (x) (y))
3146                          (and (x) (z)))
3147             to      (and (x)
3148                          (ior (y) (z)))
3149        */
3150
3151       else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3152           && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3153         {
3154           newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3155
3156           left = XEXP (left, 0);
3157           right = newexp;
3158           newexp = attr_rtx (AND, left, right);
3159           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3160         }
3161
3162       /* See if all or all but one of the insn's alternatives are specified
3163          in this tree.  Optimize if so.  */
3164
3165       else if (insn_code >= 0
3166           && (GET_CODE (left) == IOR
3167               || (GET_CODE (left) == EQ_ATTR
3168                   && XSTR (left, 0) == alternative_name)
3169               || GET_CODE (right) == IOR
3170               || (GET_CODE (right) == EQ_ATTR
3171                   && XSTR (right, 0) == alternative_name)))
3172         {
3173           i = compute_alternative_mask (exp, IOR);
3174           if (i & ~insn_alternatives[insn_code])
3175             fatal ("Illegal alternative specified for pattern number %d",
3176                    insn_index);
3177
3178           /* If all alternatives are included, this is true. */
3179           i ^= insn_alternatives[insn_code];
3180           if (i == 0)
3181             return true_rtx;
3182           else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3183             {
3184               /* If just one excluded, IOR a comparison with that one to the
3185                  front of the tree.  The others will be eliminated by
3186                  optimization.  We do not want to do this if the insn has one
3187                  alternative and we have tested none of them!  */
3188               left = make_alternative_compare (i);
3189               right = simplify_and_tree (exp, &left, insn_code, insn_index);
3190               newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3191
3192               return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3193             }
3194         }
3195
3196       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3197         {
3198           newexp = attr_rtx (IOR, left, right);
3199           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3200         }
3201       break;
3202
3203     case NOT:
3204       if (GET_CODE (XEXP (exp, 0)) == NOT)
3205         {
3206           left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3207                                     insn_code, insn_index);
3208           SIMPLIFY_ALTERNATIVE (left);
3209           return left;
3210         }
3211
3212       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3213       SIMPLIFY_ALTERNATIVE (left);
3214       if (GET_CODE (left) == NOT)
3215         return XEXP (left, 0);
3216
3217       if (left == false_rtx)
3218         {
3219           obstack_free (rtl_obstack, spacer);
3220           return true_rtx;
3221         }
3222       else if (left == true_rtx)
3223         {
3224           obstack_free (rtl_obstack, spacer);
3225           return false_rtx;
3226         }
3227
3228       /* Try to apply De`Morgan's laws.  */
3229       else if (GET_CODE (left) == IOR)
3230         {
3231           newexp = attr_rtx (AND,
3232                              attr_rtx (NOT, XEXP (left, 0)),
3233                              attr_rtx (NOT, XEXP (left, 1)));
3234
3235           newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3236         }
3237       else if (GET_CODE (left) == AND)
3238         {
3239           newexp = attr_rtx (IOR,
3240                              attr_rtx (NOT, XEXP (left, 0)),
3241                              attr_rtx (NOT, XEXP (left, 1)));
3242
3243           newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3244         }
3245       else if (left != XEXP (exp, 0))
3246         {
3247           newexp = attr_rtx (NOT, left);
3248         }
3249       break;
3250
3251     case EQ_ATTR:
3252       if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3253         return (XSTR (exp, 1) == current_alternative_string
3254                 ? true_rtx : false_rtx);
3255         
3256       /* Look at the value for this insn code in the specified attribute.
3257          We normally can replace this comparison with the condition that
3258          would give this insn the values being tested for.   */
3259       if (XSTR (exp, 0) != alternative_name
3260           && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3261         for (av = attr->first_value; av; av = av->next)
3262           for (ie = av->first_insn; ie; ie = ie->next)
3263             if (ie->insn_code == insn_code)
3264               return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3265     }
3266
3267   /* We have already simplified this expression.  Simplifying it again
3268      won't buy anything unless we weren't given a valid insn code
3269      to process (i.e., we are canonicalizing something.).  */
3270   if (insn_code != -2 /* Seems wrong: && current_alternative_string.  */
3271       && ! RTX_UNCHANGING_P (newexp))
3272     return copy_rtx_unchanging (newexp);
3273
3274   return newexp;
3275 }
3276 \f
3277 /* Optimize the attribute lists by seeing if we can determine conditional
3278    values from the known values of other attributes.  This will save subroutine
3279    calls during the compilation.  */
3280
3281 static void
3282 optimize_attrs ()
3283 {
3284   struct attr_desc *attr;
3285   struct attr_value *av;
3286   struct insn_ent *ie;
3287   rtx newexp;
3288   int something_changed = 1;
3289   int i;
3290   struct attr_value_list { struct attr_value *av;
3291                            struct insn_ent *ie;
3292                            struct attr_desc * attr;
3293                            struct attr_value_list *next; };
3294   struct attr_value_list **insn_code_values;
3295   struct attr_value_list *iv;
3296
3297   /* For each insn code, make a list of all the insn_ent's for it,
3298      for all values for all attributes.  */
3299
3300   /* Make 2 extra elements, for "code" values -2 and -1.  */
3301   insn_code_values
3302     = (struct attr_value_list **) alloca ((insn_code_number + 2)
3303                                           * sizeof (struct attr_value_list *));
3304   bzero (insn_code_values,
3305          (insn_code_number + 2) * sizeof (struct attr_value_list *));
3306   /* Offset the table address so we can index by -2 or -1.  */
3307   insn_code_values += 2;
3308
3309   for (i = 0; i < MAX_ATTRS_INDEX; i++)
3310     for (attr = attrs[i]; attr; attr = attr->next)
3311       for (av = attr->first_value; av; av = av->next)
3312         for (ie = av->first_insn; ie; ie = ie->next)
3313           {
3314             iv = ((struct attr_value_list *)
3315                   alloca (sizeof (struct attr_value_list)));
3316             iv->attr = attr;
3317             iv->av = av;
3318             iv->ie = ie;
3319             iv->next = insn_code_values[ie->insn_code];
3320             insn_code_values[ie->insn_code] = iv;
3321           }
3322
3323   /* Process one insn code at a time.  */
3324   for (i = -2; i < insn_code_number; i++)
3325     {
3326       /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3327          We use it to mean "already simplified for this insn".  */
3328       for (iv = insn_code_values[i]; iv; iv = iv->next)
3329         clear_struct_flag (iv->av->value);
3330
3331       /* Loop until nothing changes for one iteration.  */
3332       something_changed = 1;
3333       while (something_changed)
3334         {
3335           something_changed = 0;
3336           for (iv = insn_code_values[i]; iv; iv = iv->next)
3337             {
3338               struct obstack *old = rtl_obstack;
3339               char *spacer = (char *) obstack_finish (temp_obstack);
3340
3341               attr = iv->attr;
3342               av = iv->av;
3343               ie = iv->ie;
3344               if (GET_CODE (av->value) != COND)
3345                 continue;
3346
3347               rtl_obstack = temp_obstack;
3348 #if 0 /* This was intended as a speed up, but it was slower.  */
3349               if (insn_n_alternatives[ie->insn_code] > 6
3350                   && count_sub_rtxs (av->value, 200) >= 200)
3351                 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3352                                                    ie->insn_index);
3353               else
3354 #endif
3355                 newexp = simplify_cond (av->value, ie->insn_code,
3356                                         ie->insn_index);
3357
3358               rtl_obstack = old;
3359               if (newexp != av->value)
3360                 {
3361                   newexp = attr_copy_rtx (newexp);
3362                   remove_insn_ent (av, ie);
3363                   av = get_attr_value (newexp, attr, ie->insn_code);
3364                   iv->av = av;
3365                   insert_insn_ent (av, ie);
3366                   something_changed = 1;
3367                 }
3368               obstack_free (temp_obstack, spacer);
3369             }
3370         }
3371     }
3372 }
3373
3374 #if 0
3375 static rtx
3376 simplify_by_alternatives (exp, insn_code, insn_index)
3377      rtx exp;
3378      int insn_code, insn_index;
3379 {
3380   int i;
3381   int len = insn_n_alternatives[insn_code];
3382   rtx newexp = rtx_alloc (COND);
3383   rtx ultimate;
3384
3385
3386   XVEC (newexp, 0) = rtvec_alloc (len * 2);
3387
3388   /* It will not matter what value we use as the default value
3389      of the new COND, since that default will never be used.
3390      Choose something of the right type.  */
3391   for (ultimate = exp; GET_CODE (ultimate) == COND;)
3392     ultimate = XEXP (ultimate, 1);
3393   XEXP (newexp, 1) = ultimate;
3394
3395   for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3396     {
3397       current_alternative_string = attr_numeral (i);
3398       XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3399       XVECEXP (newexp, 0, i * 2 + 1)
3400         = simplify_cond (exp, insn_code, insn_index);
3401     }
3402
3403   current_alternative_string = 0;
3404   return simplify_cond (newexp, insn_code, insn_index);
3405 }
3406 #endif
3407 \f
3408 /* If EXP is a suitable expression, reorganize it by constructing an
3409    equivalent expression that is a COND with the tests being all combinations
3410    of attribute values and the values being simple constants.  */
3411
3412 static rtx
3413 simplify_by_exploding (exp)
3414      rtx exp;
3415 {
3416   rtx list = 0, link, condexp, defval;
3417   struct dimension *space;
3418   rtx *condtest, *condval;
3419   int i, j, total, ndim = 0;
3420   int most_tests, num_marks, new_marks;
3421
3422   /* Locate all the EQ_ATTR expressions.  */
3423   if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3424     {
3425       unmark_used_attributes (list, 0, 0);
3426       return exp;
3427     }
3428
3429   /* Create an attribute space from the list of used attributes.  For each
3430      dimension in the attribute space, record the attribute, list of values
3431      used, and number of values used.  Add members to the list of values to
3432      cover the domain of the attribute.  This makes the expanded COND form
3433      order independent.  */
3434
3435   space = (struct dimension *) alloca (ndim * sizeof (struct dimension));
3436
3437   total = 1;
3438   for (ndim = 0; list; ndim++)
3439     {
3440       /* Pull the first attribute value from the list and record that
3441          attribute as another dimension in the attribute space.  */
3442       char *name = XSTR (XEXP (list, 0), 0);
3443       rtx *prev;
3444
3445       if ((space[ndim].attr = find_attr (name, 0)) == 0
3446           || space[ndim].attr->is_numeric)
3447         {
3448           unmark_used_attributes (list, space, ndim);
3449           return exp;
3450         }
3451
3452       /* Add all remaining attribute values that refer to this attribute.  */
3453       space[ndim].num_values = 0;
3454       space[ndim].values = 0;
3455       prev = &list;
3456       for (link = list; link; link = *prev)
3457         if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3458           {
3459             space[ndim].num_values++;
3460             *prev = XEXP (link, 1);
3461             XEXP (link, 1) = space[ndim].values;
3462             space[ndim].values = link;
3463           }
3464         else
3465           prev = &XEXP (link, 1);
3466
3467       /* Add sufficient members to the list of values to make the list
3468          mutually exclusive and record the total size of the attribute
3469          space.  */
3470       total *= add_values_to_cover (&space[ndim]);
3471     }
3472
3473   /* Sort the attribute space so that the attributes go from non-constant
3474      to constant and from most values to least values.  */
3475   for (i = 0; i < ndim; i++)
3476     for (j = ndim - 1; j > i; j--)
3477       if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3478           || space[j-1].num_values < space[j].num_values)
3479         {
3480           struct dimension tmp;
3481           tmp = space[j];
3482           space[j] = space[j-1];
3483           space[j-1] = tmp;
3484         }
3485
3486   /* Establish the initial current value.  */
3487   for (i = 0; i < ndim; i++)
3488     space[i].current_value = space[i].values;
3489
3490   condtest = (rtx *) alloca (total * sizeof (rtx));
3491   condval = (rtx *) alloca (total * sizeof (rtx));
3492
3493   /* Expand the tests and values by iterating over all values in the
3494      attribute space.  */
3495   for (i = 0;; i++)
3496     {
3497       condtest[i] = test_for_current_value (space, ndim);
3498       condval[i] = simplify_with_current_value (exp, space, ndim);
3499       if (! increment_current_value (space, ndim))
3500         break;
3501     }
3502   if (i != total - 1)
3503     abort ();
3504
3505   /* We are now finished with the original expression.  */
3506   unmark_used_attributes (0, space, ndim);
3507
3508   /* Find the most used constant value and make that the default.  */
3509   most_tests = -1;
3510   for (i = num_marks = 0; i < total; i++)
3511     if (GET_CODE (condval[i]) == CONST_STRING
3512         && ! MEM_VOLATILE_P (condval[i]))
3513       {
3514         /* Mark the unmarked constant value and count how many are marked.  */
3515         MEM_VOLATILE_P (condval[i]) = 1;
3516         for (j = new_marks = 0; j < total; j++)
3517           if (GET_CODE (condval[j]) == CONST_STRING
3518               && MEM_VOLATILE_P (condval[j]))
3519             new_marks++;
3520         if (new_marks - num_marks > most_tests)
3521           {
3522             most_tests = new_marks - num_marks;
3523             defval = condval[i];
3524           }
3525         num_marks = new_marks;
3526       }
3527   /* Clear all the marks.  */
3528   for (i = 0; i < total; i++)
3529     MEM_VOLATILE_P (condval[i]) = 0;
3530
3531   /* Give up if nothing is constant.  */
3532   if (num_marks == 0)
3533     return exp;
3534
3535   /* If all values are the default, use that.  */
3536   if (total == most_tests)
3537     return defval;
3538
3539   /* Make a COND with the most common constant value the default.  (A more
3540      complex method where tests with the same value were combined didn't
3541      seem to improve things.)  */
3542   condexp = rtx_alloc (COND);
3543   XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3544   XEXP (condexp, 1) = defval;
3545   for (i = j = 0; i < total; i++)
3546     if (condval[i] != defval)
3547       {
3548         XVECEXP (condexp, 0, 2 * j) = condtest[i];
3549         XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3550         j++;
3551       }
3552
3553   return condexp;
3554 }
3555
3556 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3557    verify that EXP can be simplified to a constant term if all the EQ_ATTR
3558    tests have known value.  */
3559
3560 static int
3561 find_and_mark_used_attributes (exp, terms, nterms)
3562      rtx exp, *terms;
3563      int *nterms;
3564 {
3565   int i;
3566
3567   switch (GET_CODE (exp))
3568     {
3569     case EQ_ATTR:
3570       if (! MEM_VOLATILE_P (exp))
3571         {
3572           rtx link = rtx_alloc (EXPR_LIST);
3573           XEXP (link, 0) = exp;
3574           XEXP (link, 1) = *terms;
3575           *terms = link;
3576           *nterms += 1;
3577           MEM_VOLATILE_P (exp) = 1;
3578         }
3579     case CONST_STRING:
3580       return 1;
3581
3582     case IF_THEN_ELSE:
3583       if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3584         return 0;
3585     case IOR:
3586     case AND:
3587       if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3588         return 0;
3589     case NOT:
3590       if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3591         return 0;
3592       return 1;
3593
3594     case COND:
3595       for (i = 0; i < XVECLEN (exp, 0); i++)
3596         if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3597           return 0;
3598       if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3599         return 0;
3600       return 1;
3601     }
3602
3603   return 0;
3604 }
3605
3606 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3607    in the values of the NDIM-dimensional attribute space SPACE.  */
3608
3609 static void
3610 unmark_used_attributes (list, space, ndim)
3611      rtx list;
3612      struct dimension *space;
3613      int ndim;
3614 {
3615   rtx link, exp;
3616   int i;
3617
3618   for (i = 0; i < ndim; i++)
3619     unmark_used_attributes (space[i].values, 0, 0);
3620
3621   for (link = list; link; link = XEXP (link, 1))
3622     {
3623       exp = XEXP (link, 0);
3624       if (GET_CODE (exp) == EQ_ATTR)
3625         MEM_VOLATILE_P (exp) = 0;
3626     }
3627 }
3628
3629 /* Update the attribute dimension DIM so that all values of the attribute
3630    are tested.  Return the updated number of values.  */
3631
3632 static int
3633 add_values_to_cover (dim)
3634      struct dimension *dim;
3635 {
3636   struct attr_value *av;
3637   rtx exp, link, *prev;
3638   int nalt = 0;
3639
3640   for (av = dim->attr->first_value; av; av = av->next)
3641     if (GET_CODE (av->value) == CONST_STRING)
3642       nalt++;
3643
3644   if (nalt < dim->num_values)
3645     abort ();
3646   else if (nalt == dim->num_values)
3647     ; /* Ok.  */
3648   else if (nalt * 2 < dim->num_values * 3)
3649     {
3650       /* Most all the values of the attribute are used, so add all the unused
3651          values.  */
3652       prev = &dim->values;
3653       for (link = dim->values; link; link = *prev)
3654         prev = &XEXP (link, 1);
3655
3656       for (av = dim->attr->first_value; av; av = av->next)
3657         if (GET_CODE (av->value) == CONST_STRING)
3658           {
3659             exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3660             if (MEM_VOLATILE_P (exp))
3661               continue;
3662
3663             link = rtx_alloc (EXPR_LIST);
3664             XEXP (link, 0) = exp;
3665             XEXP (link, 1) = 0;
3666             *prev = link;
3667             prev = &XEXP (link, 1);
3668           }
3669       dim->num_values = nalt;
3670     }
3671   else
3672     {
3673       rtx orexp = false_rtx;
3674
3675       /* Very few values are used, so compute a mutually exclusive
3676          expression.  (We could do this for numeric values if that becomes
3677          important.)  */
3678       prev = &dim->values;
3679       for (link = dim->values; link; link = *prev)
3680         {
3681           orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3682           prev = &XEXP (link, 1);
3683         }
3684       link = rtx_alloc (EXPR_LIST);
3685       XEXP (link, 0) = attr_rtx (NOT, orexp);
3686       XEXP (link, 1) = 0;
3687       *prev = link;
3688       dim->num_values++;
3689     }
3690   return dim->num_values;
3691 }
3692
3693 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3694    and return FALSE if the increment overflowed.  */
3695
3696 static int
3697 increment_current_value (space, ndim)
3698      struct dimension *space;
3699      int ndim;
3700 {
3701   int i;
3702
3703   for (i = ndim - 1; i >= 0; i--)
3704     {
3705       if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3706         space[i].current_value = space[i].values;
3707       else
3708         return 1;
3709     }
3710   return 0;
3711 }
3712
3713 /* Construct an expression corresponding to the current value for the
3714    NDIM-dimensional attribute space SPACE.  */
3715
3716 static rtx
3717 test_for_current_value (space, ndim)
3718      struct dimension *space;
3719      int ndim;
3720 {
3721   int i;
3722   rtx exp = true_rtx;
3723
3724   for (i = 0; i < ndim; i++)
3725     exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3726                              -2, -2);
3727
3728   return exp;
3729 }
3730
3731 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3732    set the corresponding EQ_ATTR expressions to that value and reduce
3733    the expression EXP as much as possible.  On input [and output], all
3734    known EQ_ATTR expressions are set to FALSE.  */
3735
3736 static rtx
3737 simplify_with_current_value (exp, space, ndim)
3738      rtx exp;
3739      struct dimension *space;
3740      int ndim;
3741 {
3742   int i;
3743   rtx x;
3744
3745   /* Mark each current value as TRUE.  */
3746   for (i = 0; i < ndim; i++)
3747     {
3748       x = XEXP (space[i].current_value, 0);
3749       if (GET_CODE (x) == EQ_ATTR)
3750         MEM_VOLATILE_P (x) = 0;
3751     }
3752
3753   exp = simplify_with_current_value_aux (exp);
3754
3755   /* Change each current value back to FALSE.  */
3756   for (i = 0; i < ndim; i++)
3757     {
3758       x = XEXP (space[i].current_value, 0);
3759       if (GET_CODE (x) == EQ_ATTR)
3760         MEM_VOLATILE_P (x) = 1;
3761     }
3762
3763   return exp;
3764 }
3765
3766 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
3767    all EQ_ATTR expressions.  */
3768
3769 static rtx
3770 simplify_with_current_value_aux (exp)
3771      rtx exp;
3772 {
3773   register int i;
3774   rtx cond;
3775
3776   switch (GET_CODE (exp))
3777     {
3778     case EQ_ATTR:
3779       if (MEM_VOLATILE_P (exp))
3780         return false_rtx;
3781       else
3782         return true_rtx;
3783     case CONST_STRING:
3784       return exp;
3785
3786     case IF_THEN_ELSE:
3787       cond = simplify_with_current_value_aux (XEXP (exp, 0));
3788       if (cond == true_rtx)
3789         return simplify_with_current_value_aux (XEXP (exp, 1));
3790       else if (cond == false_rtx)
3791         return simplify_with_current_value_aux (XEXP (exp, 2));
3792       else
3793         return attr_rtx (IF_THEN_ELSE, cond,
3794                          simplify_with_current_value_aux (XEXP (exp, 1)),
3795                          simplify_with_current_value_aux (XEXP (exp, 2)));
3796
3797     case IOR:
3798       cond = simplify_with_current_value_aux (XEXP (exp, 1));
3799       if (cond == true_rtx)
3800         return cond;
3801       else if (cond == false_rtx)
3802         return simplify_with_current_value_aux (XEXP (exp, 0));
3803       else
3804         return attr_rtx (IOR, cond,
3805                          simplify_with_current_value_aux (XEXP (exp, 0)));
3806
3807     case AND:
3808       cond = simplify_with_current_value_aux (XEXP (exp, 1));
3809       if (cond == true_rtx)
3810         return simplify_with_current_value_aux (XEXP (exp, 0));
3811       else if (cond == false_rtx)
3812         return cond;
3813       else
3814         return attr_rtx (AND, cond,
3815                          simplify_with_current_value_aux (XEXP (exp, 0)));
3816
3817     case NOT:
3818       cond = simplify_with_current_value_aux (XEXP (exp, 0));
3819       if (cond == true_rtx)
3820         return false_rtx;
3821       else if (cond == false_rtx)
3822         return true_rtx;
3823       else
3824         return attr_rtx (NOT, cond);
3825
3826     case COND:
3827       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3828         {
3829           cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
3830           if (cond == true_rtx)
3831             return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
3832           else if (cond == false_rtx)
3833             continue;
3834           else
3835             abort (); /* With all EQ_ATTR's of known value, a case should
3836                          have been selected.  */
3837         }
3838       return simplify_with_current_value_aux (XEXP (exp, 1));
3839     }
3840   abort ();
3841 }
3842 \f
3843 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions.  */
3844
3845 static void
3846 clear_struct_flag (x)
3847      rtx x;
3848 {
3849   register int i;
3850   register int j;
3851   register enum rtx_code code;
3852   register char *fmt;
3853
3854   MEM_IN_STRUCT_P (x) = 0;
3855   if (RTX_UNCHANGING_P (x))
3856     return;
3857
3858   code = GET_CODE (x);
3859
3860   switch (code)
3861     {
3862     case REG:
3863     case QUEUED:
3864     case CONST_INT:
3865     case CONST_DOUBLE:
3866     case SYMBOL_REF:
3867     case CODE_LABEL:
3868     case PC:
3869     case CC0:
3870     case EQ_ATTR:
3871     case ATTR_FLAG:
3872       return;
3873     }
3874
3875   /* Compare the elements.  If any pair of corresponding elements
3876      fail to match, return 0 for the whole things.  */
3877
3878   fmt = GET_RTX_FORMAT (code);
3879   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3880     {
3881       switch (fmt[i])
3882         {
3883         case 'V':
3884         case 'E':
3885           for (j = 0; j < XVECLEN (x, i); j++)
3886             clear_struct_flag (XVECEXP (x, i, j));
3887           break;
3888
3889         case 'e':
3890           clear_struct_flag (XEXP (x, i));
3891           break;
3892         }
3893     }
3894 }
3895
3896 /* Return the number of RTX objects making up the expression X.
3897    But if we count more more than MAX objects, stop counting.  */
3898
3899 static int
3900 count_sub_rtxs (x, max)
3901      rtx x;
3902      int max;
3903 {
3904   register int i;
3905   register int j;
3906   register enum rtx_code code;
3907   register char *fmt;
3908   int total = 0;
3909
3910   code = GET_CODE (x);
3911
3912   switch (code)
3913     {
3914     case REG:
3915     case QUEUED:
3916     case CONST_INT:
3917     case CONST_DOUBLE:
3918     case SYMBOL_REF:
3919     case CODE_LABEL:
3920     case PC:
3921     case CC0:
3922     case EQ_ATTR:
3923     case ATTR_FLAG:
3924       return 1;
3925     }
3926
3927   /* Compare the elements.  If any pair of corresponding elements
3928      fail to match, return 0 for the whole things.  */
3929
3930   fmt = GET_RTX_FORMAT (code);
3931   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3932     {
3933       if (total >= max)
3934         return total;
3935
3936       switch (fmt[i])
3937         {
3938         case 'V':
3939         case 'E':
3940           for (j = 0; j < XVECLEN (x, i); j++)
3941             total += count_sub_rtxs (XVECEXP (x, i, j), max);
3942           break;
3943
3944         case 'e':
3945           total += count_sub_rtxs (XEXP (x, i), max);
3946           break;
3947         }
3948     }
3949   return total;
3950
3951 }
3952 \f
3953 /* Create table entries for DEFINE_ATTR.  */
3954
3955 static void
3956 gen_attr (exp)
3957      rtx exp;
3958 {
3959   struct attr_desc *attr;
3960   struct attr_value *av;
3961   char *name_ptr;
3962   char *p;
3963
3964   /* Make a new attribute structure.  Check for duplicate by looking at
3965      attr->default_val, since it is initialized by this routine.  */
3966   attr = find_attr (XSTR (exp, 0), 1);
3967   if (attr->default_val)
3968     fatal ("Duplicate definition for `%s' attribute", attr->name);
3969
3970   if (*XSTR (exp, 1) == '\0')
3971       attr->is_numeric = 1;
3972   else
3973     {
3974       name_ptr = XSTR (exp, 1);
3975       while ((p = next_comma_elt (&name_ptr)) != NULL)
3976         {
3977           av = (struct attr_value *) oballoc (sizeof (struct attr_value));
3978           av->value = attr_rtx (CONST_STRING, p);
3979           av->next = attr->first_value;
3980           attr->first_value = av;
3981           av->first_insn = NULL;
3982           av->num_insns = 0;
3983           av->has_asm_insn = 0;
3984         }
3985     }
3986
3987   if (GET_CODE (XEXP (exp, 2)) == CONST)
3988     {
3989       attr->is_const = 1;
3990       if (attr->is_numeric)
3991         fatal ("Constant attributes may not take numeric values");
3992       /* Get rid of the CONST node.  It is allowed only at top-level.  */
3993       XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3994     }
3995
3996   if (! strcmp (attr->name, "length") && ! attr->is_numeric)
3997     fatal ("`length' attribute must take numeric values");
3998
3999   /* Set up the default value. */
4000   XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4001   attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4002 }
4003 \f
4004 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4005    alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
4006    number of alternatives as this should be checked elsewhere.  */
4007
4008 static int
4009 count_alternatives (exp)
4010      rtx exp;
4011 {
4012   int i, j, n;
4013   char *fmt;
4014   
4015   if (GET_CODE (exp) == MATCH_OPERAND)
4016     return n_comma_elts (XSTR (exp, 2));
4017
4018   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4019        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4020     switch (*fmt++)
4021       {
4022       case 'e':
4023       case 'u':
4024         n = count_alternatives (XEXP (exp, i));
4025         if (n)
4026           return n;
4027         break;
4028
4029       case 'E':
4030       case 'V':
4031         if (XVEC (exp, i) != NULL)
4032           for (j = 0; j < XVECLEN (exp, i); j++)
4033             {
4034               n = count_alternatives (XVECEXP (exp, i, j));
4035               if (n)
4036                 return n;
4037             }
4038       }
4039
4040   return 0;
4041 }
4042 \f
4043 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4044    `alternative' attribute.  */
4045
4046 static int
4047 compares_alternatives_p (exp)
4048      rtx exp;
4049 {
4050   int i, j;
4051   char *fmt;
4052
4053   if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4054     return 1;
4055
4056   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4057        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4058     switch (*fmt++)
4059       {
4060       case 'e':
4061       case 'u':
4062         if (compares_alternatives_p (XEXP (exp, i)))
4063           return 1;
4064         break;
4065
4066       case 'E':
4067         for (j = 0; j < XVECLEN (exp, i); j++)
4068           if (compares_alternatives_p (XVECEXP (exp, i, j)))
4069             return 1;
4070         break;
4071       }
4072
4073   return 0;
4074 }
4075 \f
4076 /* Returns non-zero is INNER is contained in EXP.  */
4077
4078 static int
4079 contained_in_p (inner, exp)
4080      rtx inner;
4081      rtx exp;
4082 {
4083   int i, j;
4084   char *fmt;
4085
4086   if (rtx_equal_p (inner, exp))
4087     return 1;
4088
4089   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4090        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4091     switch (*fmt++)
4092       {
4093       case 'e':
4094       case 'u':
4095         if (contained_in_p (inner, XEXP (exp, i)))
4096           return 1;
4097         break;
4098
4099       case 'E':
4100         for (j = 0; j < XVECLEN (exp, i); j++)
4101           if (contained_in_p (inner, XVECEXP (exp, i, j)))
4102             return 1;
4103         break;
4104       }
4105
4106   return 0;
4107 }
4108 \f       
4109 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
4110
4111 static void
4112 gen_insn (exp)
4113      rtx exp;
4114 {
4115   struct insn_def *id;
4116
4117   id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4118   id->next = defs;
4119   defs = id;
4120   id->def = exp;
4121
4122   switch (GET_CODE (exp))
4123     {
4124     case DEFINE_INSN:
4125       id->insn_code = insn_code_number++;
4126       id->insn_index = insn_index_number++;
4127       id->num_alternatives = count_alternatives (exp);
4128       if (id->num_alternatives == 0)
4129         id->num_alternatives = 1;
4130       id->vec_idx = 4;
4131       break;
4132
4133     case DEFINE_PEEPHOLE:
4134       id->insn_code = insn_code_number++;
4135       id->insn_index = insn_index_number++;
4136       id->num_alternatives = count_alternatives (exp);
4137       if (id->num_alternatives == 0)
4138         id->num_alternatives = 1;
4139       id->vec_idx = 3;
4140       break;
4141
4142     case DEFINE_ASM_ATTRIBUTES:
4143       id->insn_code = -1;
4144       id->insn_index = -1;
4145       id->num_alternatives = 1;
4146       id->vec_idx = 0;
4147       got_define_asm_attributes = 1;
4148       break;
4149     }
4150 }
4151 \f
4152 /* Process a DEFINE_DELAY.  Validate the vector length, check if annul
4153    true or annul false is specified, and make a `struct delay_desc'.  */
4154
4155 static void
4156 gen_delay (def)
4157      rtx def;
4158 {
4159   struct delay_desc *delay;
4160   int i;
4161
4162   if (XVECLEN (def, 1) % 3 != 0)
4163     fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
4164
4165   for (i = 0; i < XVECLEN (def, 1); i += 3)
4166     {
4167       if (XVECEXP (def, 1, i + 1))
4168         have_annul_true = 1;
4169       if (XVECEXP (def, 1, i + 2))
4170         have_annul_false = 1;
4171     }
4172   
4173   delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4174   delay->def = def;
4175   delay->num = ++num_delays;
4176   delay->next = delays;
4177   delays = delay;
4178 }
4179 \f
4180 /* Process a DEFINE_FUNCTION_UNIT.  
4181
4182    This gives information about a function unit contained in the CPU.
4183    We fill in a `struct function_unit_op' and a `struct function_unit'
4184    with information used later by `expand_unit'.  */
4185
4186 static void
4187 gen_unit (def)
4188      rtx def;
4189 {
4190   struct function_unit *unit;
4191   struct function_unit_op *op;
4192   char *name = XSTR (def, 0);
4193   int multiplicity = XINT (def, 1);
4194   int simultaneity = XINT (def, 2);
4195   rtx condexp = XEXP (def, 3);
4196   int ready_cost = MAX (XINT (def, 4), 1);
4197   int issue_delay = MAX (XINT (def, 5), 1);
4198
4199   /* See if we have already seen this function unit.  If so, check that
4200      the multiplicity and simultaneity values are the same.  If not, make
4201      a structure for this function unit.  */
4202   for (unit = units; unit; unit = unit->next)
4203     if (! strcmp (unit->name, name))
4204       {
4205         if (unit->multiplicity != multiplicity
4206             || unit->simultaneity != simultaneity)
4207           fatal ("Differing specifications given for `%s' function unit.",
4208                  unit->name);
4209         break;
4210       }
4211
4212   if (unit == 0)
4213     {
4214       unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4215       unit->name = name;
4216       unit->multiplicity = multiplicity;
4217       unit->simultaneity = simultaneity;
4218       unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4219       unit->num = num_units++;
4220       unit->num_opclasses = 0;
4221       unit->condexp = false_rtx;
4222       unit->ops = 0;
4223       unit->next = units;
4224       units = unit;
4225     }
4226
4227   /* Make a new operation class structure entry and initialize it.  */
4228   op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4229   op->condexp = condexp;
4230   op->num = unit->num_opclasses++;
4231   op->ready = ready_cost;
4232   op->issue_delay = issue_delay;
4233   op->next = unit->ops;
4234   unit->ops = op;
4235
4236   /* Set our issue expression based on whether or not an optional conflict
4237      vector was specified.  */
4238   if (XVEC (def, 6))
4239     {
4240       /* Compute the IOR of all the specified expressions.  */
4241       rtx orexp = false_rtx;
4242       int i;
4243
4244       for (i = 0; i < XVECLEN (def, 6); i++)
4245         orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4246
4247       op->conflict_exp = orexp;
4248       extend_range (&unit->issue_delay, 1, issue_delay);
4249     }
4250   else
4251     {
4252       op->conflict_exp = true_rtx;
4253       extend_range (&unit->issue_delay, issue_delay, issue_delay);
4254     }
4255
4256   /* Merge our conditional into that of the function unit so we can determine
4257      which insns are used by the function unit.  */
4258   unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4259 }
4260 \f
4261 /* Given a piece of RTX, print a C expression to test it's truth value.
4262    We use AND and IOR both for logical and bit-wise operations, so 
4263    interpret them as logical unless they are inside a comparison expression.
4264    The second operand of this function will be non-zero in that case.  */
4265
4266 static void
4267 write_test_expr (exp, in_comparison)
4268      rtx exp;
4269      int in_comparison;
4270 {
4271   int comparison_operator = 0;
4272   RTX_CODE code;
4273   struct attr_desc *attr;
4274
4275   /* In order not to worry about operator precedence, surround our part of
4276      the expression with parentheses.  */
4277
4278   printf ("(");
4279   code = GET_CODE (exp);
4280   switch (code)
4281     {
4282     /* Binary operators.  */
4283     case EQ: case NE:
4284     case GE: case GT: case GEU: case GTU:
4285     case LE: case LT: case LEU: case LTU:
4286       comparison_operator = 1;
4287
4288     case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
4289     case AND:    case IOR:    case XOR:
4290     case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4291       write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator);
4292       switch (code)
4293         {
4294         case EQ:
4295           printf (" == ");
4296           break;
4297         case NE:
4298           printf (" != ");
4299           break;
4300         case GE:
4301           printf (" >= ");
4302           break;
4303         case GT:
4304           printf (" > ");
4305           break;
4306         case GEU:
4307           printf (" >= (unsigned) ");
4308           break;
4309         case GTU:
4310           printf (" > (unsigned) ");
4311           break;
4312         case LE:
4313           printf (" <= ");
4314           break;
4315         case LT:
4316           printf (" < ");
4317           break;
4318         case LEU:
4319           printf (" <= (unsigned) ");
4320           break;
4321         case LTU:
4322           printf (" < (unsigned) ");
4323           break;
4324         case PLUS:
4325           printf (" + ");
4326           break;
4327         case MINUS:
4328           printf (" - ");
4329           break;
4330         case MULT:
4331           printf (" * ");
4332           break;
4333         case DIV:
4334           printf (" / ");
4335           break;
4336         case MOD:
4337           printf (" %% ");
4338           break;
4339         case AND:
4340           if (in_comparison)
4341             printf (" & ");
4342           else
4343             printf (" && ");
4344           break;
4345         case IOR:
4346           if (in_comparison)
4347             printf (" | ");
4348           else
4349             printf (" || ");
4350           break;
4351         case XOR:
4352           printf (" ^ ");
4353           break;
4354         case ASHIFT:
4355           printf (" << ");
4356           break;
4357         case LSHIFTRT:
4358         case ASHIFTRT:
4359           printf (" >> ");
4360           break;
4361         }
4362
4363       write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator);
4364       break;
4365
4366     case NOT:
4367       /* Special-case (not (eq_attrq "alternative" "x")) */
4368       if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4369           && XSTR (XEXP (exp, 0), 0) == alternative_name)
4370         {
4371           printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4372           break;
4373         }
4374
4375       /* Otherwise, fall through to normal unary operator.  */
4376
4377     /* Unary operators.  */   
4378     case ABS:  case NEG:
4379       switch (code)
4380         {
4381         case NOT:
4382           if (in_comparison)
4383             printf ("~ ");
4384           else
4385             printf ("! ");
4386           break;
4387         case ABS:
4388           printf ("abs ");
4389           break;
4390         case NEG:
4391           printf ("-");
4392           break;
4393         }
4394
4395       write_test_expr (XEXP (exp, 0), in_comparison);
4396       break;
4397
4398     /* Comparison test of an attribute with a value.  Most of these will
4399        have been removed by optimization.   Handle "alternative"
4400        specially and give error if EQ_ATTR present inside a comparison.  */
4401     case EQ_ATTR:
4402       if (in_comparison)
4403         fatal ("EQ_ATTR not valid inside comparison");
4404
4405       if (XSTR (exp, 0) == alternative_name)
4406         {
4407           printf ("which_alternative == %s", XSTR (exp, 1));
4408           break;
4409         }
4410
4411       attr = find_attr (XSTR (exp, 0), 0);
4412       if (! attr) abort ();
4413
4414       /* Now is the time to expand the value of a constant attribute.  */
4415       if (attr->is_const)
4416         {
4417           write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4418                                              -2, -2),
4419                            in_comparison);
4420         }
4421       else
4422         {
4423           printf ("get_attr_%s (insn) == ", attr->name);
4424           write_attr_valueq (attr, XSTR (exp, 1)); 
4425         }
4426       break;
4427
4428     /* Comparison test of flags for define_delays.  */
4429     case ATTR_FLAG:
4430       if (in_comparison)
4431         fatal ("ATTR_FLAG not valid inside comparison");
4432       printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4433       break;
4434
4435     /* See if an operand matches a predicate.  */
4436     case MATCH_OPERAND:
4437       /* If only a mode is given, just ensure the mode matches the operand.
4438          If neither a mode nor predicate is given, error.  */
4439      if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4440         {
4441           if (GET_MODE (exp) == VOIDmode)
4442             fatal ("Null MATCH_OPERAND specified as test");
4443           else
4444             printf ("GET_MODE (operands[%d]) == %smode",
4445                     XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4446         }
4447       else
4448         printf ("%s (operands[%d], %smode)",
4449                 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4450       break;
4451
4452     /* Constant integer. */
4453     case CONST_INT:
4454 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
4455       printf ("%d", XWINT (exp, 0));
4456 #else
4457       printf ("%ld", XWINT (exp, 0));
4458 #endif
4459       break;
4460
4461     /* A random C expression. */
4462     case SYMBOL_REF:
4463       printf ("%s", XSTR (exp, 0));
4464       break;
4465
4466     /* The address of the branch target.  */
4467     case MATCH_DUP:
4468       printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
4469       break;
4470
4471     /* The address of the current insn.  It would be more consistent with
4472        other usage to make this the address of the NEXT insn, but this gets
4473        too confusing because of the ambiguity regarding the length of the
4474        current insn.  */
4475     case PC:
4476       printf ("insn_current_address");
4477       break;
4478
4479     default:
4480       fatal ("bad RTX code `%s' in attribute calculation\n",
4481              GET_RTX_NAME (code));
4482     }
4483
4484   printf (")");
4485 }
4486 \f
4487 /* Given an attribute value, return the maximum CONST_STRING argument
4488    encountered.  It is assumed that they are all numeric.  */
4489
4490 static int
4491 max_attr_value (exp)
4492      rtx exp;
4493 {
4494   int current_max = 0;
4495   int n;
4496   int i;
4497
4498   if (GET_CODE (exp) == CONST_STRING)
4499     return atoi (XSTR (exp, 0));
4500
4501   else if (GET_CODE (exp) == COND)
4502     {
4503       for (i = 0; i < XVECLEN (exp, 0); i += 2)
4504         {
4505           n = max_attr_value (XVECEXP (exp, 0, i + 1));
4506           if (n > current_max)
4507             current_max = n;
4508         }
4509
4510       n = max_attr_value (XEXP (exp, 1));
4511       if (n > current_max)
4512         current_max = n;
4513     }
4514
4515   else if (GET_CODE (exp) == IF_THEN_ELSE)
4516     {
4517       current_max = max_attr_value (XEXP (exp, 1));
4518       n = max_attr_value (XEXP (exp, 2));
4519       if (n > current_max)
4520         current_max = n;
4521     }
4522
4523   else
4524     abort ();
4525
4526   return current_max;
4527 }
4528 \f
4529 /* Scan an attribute value, possibly a conditional, and record what actions
4530    will be required to do any conditional tests in it.
4531
4532    Specifically, set
4533         `must_extract'    if we need to extract the insn operands
4534         `must_constrain'  if we must compute `which_alternative'
4535         `address_used'    if an address expression was used
4536         `length_used'     if an (eq_attr "length" ...) was used
4537  */
4538
4539 static void
4540 walk_attr_value (exp)
4541      rtx exp;
4542 {
4543   register int i, j;
4544   register char *fmt;
4545   RTX_CODE code;
4546
4547   if (exp == NULL)
4548     return;
4549
4550   code = GET_CODE (exp);
4551   switch (code)
4552     {
4553     case SYMBOL_REF:
4554       if (! RTX_UNCHANGING_P (exp))
4555         /* Since this is an arbitrary expression, it can look at anything.
4556            However, constant expressions do not depend on any particular
4557            insn.  */
4558         must_extract = must_constrain = 1;
4559       return;
4560
4561     case MATCH_OPERAND:
4562       must_extract = 1;
4563       return;
4564
4565     case EQ_ATTR:
4566       if (XSTR (exp, 0) == alternative_name)
4567         must_extract = must_constrain = 1;
4568       else if (strcmp (XSTR (exp, 0), "length") == 0)
4569         length_used = 1;
4570       return;
4571
4572     case MATCH_DUP:
4573     case PC:
4574       address_used = 1;
4575       return;
4576
4577     case ATTR_FLAG:
4578       return;
4579     }
4580
4581   for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4582     switch (*fmt++)
4583       {
4584       case 'e':
4585       case 'u':
4586         walk_attr_value (XEXP (exp, i));
4587         break;
4588
4589       case 'E':
4590         if (XVEC (exp, i) != NULL)
4591           for (j = 0; j < XVECLEN (exp, i); j++)
4592             walk_attr_value (XVECEXP (exp, i, j));
4593         break;
4594       }
4595 }
4596 \f
4597 /* Write out a function to obtain the attribute for a given INSN.  */
4598
4599 static void
4600 write_attr_get (attr)
4601      struct attr_desc *attr;
4602 {
4603   struct attr_value *av, *common_av;
4604
4605   /* Find the most used attribute value.  Handle that as the `default' of the
4606      switch we will generate. */
4607   common_av = find_most_used (attr);
4608
4609   /* Write out start of function, then all values with explicit `case' lines,
4610      then a `default', then the value with the most uses.  */
4611   if (!attr->is_numeric)
4612     printf ("enum attr_%s\n", attr->name);
4613   else if (attr->unsigned_p)
4614     printf ("unsigned int\n");
4615   else
4616     printf ("int\n");
4617
4618   /* If the attribute name starts with a star, the remainder is the name of
4619      the subroutine to use, instead of `get_attr_...'.  */
4620   if (attr->name[0] == '*')
4621     printf ("%s (insn)\n", &attr->name[1]);
4622   else if (attr->is_const == 0)
4623     printf ("get_attr_%s (insn)\n", attr->name);
4624   else
4625     {
4626       printf ("get_attr_%s ()\n", attr->name);
4627       printf ("{\n");
4628
4629       for (av = attr->first_value; av; av = av->next)
4630         if (av->num_insns != 0)
4631           write_attr_set (attr, 2, av->value, "return", ";",
4632                           true_rtx, av->first_insn->insn_code,
4633                           av->first_insn->insn_index);
4634
4635       printf ("}\n\n");
4636       return;
4637     }
4638   printf ("     rtx insn;\n");
4639   printf ("{\n");
4640   printf ("  switch (recog_memoized (insn))\n");
4641   printf ("    {\n");
4642
4643   for (av = attr->first_value; av; av = av->next)
4644     if (av != common_av)
4645       write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4646
4647   write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4648   printf ("    }\n}\n\n");
4649 }
4650 \f
4651 /* Given an AND tree of known true terms (because we are inside an `if' with
4652    that as the condition or are in an `else' clause) and an expression,
4653    replace any known true terms with TRUE.  Use `simplify_and_tree' to do
4654    the bulk of the work.  */
4655
4656 static rtx
4657 eliminate_known_true (known_true, exp, insn_code, insn_index)
4658      rtx known_true;
4659      rtx exp;
4660      int insn_code, insn_index;
4661 {
4662   rtx term;
4663
4664   known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4665
4666   if (GET_CODE (known_true) == AND)
4667     {
4668       exp = eliminate_known_true (XEXP (known_true, 0), exp,
4669                                   insn_code, insn_index);
4670       exp = eliminate_known_true (XEXP (known_true, 1), exp,
4671                                   insn_code, insn_index);
4672     }
4673   else
4674     {
4675       term = known_true;
4676       exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4677     }
4678
4679   return exp;
4680 }
4681 \f
4682 /* Write out a series of tests and assignment statements to perform tests and
4683    sets of an attribute value.  We are passed an indentation amount and prefix
4684    and suffix strings to write around each attribute value (e.g., "return"
4685    and ";").  */
4686
4687 static void
4688 write_attr_set (attr, indent, value, prefix, suffix, known_true,
4689                 insn_code, insn_index)
4690      struct attr_desc *attr;
4691      int indent;
4692      rtx value;
4693      char *prefix;
4694      char *suffix;
4695      rtx known_true;
4696      int insn_code, insn_index;
4697 {
4698   if (GET_CODE (value) == CONST_STRING)
4699     {
4700       write_indent (indent);
4701       printf ("%s ", prefix);
4702       write_attr_value (attr, value);
4703       printf ("%s\n", suffix);
4704     }
4705   else if (GET_CODE (value) == COND)
4706     {
4707       /* Assume the default value will be the default of the COND unless we
4708          find an always true expression.  */
4709       rtx default_val = XEXP (value, 1);
4710       rtx our_known_true = known_true;
4711       rtx newexp;
4712       int first_if = 1;
4713       int i;
4714
4715       for (i = 0; i < XVECLEN (value, 0); i += 2)
4716         {
4717           rtx testexp;
4718           rtx inner_true;
4719
4720           testexp = eliminate_known_true (our_known_true,
4721                                           XVECEXP (value, 0, i),
4722                                           insn_code, insn_index);
4723           newexp = attr_rtx (NOT, testexp);
4724           newexp  = insert_right_side (AND, our_known_true, newexp,
4725                                        insn_code, insn_index);
4726
4727           /* If the test expression is always true or if the next `known_true'
4728              expression is always false, this is the last case, so break
4729              out and let this value be the `else' case.  */
4730           if (testexp == true_rtx || newexp == false_rtx)
4731             {
4732               default_val = XVECEXP (value, 0, i + 1);
4733               break;
4734             }
4735
4736           /* Compute the expression to pass to our recursive call as being
4737              known true.  */
4738           inner_true = insert_right_side (AND, our_known_true,
4739                                           testexp, insn_code, insn_index);
4740
4741           /* If this is always false, skip it.  */
4742           if (inner_true == false_rtx)
4743             continue;
4744
4745           write_indent (indent);
4746           printf ("%sif ", first_if ? "" : "else ");
4747           first_if = 0;
4748           write_test_expr (testexp, 0);
4749           printf ("\n");
4750           write_indent (indent + 2);
4751           printf ("{\n");
4752
4753           write_attr_set (attr, indent + 4,  
4754                           XVECEXP (value, 0, i + 1), prefix, suffix,
4755                           inner_true, insn_code, insn_index);
4756           write_indent (indent + 2);
4757           printf ("}\n");
4758           our_known_true = newexp;
4759         }
4760
4761       if (! first_if)
4762         {
4763           write_indent (indent);
4764           printf ("else\n");
4765           write_indent (indent + 2);
4766           printf ("{\n");
4767         }
4768
4769       write_attr_set (attr, first_if ? indent : indent + 4, default_val,
4770                       prefix, suffix, our_known_true, insn_code, insn_index);
4771
4772       if (! first_if)
4773         {
4774           write_indent (indent + 2);
4775           printf ("}\n");
4776         }
4777     }
4778   else
4779     abort ();
4780 }
4781 \f
4782 /* Write out the computation for one attribute value.  */
4783
4784 static void
4785 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
4786                  known_true)
4787      struct attr_desc *attr;
4788      struct attr_value *av;
4789      int write_case_lines;
4790      char *prefix, *suffix;
4791      int indent;
4792      rtx known_true;
4793 {
4794   struct insn_ent *ie;
4795
4796   if (av->num_insns == 0)
4797     return;
4798
4799   if (av->has_asm_insn)
4800     {
4801       write_indent (indent);
4802       printf ("case -1:\n");
4803       write_indent (indent + 2);
4804       printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4805       write_indent (indent + 2);
4806       printf ("    && asm_noperands (PATTERN (insn)) < 0)\n");
4807       write_indent (indent + 2);
4808       printf ("  fatal_insn_not_found (insn);\n");
4809     }
4810
4811   if (write_case_lines)
4812     {
4813       for (ie = av->first_insn; ie; ie = ie->next)
4814         if (ie->insn_code != -1)
4815           {
4816             write_indent (indent);
4817             printf ("case %d:\n", ie->insn_code);
4818           }
4819     }
4820   else
4821     {
4822       write_indent (indent);
4823       printf ("default:\n");
4824     }
4825
4826   /* See what we have to do to output this value.  */
4827   must_extract = must_constrain = address_used = 0;
4828   walk_attr_value (av->value);
4829
4830   if (must_extract)
4831     {
4832       write_indent (indent + 2);
4833       printf ("insn_extract (insn);\n");
4834     }
4835
4836   if (must_constrain)
4837     {
4838 #ifdef REGISTER_CONSTRAINTS
4839       write_indent (indent + 2);
4840       printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
4841       write_indent (indent + 2);
4842       printf ("  fatal_insn_not_found (insn);\n");
4843 #endif
4844     }
4845
4846   write_attr_set (attr, indent + 2, av->value, prefix, suffix,
4847                   known_true, av->first_insn->insn_code,
4848                   av->first_insn->insn_index);
4849
4850   if (strncmp (prefix, "return", 6))
4851     {
4852       write_indent (indent + 2);
4853       printf ("break;\n");
4854     }
4855   printf ("\n");
4856 }
4857 \f
4858 /* Utilities to write names in various forms.  */
4859
4860 static void
4861 write_attr_valueq (attr, s)
4862      struct attr_desc *attr;
4863      char *s;
4864 {
4865   if (attr->is_numeric)
4866     {
4867       printf ("%s", s);
4868       /* Make the blockage range values easier to read.  */
4869       if (strlen (s) > 1)
4870         printf (" /* 0x%x */", atoi (s));
4871     }
4872   else
4873     {
4874       write_upcase (attr->name);
4875       printf ("_");
4876       write_upcase (s);
4877     }
4878 }
4879
4880 static void
4881 write_attr_value (attr, value)
4882      struct attr_desc *attr;
4883      rtx value;
4884 {
4885   if (GET_CODE (value) != CONST_STRING)
4886     abort ();
4887
4888   write_attr_valueq (attr, XSTR (value, 0));
4889 }
4890
4891 static void
4892 write_upcase (str)
4893      char *str;
4894 {
4895   while (*str)
4896     if (*str < 'a' || *str > 'z')
4897       printf ("%c", *str++);
4898     else
4899       printf ("%c", *str++ - 'a' + 'A');
4900 }
4901
4902 static void
4903 write_indent (indent)
4904      int indent;
4905 {
4906   for (; indent > 8; indent -= 8)
4907     printf ("\t");
4908
4909   for (; indent; indent--)
4910     printf (" ");
4911 }
4912 \f
4913 /* Write a subroutine that is given an insn that requires a delay slot, a
4914    delay slot ordinal, and a candidate insn.  It returns non-zero if the
4915    candidate can be placed in the specified delay slot of the insn.
4916
4917    We can write as many as three subroutines.  `eligible_for_delay'
4918    handles normal delay slots, `eligible_for_annul_true' indicates that
4919    the specified insn can be annulled if the branch is true, and likewise
4920    for `eligible_for_annul_false'.
4921
4922    KIND is a string distinguishing these three cases ("delay", "annul_true",
4923    or "annul_false").  */
4924
4925 static void
4926 write_eligible_delay (kind)
4927      char *kind;
4928 {
4929   struct delay_desc *delay;
4930   int max_slots;
4931   char str[50];
4932   struct attr_desc *attr;
4933   struct attr_value *av, *common_av;
4934   int i;
4935
4936   /* Compute the maximum number of delay slots required.  We use the delay
4937      ordinal times this number plus one, plus the slot number as an index into
4938      the appropriate predicate to test.  */
4939
4940   for (delay = delays, max_slots = 0; delay; delay = delay->next)
4941     if (XVECLEN (delay->def, 1) / 3 > max_slots)
4942       max_slots = XVECLEN (delay->def, 1) / 3;
4943
4944   /* Write function prelude.  */
4945
4946   printf ("int\n");
4947   printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n", 
4948            kind);
4949   printf ("     rtx delay_insn;\n");
4950   printf ("     int slot;\n");
4951   printf ("     rtx candidate_insn;\n");
4952   printf ("     int flags;\n");
4953   printf ("{\n");
4954   printf ("  rtx insn;\n");
4955   printf ("\n");
4956   printf ("  if (slot >= %d)\n", max_slots);
4957   printf ("    abort ();\n");
4958   printf ("\n");
4959
4960   /* If more than one delay type, find out which type the delay insn is.  */
4961
4962   if (num_delays > 1)
4963     {
4964       attr = find_attr ("*delay_type", 0);
4965       if (! attr) abort ();
4966       common_av = find_most_used (attr);
4967
4968       printf ("  insn = delay_insn;\n");
4969       printf ("  switch (recog_memoized (insn))\n");
4970       printf ("    {\n");
4971
4972       sprintf (str, " * %d;\n      break;", max_slots);
4973       for (av = attr->first_value; av; av = av->next)
4974         if (av != common_av)
4975           write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4976
4977       write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4978       printf ("    }\n\n");
4979
4980       /* Ensure matched.  Otherwise, shouldn't have been called.  */
4981       printf ("  if (slot < %d)\n", max_slots);
4982       printf ("    abort ();\n\n");
4983     }
4984
4985   /* If just one type of delay slot, write simple switch.  */
4986   if (num_delays == 1 && max_slots == 1)
4987     {
4988       printf ("  insn = candidate_insn;\n");
4989       printf ("  switch (recog_memoized (insn))\n");
4990       printf ("    {\n");
4991
4992       attr = find_attr ("*delay_1_0", 0);
4993       if (! attr) abort ();
4994       common_av = find_most_used (attr);
4995
4996       for (av = attr->first_value; av; av = av->next)
4997         if (av != common_av)
4998           write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4999
5000       write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5001       printf ("    }\n");
5002     }
5003
5004   else
5005     {
5006       /* Write a nested CASE.  The first indicates which condition we need to
5007          test, and the inner CASE tests the condition.  */
5008       printf ("  insn = candidate_insn;\n");
5009       printf ("  switch (slot)\n");
5010       printf ("    {\n");
5011
5012       for (delay = delays; delay; delay = delay->next)
5013         for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5014           {
5015             printf ("    case %d:\n",
5016                     (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5017             printf ("      switch (recog_memoized (insn))\n");
5018             printf ("\t{\n");
5019
5020             sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5021             attr = find_attr (str, 0);
5022             if (! attr) abort ();
5023             common_av = find_most_used (attr);
5024
5025             for (av = attr->first_value; av; av = av->next)
5026               if (av != common_av)
5027                 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5028
5029             write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5030             printf ("      }\n");
5031           }
5032
5033       printf ("    default:\n");
5034       printf ("      abort ();\n");     
5035       printf ("    }\n");
5036     }
5037
5038   printf ("}\n\n");
5039 }
5040 \f
5041 /* Write routines to compute conflict cost for function units.  Then write a
5042    table describing the available function units.  */
5043
5044 static void
5045 write_function_unit_info ()
5046 {
5047   struct function_unit *unit;
5048   int i;
5049
5050   /* Write out conflict routines for function units.  Don't bother writing
5051      one if there is only one issue delay value.  */
5052
5053   for (unit = units; unit; unit = unit->next)
5054     {
5055       if (unit->needs_blockage_function)
5056         write_complex_function (unit, "blockage", "block");
5057
5058       /* If the minimum and maximum conflict costs are the same, there
5059          is only one value, so we don't need a function.  */
5060       if (! unit->needs_conflict_function)
5061         {
5062           unit->default_cost = make_numeric_value (unit->issue_delay.max);
5063           continue;
5064         }
5065
5066       /* The function first computes the case from the candidate insn.  */
5067       unit->default_cost = make_numeric_value (0);
5068       write_complex_function (unit, "conflict_cost", "cost");
5069     }
5070
5071   /* Now that all functions have been written, write the table describing
5072      the function units.   The name is included for documentation purposes
5073      only.  */
5074
5075   printf ("struct function_unit_desc function_units[] = {\n");
5076
5077   /* Write out the descriptions in numeric order, but don't force that order
5078      on the list.  Doing so increases the runtime of genattrtab.c.  */
5079   for (i = 0; i < num_units; i++)
5080     {
5081       for (unit = units; unit; unit = unit->next)
5082         if (unit->num == i)
5083           break;
5084
5085       printf ("  {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5086               unit->name, 1 << unit->num, unit->multiplicity,
5087               unit->simultaneity, XSTR (unit->default_cost, 0),
5088               unit->issue_delay.max, unit->name);
5089
5090       if (unit->needs_conflict_function)
5091         printf ("%s_unit_conflict_cost, ", unit->name);
5092       else
5093         printf ("0, ");
5094
5095       printf ("%d, ", unit->max_blockage);
5096
5097       if (unit->needs_range_function)
5098         printf ("%s_unit_blockage_range, ", unit->name);
5099       else
5100         printf ("0, ");
5101
5102       if (unit->needs_blockage_function)
5103         printf ("%s_unit_blockage", unit->name);
5104       else
5105         printf ("0");
5106
5107       printf ("}, \n");
5108     }
5109
5110   printf ("};\n\n");
5111 }
5112
5113 static void
5114 write_complex_function (unit, name, connection)
5115      struct function_unit *unit;
5116      char *name, *connection;
5117 {
5118   struct attr_desc *case_attr, *attr;
5119   struct attr_value *av, *common_av;
5120   rtx value;
5121   char *str;
5122   int using_case;
5123   int i;
5124
5125   printf ("static int\n");
5126   printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
5127           unit->name, name);
5128   printf ("     rtx executing_insn;\n");
5129   printf ("     rtx candidate_insn;\n");
5130   printf ("{\n");
5131   printf ("  rtx insn;\n");
5132   printf ("  int casenum;\n\n");
5133   printf ("  insn = executing_insn;\n");
5134   printf ("  switch (recog_memoized (insn))\n");
5135   printf ("    {\n");
5136
5137   /* Write the `switch' statement to get the case value.  */
5138   str = (char *) alloca (strlen (unit->name) + strlen (name) + strlen (connection) + 10);
5139   sprintf (str, "*%s_cases", unit->name);
5140   case_attr = find_attr (str, 0);
5141   if (! case_attr) abort ();
5142   common_av = find_most_used (case_attr);
5143
5144   for (av = case_attr->first_value; av; av = av->next)
5145     if (av != common_av)
5146       write_attr_case (case_attr, av, 1,
5147                        "casenum =", ";", 4, unit->condexp);
5148
5149   write_attr_case (case_attr, common_av, 0,
5150                    "casenum =", ";", 4, unit->condexp);
5151   printf ("    }\n\n");
5152
5153   /* Now write an outer switch statement on each case.  Then write
5154      the tests on the executing function within each.  */
5155   printf ("  insn = candidate_insn;\n");
5156   printf ("  switch (casenum)\n");
5157   printf ("    {\n");
5158
5159   for (i = 0; i < unit->num_opclasses; i++)
5160     {
5161       /* Ensure using this case.  */
5162       using_case = 0;
5163       for (av = case_attr->first_value; av; av = av->next)
5164         if (av->num_insns
5165             && contained_in_p (make_numeric_value (i), av->value))
5166           using_case = 1;
5167
5168       if (! using_case)
5169         continue;
5170
5171       printf ("    case %d:\n", i);
5172       sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5173       attr = find_attr (str, 0);
5174       if (! attr) abort ();
5175
5176       /* If single value, just write it.  */
5177       value = find_single_value (attr);
5178       if (value)
5179         write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5180       else
5181         {
5182           common_av = find_most_used (attr);
5183           printf ("      switch (recog_memoized (insn))\n");
5184           printf ("\t{\n");
5185
5186           for (av = attr->first_value; av; av = av->next)
5187             if (av != common_av)
5188               write_attr_case (attr, av, 1,
5189                                "return", ";", 8, unit->condexp);
5190
5191           write_attr_case (attr, common_av, 0,
5192                            "return", ";", 8, unit->condexp);
5193           printf ("      }\n\n");
5194         }
5195     }
5196
5197   printf ("    }\n}\n\n");
5198 }
5199 \f
5200 /* This page contains miscellaneous utility routines.  */
5201
5202 /* Given a string, return the number of comma-separated elements in it.
5203    Return 0 for the null string.  */
5204
5205 static int
5206 n_comma_elts (s)
5207      char *s;
5208 {
5209   int n;
5210
5211   if (*s == '\0')
5212     return 0;
5213
5214   for (n = 1; *s; s++)
5215     if (*s == ',')
5216       n++;
5217
5218   return n;
5219 }
5220
5221 /* Given a pointer to a (char *), return a malloc'ed string containing the
5222    next comma-separated element.  Advance the pointer to after the string
5223    scanned, or the end-of-string.  Return NULL if at end of string.  */
5224
5225 static char *
5226 next_comma_elt (pstr)
5227      char **pstr;
5228 {
5229   char *out_str;
5230   char *p;
5231
5232   if (**pstr == '\0')
5233     return NULL;
5234
5235   /* Find end of string to compute length.  */
5236   for (p = *pstr; *p != ',' && *p != '\0'; p++)
5237     ;
5238
5239   out_str = attr_string (*pstr, p - *pstr);
5240   *pstr = p;
5241
5242   if (**pstr == ',')
5243     (*pstr)++;
5244
5245   return out_str;
5246 }
5247
5248 /* Return a `struct attr_desc' pointer for a given named attribute.  If CREATE
5249    is non-zero, build a new attribute, if one does not exist.  */
5250
5251 static struct attr_desc *
5252 find_attr (name, create)
5253      char *name;
5254      int create;
5255 {
5256   struct attr_desc *attr;
5257   int index;
5258
5259   /* Before we resort to using `strcmp', see if the string address matches
5260      anywhere.  In most cases, it should have been canonicalized to do so.  */
5261   if (name == alternative_name)
5262     return NULL;
5263
5264   index = name[0] & (MAX_ATTRS_INDEX - 1);
5265   for (attr = attrs[index]; attr; attr = attr->next)
5266     if (name == attr->name)
5267       return attr;
5268
5269   /* Otherwise, do it the slow way.  */
5270   for (attr = attrs[index]; attr; attr = attr->next)
5271     if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5272       return attr;
5273
5274   if (! create)
5275     return NULL;
5276
5277   attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5278   attr->name = attr_string (name, strlen (name));
5279   attr->first_value = attr->default_val = NULL;
5280   attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5281   attr->next = attrs[index];
5282   attrs[index] = attr;
5283
5284   return attr;
5285 }
5286
5287 /* Create internal attribute with the given default value.  */
5288
5289 static void
5290 make_internal_attr (name, value, special)
5291      char *name;
5292      rtx value;
5293      int special;
5294 {
5295   struct attr_desc *attr;
5296
5297   attr = find_attr (name, 1);
5298   if (attr->default_val)
5299     abort ();
5300
5301   attr->is_numeric = 1;
5302   attr->is_const = 0;
5303   attr->is_special = (special & 1) != 0;
5304   attr->negative_ok = (special & 2) != 0;
5305   attr->unsigned_p = (special & 4) != 0;
5306   attr->default_val = get_attr_value (value, attr, -2);
5307 }
5308
5309 /* Find the most used value of an attribute.  */
5310
5311 static struct attr_value *
5312 find_most_used (attr)
5313      struct attr_desc *attr;
5314 {
5315   struct attr_value *av;
5316   struct attr_value *most_used;
5317   int nuses;
5318
5319   most_used = NULL;
5320   nuses = -1;
5321
5322   for (av = attr->first_value; av; av = av->next)
5323     if (av->num_insns > nuses)
5324       nuses = av->num_insns, most_used = av;
5325
5326   return most_used;
5327 }
5328
5329 /* If an attribute only has a single value used, return it.  Otherwise
5330    return NULL.  */
5331
5332 static rtx
5333 find_single_value (attr)
5334      struct attr_desc *attr;
5335 {
5336   struct attr_value *av;
5337   rtx unique_value;
5338
5339   unique_value = NULL;
5340   for (av = attr->first_value; av; av = av->next)
5341     if (av->num_insns)
5342       {
5343         if (unique_value)
5344           return NULL;
5345         else
5346           unique_value = av->value;
5347       }
5348
5349   return unique_value;
5350 }
5351
5352 /* Return (attr_value "n") */
5353
5354 static rtx
5355 make_numeric_value (n)
5356      int n;
5357 {
5358   static rtx int_values[20];
5359   rtx exp;
5360   char *p;
5361
5362   if (n < 0)
5363     abort ();
5364
5365   if (n < 20 && int_values[n])
5366     return int_values[n];
5367
5368   p = attr_printf (MAX_DIGITS, "%d", n);
5369   exp = attr_rtx (CONST_STRING, p);
5370
5371   if (n < 20)
5372     int_values[n] = exp;
5373
5374   return exp;
5375 }
5376 \f
5377 static void
5378 extend_range (range, min, max)
5379      struct range *range;
5380      int min;
5381      int max;
5382 {
5383   if (range->min > min) range->min = min;
5384   if (range->max < max) range->max = max;
5385 }
5386
5387 char *
5388 xrealloc (ptr, size)
5389      char *ptr;
5390      unsigned size;
5391 {
5392   char *result = (char *) realloc (ptr, size);
5393   if (!result)
5394     fatal ("virtual memory exhausted");
5395   return result;
5396 }
5397
5398 char *
5399 xmalloc (size)
5400      unsigned size;
5401 {
5402   register char *val = (char *) malloc (size);
5403
5404   if (val == 0)
5405     fatal ("virtual memory exhausted");
5406   return val;
5407 }
5408
5409 static rtx
5410 copy_rtx_unchanging (orig)
5411      register rtx orig;
5412 {
5413 #if 0
5414   register rtx copy;
5415   register RTX_CODE code;
5416 #endif
5417
5418   if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
5419     return orig;
5420
5421   MEM_IN_STRUCT_P (orig) = 1;
5422   return orig;
5423
5424 #if 0
5425   code = GET_CODE (orig);
5426   switch (code)
5427     {
5428     case CONST_INT:
5429     case CONST_DOUBLE:
5430     case SYMBOL_REF:
5431     case CODE_LABEL:
5432       return orig;
5433     }
5434
5435   copy = rtx_alloc (code);
5436   PUT_MODE (copy, GET_MODE (orig));
5437   RTX_UNCHANGING_P (copy) = 1;
5438   
5439   bcopy (&XEXP (orig, 0), &XEXP (copy, 0),
5440          GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
5441   return copy;
5442 #endif
5443 }
5444
5445 static void
5446 fatal (s, a1, a2)
5447      char *s;
5448 {
5449   fprintf (stderr, "genattrtab: ");
5450   fprintf (stderr, s, a1, a2);
5451   fprintf (stderr, "\n");
5452   exit (FATAL_EXIT_CODE);
5453 }
5454
5455 /* More 'friendly' abort that prints the line and file.
5456    config.h can #define abort fancy_abort if you like that sort of thing.  */
5457
5458 void
5459 fancy_abort ()
5460 {
5461   fatal ("Internal gcc abort.");
5462 }
5463
5464 /* Determine if an insn has a constant number of delay slots, i.e., the
5465    number of delay slots is not a function of the length of the insn.  */
5466
5467 void
5468 write_const_num_delay_slots ()
5469 {
5470   struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
5471   struct attr_value *av;
5472   struct insn_ent *ie;
5473   int i;
5474
5475   if (attr)
5476     {
5477       printf ("int\nconst_num_delay_slots (insn)\n");
5478       printf ("     rtx insn;\n");
5479       printf ("{\n");
5480       printf ("  switch (recog_memoized (insn))\n");
5481       printf ("    {\n");
5482
5483       for (av = attr->first_value; av; av = av->next)
5484         {
5485           length_used = 0;
5486           walk_attr_value (av->value);
5487           if (length_used)
5488             {
5489               for (ie = av->first_insn; ie; ie = ie->next)
5490               if (ie->insn_code != -1)
5491                 printf ("    case %d:\n", ie->insn_code);
5492               printf ("      return 0;\n");
5493             }
5494         }
5495
5496       printf ("    default:\n");
5497       printf ("      return 1;\n");
5498       printf ("    }\n}\n");
5499     }
5500 }
5501
5502 \f
5503 int
5504 main (argc, argv)
5505      int argc;
5506      char **argv;
5507 {
5508   rtx desc;
5509   FILE *infile;
5510   register int c;
5511   struct attr_desc *attr;
5512   struct insn_def *id;
5513   rtx tem;
5514   int i;
5515
5516 #ifdef RLIMIT_STACK
5517   /* Get rid of any avoidable limit on stack size.  */
5518   {
5519     struct rlimit rlim;
5520
5521     /* Set the stack limit huge so that alloca does not fail. */
5522     getrlimit (RLIMIT_STACK, &rlim);
5523     rlim.rlim_cur = rlim.rlim_max;
5524     setrlimit (RLIMIT_STACK, &rlim);
5525   }
5526 #endif /* RLIMIT_STACK defined */
5527
5528   obstack_init (rtl_obstack);
5529   obstack_init (hash_obstack);
5530   obstack_init (temp_obstack);
5531
5532   if (argc <= 1)
5533     fatal ("No input file name.");
5534
5535   infile = fopen (argv[1], "r");
5536   if (infile == 0)
5537     {
5538       perror (argv[1]);
5539       exit (FATAL_EXIT_CODE);
5540     }
5541
5542   init_rtl ();
5543
5544   /* Set up true and false rtx's */
5545   true_rtx = rtx_alloc (CONST_INT);
5546   XWINT (true_rtx, 0) = 1;
5547   false_rtx = rtx_alloc (CONST_INT);
5548   XWINT (false_rtx, 0) = 0;
5549   RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
5550   RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
5551
5552   alternative_name = attr_string ("alternative", strlen ("alternative"));
5553
5554   printf ("/* Generated automatically by the program `genattrtab'\n\
5555 from the machine description file `md'.  */\n\n");
5556
5557   /* Read the machine description.  */
5558
5559   while (1)
5560     {
5561       c = read_skip_spaces (infile);
5562       if (c == EOF)
5563         break;
5564       ungetc (c, infile);
5565
5566       desc = read_rtx (infile);
5567       if (GET_CODE (desc) == DEFINE_INSN
5568           || GET_CODE (desc) == DEFINE_PEEPHOLE
5569           || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
5570         gen_insn (desc);
5571
5572       else if (GET_CODE (desc) == DEFINE_EXPAND)
5573         insn_code_number++, insn_index_number++;
5574
5575       else if (GET_CODE (desc) == DEFINE_SPLIT)
5576         insn_code_number++, insn_index_number++;
5577
5578       else if (GET_CODE (desc) == DEFINE_ATTR)
5579         {
5580           gen_attr (desc);
5581           insn_index_number++;
5582         }
5583
5584       else if (GET_CODE (desc) == DEFINE_DELAY)
5585         {
5586           gen_delay (desc);
5587           insn_index_number++;
5588         }
5589
5590       else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
5591         {
5592           gen_unit (desc);
5593           insn_index_number++;
5594         }
5595     }
5596
5597   /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
5598   if (! got_define_asm_attributes)
5599     {
5600       tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5601       XVEC (tem, 0) = rtvec_alloc (0);
5602       gen_insn (tem);
5603     }
5604
5605   /* Expand DEFINE_DELAY information into new attribute.  */
5606   if (num_delays)
5607     expand_delays ();
5608
5609   /* Expand DEFINE_FUNCTION_UNIT information into new attributes.  */
5610   if (num_units)
5611     expand_units ();
5612
5613   printf ("#include \"config.h\"\n");
5614   printf ("#include \"rtl.h\"\n");
5615   printf ("#include \"insn-config.h\"\n");
5616   printf ("#include \"recog.h\"\n");
5617   printf ("#include \"regs.h\"\n");
5618   printf ("#include \"real.h\"\n");
5619   printf ("#include \"output.h\"\n");
5620   printf ("#include \"insn-attr.h\"\n");
5621   printf ("\n");  
5622   printf ("#define operands recog_operand\n\n");
5623
5624   /* Make `insn_alternatives'.  */
5625   insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
5626   for (id = defs; id; id = id->next)
5627     if (id->insn_code >= 0)
5628       insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
5629
5630   /* Make `insn_n_alternatives'.  */
5631   insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
5632   for (id = defs; id; id = id->next)
5633     if (id->insn_code >= 0)
5634       insn_n_alternatives[id->insn_code] = id->num_alternatives;
5635
5636   /* Prepare to write out attribute subroutines by checking everything stored
5637      away and building the attribute cases.  */
5638
5639   check_defs ();
5640   for (i = 0; i < MAX_ATTRS_INDEX; i++)
5641     for (attr = attrs[i]; attr; attr = attr->next)
5642       {
5643         attr->default_val->value
5644           = check_attr_value (attr->default_val->value, attr);
5645         fill_attr (attr);
5646       }
5647
5648   /* Construct extra attributes for `length'.  */
5649   make_length_attrs ();
5650
5651   /* Perform any possible optimizations to speed up compilation. */
5652   optimize_attrs ();
5653
5654   /* Now write out all the `gen_attr_...' routines.  Do these before the
5655      special routines (specifically before write_function_unit_info), so
5656      that they get defined before they are used.  */
5657
5658   for (i = 0; i < MAX_ATTRS_INDEX; i++)
5659     for (attr = attrs[i]; attr; attr = attr->next)
5660       {
5661         if (! attr->is_special)
5662           write_attr_get (attr);
5663       }
5664
5665   /* Write out delay eligibility information, if DEFINE_DELAY present.
5666      (The function to compute the number of delay slots will be written
5667      below.)  */
5668   if (num_delays)
5669     {
5670       write_eligible_delay ("delay");
5671       if (have_annul_true)
5672         write_eligible_delay ("annul_true");
5673       if (have_annul_false)
5674         write_eligible_delay ("annul_false");
5675     }
5676
5677   /* Write out information about function units.  */
5678   if (num_units)
5679     write_function_unit_info ();
5680
5681   /* Write out constant delay slot info */
5682   write_const_num_delay_slots ();
5683
5684   fflush (stdout);
5685   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
5686   /* NOTREACHED */
5687   return 0;
5688 }