OSDN Git Service

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