OSDN Git Service

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