OSDN Git Service

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