OSDN Git Service

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