OSDN Git Service

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