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