OSDN Git Service

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