OSDN Git Service

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