OSDN Git Service

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