OSDN Git Service

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