OSDN Git Service

include/:
[pf3gnuchains/gcc-fork.git] / gcc / genattrtab.c
1 /* Generate code from machine description to compute values of attributes.
2    Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3    2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4    Free Software Foundation, Inc.
5    Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6
7 This file is part of GCC.
8
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
13
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
17 for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3.  If not see
21 <http://www.gnu.org/licenses/>.  */
22
23 /* This program handles insn attributes and the DEFINE_DELAY and
24    DEFINE_INSN_RESERVATION definitions.
25
26    It produces a series of functions named `get_attr_...', one for each insn
27    attribute.  Each of these is given the rtx for an insn and returns a member
28    of the enum for the attribute.
29
30    These subroutines have the form of a `switch' on the INSN_CODE (via
31    `recog_memoized').  Each case either returns a constant attribute value
32    or a value that depends on tests on other attributes, the form of
33    operands, or some random C expression (encoded with a SYMBOL_REF
34    expression).
35
36    If the attribute `alternative', or a random C expression is present,
37    `constrain_operands' is called.  If either of these cases of a reference to
38    an operand is found, `extract_insn' is called.
39
40    The special attribute `length' is also recognized.  For this operand,
41    expressions involving the address of an operand or the current insn,
42    (address (pc)), are valid.  In this case, an initial pass is made to
43    set all lengths that do not depend on address.  Those that do are set to
44    the maximum length.  Then each insn that depends on an address is checked
45    and possibly has its length changed.  The process repeats until no further
46    changed are made.  The resulting lengths are saved for use by
47    `get_attr_length'.
48
49    A special form of DEFINE_ATTR, where the expression for default value is a
50    CONST expression, indicates an attribute that is constant for a given run
51    of the compiler.  The subroutine generated for these attributes has no
52    parameters as it does not depend on any particular insn.  Constant
53    attributes are typically used to specify which variety of processor is
54    used.
55
56    Internal attributes are defined to handle DEFINE_DELAY and
57    DEFINE_INSN_RESERVATION.  Special routines are output for these cases.
58
59    This program works by keeping a list of possible values for each attribute.
60    These include the basic attribute choices, default values for attribute, and
61    all derived quantities.
62
63    As the description file is read, the definition for each insn is saved in a
64    `struct insn_def'.   When the file reading is complete, a `struct insn_ent'
65    is created for each insn and chained to the corresponding attribute value,
66    either that specified, or the default.
67
68    An optimization phase is then run.  This simplifies expressions for each
69    insn.  EQ_ATTR tests are resolved, whenever possible, to a test that
70    indicates when the attribute has the specified value for the insn.  This
71    avoids recursive calls during compilation.
72
73    The strategy used when processing DEFINE_DELAY definitions is to create
74    arbitrarily complex expressions and have the 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' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89       independent of the insn code.
90    `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91       for the insn code currently being processed (see optimize_attrs).
92    `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
93       (see attr_rtx).  */
94
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
98
99 #if 0
100 #define strcmp_check(S1, S2) ((S1) == (S2)              \
101                               ? 0                       \
102                               : (gcc_assert (strcmp ((S1), (S2))), 1))
103 #else
104 #define strcmp_check(S1, S2) ((S1) != (S2))
105 #endif
106
107 #include "bconfig.h"
108 #include "system.h"
109 #include "coretypes.h"
110 #include "tm.h"
111 #include "rtl.h"
112 #include "gensupport.h"
113 #include "obstack.h"
114 #include "errors.h"
115
116 /* Flags for make_internal_attr's `special' parameter.  */
117 #define ATTR_NONE               0
118 #define ATTR_SPECIAL            (1 << 0)
119
120 static struct obstack obstack1, obstack2;
121 static struct obstack *hash_obstack = &obstack1;
122 static struct obstack *temp_obstack = &obstack2;
123
124 /* enough space to reserve for printing out ints */
125 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
126
127 /* Define structures used to record attributes and values.  */
128
129 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
130    encountered, we store all the relevant information into a
131    `struct insn_def'.  This is done to allow attribute definitions to occur
132    anywhere in the file.  */
133
134 struct insn_def
135 {
136   struct insn_def *next;        /* Next insn in chain.  */
137   rtx def;                      /* The DEFINE_...  */
138   int insn_code;                /* Instruction number.  */
139   int insn_index;               /* Expression number in file, for errors.  */
140   int lineno;                   /* Line number.  */
141   int num_alternatives;         /* Number of alternatives.  */
142   int vec_idx;                  /* Index of attribute vector in `def'.  */
143 };
144
145 /* Once everything has been read in, we store in each attribute value a list
146    of insn codes that have that value.  Here is the structure used for the
147    list.  */
148
149 struct insn_ent
150 {
151   struct insn_ent *next;        /* Next in chain.  */
152   struct insn_def *def;         /* Instruction definition.  */
153 };
154
155 /* Each value of an attribute (either constant or computed) is assigned a
156    structure which is used as the listhead of the insns that have that
157    value.  */
158
159 struct attr_value
160 {
161   rtx value;                    /* Value of attribute.  */
162   struct attr_value *next;      /* Next attribute value in chain.  */
163   struct insn_ent *first_insn;  /* First insn with this value.  */
164   int num_insns;                /* Number of insns with this value.  */
165   int has_asm_insn;             /* True if this value used for `asm' insns */
166 };
167
168 /* Structure for each attribute.  */
169
170 struct attr_desc
171 {
172   char *name;                   /* Name of attribute.  */
173   struct attr_desc *next;       /* Next attribute.  */
174   struct attr_value *first_value; /* First value of this attribute.  */
175   struct attr_value *default_val; /* Default value for this attribute.  */
176   int lineno : 24;              /* Line number.  */
177   unsigned is_numeric   : 1;    /* Values of this attribute are numeric.  */
178   unsigned is_const     : 1;    /* Attribute value constant for each run.  */
179   unsigned is_special   : 1;    /* Don't call `write_attr_set'.  */
180 };
181
182 /* Structure for each DEFINE_DELAY.  */
183
184 struct delay_desc
185 {
186   rtx def;                      /* DEFINE_DELAY expression.  */
187   struct delay_desc *next;      /* Next DEFINE_DELAY.  */
188   int num;                      /* Number of DEFINE_DELAY, starting at 1.  */
189   int lineno;                   /* Line number.  */
190 };
191
192 struct attr_value_list
193 {
194   struct attr_value *av;
195   struct insn_ent *ie;
196   struct attr_desc *attr;
197   struct attr_value_list *next;
198 };
199
200 /* Listheads of above structures.  */
201
202 /* This one is indexed by the first character of the attribute name.  */
203 #define MAX_ATTRS_INDEX 256
204 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
205 static struct insn_def *defs;
206 static struct delay_desc *delays;
207 struct attr_value_list **insn_code_values;
208
209 /* Other variables.  */
210
211 static int insn_code_number;
212 static int insn_index_number;
213 static int got_define_asm_attributes;
214 static int must_extract;
215 static int must_constrain;
216 static int address_used;
217 static int length_used;
218 static int num_delays;
219 static int have_annul_true, have_annul_false;
220 static int num_insn_ents;
221
222 /* Stores, for each insn code, the number of constraint alternatives.  */
223
224 static int *insn_n_alternatives;
225
226 /* Stores, for each insn code, a bitmap that has bits on for each possible
227    alternative.  */
228
229 static int *insn_alternatives;
230
231 /* Used to simplify expressions.  */
232
233 static rtx true_rtx, false_rtx;
234
235 /* Used to reduce calls to `strcmp' */
236
237 static const char *alternative_name;
238 static const char *length_str;
239 static const char *delay_type_str;
240 static const char *delay_1_0_str;
241 static const char *num_delay_slots_str;
242
243 /* Simplify an expression.  Only call the routine if there is something to
244    simplify.  */
245 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)     \
246   (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP)  \
247    : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
248
249 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
250
251 /* Forward declarations of functions used before their definitions, only.  */
252 static char *attr_string           (const char *, int);
253 static char *attr_printf           (unsigned int, const char *, ...)
254   ATTRIBUTE_PRINTF_2;
255 static rtx make_numeric_value      (int);
256 static struct attr_desc *find_attr (const char **, int);
257 static rtx mk_attr_alt             (int);
258 static char *next_comma_elt        (const char **);
259 static rtx insert_right_side       (enum rtx_code, rtx, rtx, int, int);
260 static rtx copy_boolean            (rtx);
261 static int compares_alternatives_p (rtx);
262 static void make_internal_attr     (const char *, rtx, int);
263 static void insert_insn_ent        (struct attr_value *, struct insn_ent *);
264 static void walk_attr_value        (rtx);
265 static int max_attr_value          (rtx, int*);
266 static int min_attr_value          (rtx, int*);
267 static int or_attr_value           (rtx, int*);
268 static rtx simplify_test_exp       (rtx, int, int);
269 static rtx simplify_test_exp_in_temp (rtx, int, int);
270 static rtx copy_rtx_unchanging     (rtx);
271 static bool attr_alt_subset_p      (rtx, rtx);
272 static bool attr_alt_subset_of_compl_p (rtx, rtx);
273 static void clear_struct_flag      (rtx);
274 static void write_attr_valueq      (struct attr_desc *, const char *);
275 static struct attr_value *find_most_used  (struct attr_desc *);
276 static void write_attr_set         (struct attr_desc *, int, rtx,
277                                     const char *, const char *, rtx,
278                                     int, int);
279 static void write_attr_case        (struct attr_desc *, struct attr_value *,
280                                     int, const char *, const char *, int, rtx);
281 static void write_attr_value       (struct attr_desc *, rtx);
282 static void write_upcase           (const char *);
283 static void write_indent           (int);
284 static rtx identity_fn             (rtx);
285 static rtx zero_fn                 (rtx);
286 static rtx one_fn                  (rtx);
287 static rtx max_fn                  (rtx);
288 static rtx min_fn                  (rtx);
289
290 #define oballoc(T) XOBNEW (hash_obstack, T)
291 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
292
293 /* Hash table for sharing RTL and strings.  */
294
295 /* Each hash table slot is a bucket containing a chain of these structures.
296    Strings are given negative hash codes; RTL expressions are given positive
297    hash codes.  */
298
299 struct attr_hash
300 {
301   struct attr_hash *next;       /* Next structure in the bucket.  */
302   int hashcode;                 /* Hash code of this rtx or string.  */
303   union
304     {
305       char *str;                /* The string (negative hash codes) */
306       rtx rtl;                  /* or the RTL recorded here.  */
307     } u;
308 };
309
310 /* Now here is the hash table.  When recording an RTL, it is added to
311    the slot whose index is the hash code mod the table size.  Note
312    that the hash table is used for several kinds of RTL (see attr_rtx)
313    and for strings.  While all these live in the same table, they are
314    completely independent, and the hash code is computed differently
315    for each.  */
316
317 #define RTL_HASH_SIZE 4093
318 static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
319
320 /* Here is how primitive or already-shared RTL's hash
321    codes are made.  */
322 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
323
324 /* Add an entry to the hash table for RTL with hash code HASHCODE.  */
325
326 static void
327 attr_hash_add_rtx (int hashcode, rtx rtl)
328 {
329   struct attr_hash *h;
330
331   h = XOBNEW (hash_obstack, struct attr_hash);
332   h->hashcode = hashcode;
333   h->u.rtl = rtl;
334   h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
335   attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
336 }
337
338 /* Add an entry to the hash table for STRING with hash code HASHCODE.  */
339
340 static void
341 attr_hash_add_string (int hashcode, char *str)
342 {
343   struct attr_hash *h;
344
345   h = XOBNEW (hash_obstack, struct attr_hash);
346   h->hashcode = -hashcode;
347   h->u.str = str;
348   h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
349   attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
350 }
351
352 /* Generate an RTL expression, but avoid duplicates.
353    Set the ATTR_PERMANENT_P flag for these permanent objects.
354
355    In some cases we cannot uniquify; then we return an ordinary
356    impermanent rtx with ATTR_PERMANENT_P clear.
357
358    Args are as follows:
359
360    rtx attr_rtx (code, [element1, ..., elementn])  */
361
362 static rtx
363 attr_rtx_1 (enum rtx_code code, va_list p)
364 {
365   rtx rt_val = NULL_RTX;/* RTX to return to caller...           */
366   int hashcode;
367   struct attr_hash *h;
368   struct obstack *old_obstack = rtl_obstack;
369
370   /* For each of several cases, search the hash table for an existing entry.
371      Use that entry if one is found; otherwise create a new RTL and add it
372      to the table.  */
373
374   if (GET_RTX_CLASS (code) == RTX_UNARY)
375     {
376       rtx arg0 = va_arg (p, rtx);
377
378       /* A permanent object cannot point to impermanent ones.  */
379       if (! ATTR_PERMANENT_P (arg0))
380         {
381           rt_val = rtx_alloc (code);
382           XEXP (rt_val, 0) = arg0;
383           return rt_val;
384         }
385
386       hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
387       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
388         if (h->hashcode == hashcode
389             && GET_CODE (h->u.rtl) == code
390             && XEXP (h->u.rtl, 0) == arg0)
391           return h->u.rtl;
392
393       if (h == 0)
394         {
395           rtl_obstack = hash_obstack;
396           rt_val = rtx_alloc (code);
397           XEXP (rt_val, 0) = arg0;
398         }
399     }
400   else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
401            || GET_RTX_CLASS (code) == RTX_COMM_ARITH
402            || GET_RTX_CLASS (code) == RTX_COMPARE
403            || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
404     {
405       rtx arg0 = va_arg (p, rtx);
406       rtx arg1 = va_arg (p, rtx);
407
408       /* A permanent object cannot point to impermanent ones.  */
409       if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
410         {
411           rt_val = rtx_alloc (code);
412           XEXP (rt_val, 0) = arg0;
413           XEXP (rt_val, 1) = arg1;
414           return rt_val;
415         }
416
417       hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
418       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
419         if (h->hashcode == hashcode
420             && GET_CODE (h->u.rtl) == code
421             && XEXP (h->u.rtl, 0) == arg0
422             && XEXP (h->u.rtl, 1) == arg1)
423           return h->u.rtl;
424
425       if (h == 0)
426         {
427           rtl_obstack = hash_obstack;
428           rt_val = rtx_alloc (code);
429           XEXP (rt_val, 0) = arg0;
430           XEXP (rt_val, 1) = arg1;
431         }
432     }
433   else if (GET_RTX_LENGTH (code) == 1
434            && GET_RTX_FORMAT (code)[0] == 's')
435     {
436       char *arg0 = va_arg (p, char *);
437
438       arg0 = DEF_ATTR_STRING (arg0);
439
440       hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
441       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
442         if (h->hashcode == hashcode
443             && GET_CODE (h->u.rtl) == code
444             && XSTR (h->u.rtl, 0) == arg0)
445           return h->u.rtl;
446
447       if (h == 0)
448         {
449           rtl_obstack = hash_obstack;
450           rt_val = rtx_alloc (code);
451           XSTR (rt_val, 0) = arg0;
452         }
453     }
454   else if (GET_RTX_LENGTH (code) == 2
455            && GET_RTX_FORMAT (code)[0] == 's'
456            && GET_RTX_FORMAT (code)[1] == 's')
457     {
458       char *arg0 = va_arg (p, char *);
459       char *arg1 = va_arg (p, char *);
460
461       hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
462       for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
463         if (h->hashcode == hashcode
464             && GET_CODE (h->u.rtl) == code
465             && XSTR (h->u.rtl, 0) == arg0
466             && XSTR (h->u.rtl, 1) == arg1)
467           return h->u.rtl;
468
469       if (h == 0)
470         {
471           rtl_obstack = hash_obstack;
472           rt_val = rtx_alloc (code);
473           XSTR (rt_val, 0) = arg0;
474           XSTR (rt_val, 1) = arg1;
475         }
476     }
477   else if (code == CONST_INT)
478     {
479       HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
480       if (arg0 == 0)
481         return false_rtx;
482       else if (arg0 == 1)
483         return true_rtx;
484       else
485         goto nohash;
486     }
487   else
488     {
489       int i;            /* Array indices...                     */
490       const char *fmt;  /* Current rtx's format...              */
491     nohash:
492       rt_val = rtx_alloc (code);        /* Allocate the storage space.  */
493
494       fmt = GET_RTX_FORMAT (code);      /* Find the right format...  */
495       for (i = 0; i < GET_RTX_LENGTH (code); i++)
496         {
497           switch (*fmt++)
498             {
499             case '0':           /* Unused field.  */
500               break;
501
502             case 'i':           /* An integer?  */
503               XINT (rt_val, i) = va_arg (p, int);
504               break;
505
506             case 'w':           /* A wide integer? */
507               XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
508               break;
509
510             case 's':           /* A string?  */
511               XSTR (rt_val, i) = va_arg (p, char *);
512               break;
513
514             case 'e':           /* An expression?  */
515             case 'u':           /* An insn?  Same except when printing.  */
516               XEXP (rt_val, i) = va_arg (p, rtx);
517               break;
518
519             case 'E':           /* An RTX vector?  */
520               XVEC (rt_val, i) = va_arg (p, rtvec);
521               break;
522
523             default:
524               gcc_unreachable ();
525             }
526         }
527       return rt_val;
528     }
529
530   rtl_obstack = old_obstack;
531   attr_hash_add_rtx (hashcode, rt_val);
532   ATTR_PERMANENT_P (rt_val) = 1;
533   return rt_val;
534 }
535
536 static rtx
537 attr_rtx (enum rtx_code code, ...)
538 {
539   rtx result;
540   va_list p;
541
542   va_start (p, code);
543   result = attr_rtx_1 (code, p);
544   va_end (p);
545   return result;
546 }
547
548 /* Create a new string printed with the printf line arguments into a space
549    of at most LEN bytes:
550
551    rtx attr_printf (len, format, [arg1, ..., argn])  */
552
553 static char *
554 attr_printf (unsigned int len, const char *fmt, ...)
555 {
556   char str[256];
557   va_list p;
558
559   va_start (p, fmt);
560
561   gcc_assert (len < sizeof str); /* Leave room for \0.  */
562
563   vsprintf (str, fmt, p);
564   va_end (p);
565
566   return DEF_ATTR_STRING (str);
567 }
568
569 static rtx
570 attr_eq (const char *name, const char *value)
571 {
572   return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
573 }
574
575 static const char *
576 attr_numeral (int n)
577 {
578   return XSTR (make_numeric_value (n), 0);
579 }
580
581 /* Return a permanent (possibly shared) copy of a string STR (not assumed
582    to be null terminated) with LEN bytes.  */
583
584 static char *
585 attr_string (const char *str, int len)
586 {
587   struct attr_hash *h;
588   int hashcode;
589   int i;
590   char *new_str;
591
592   /* Compute the hash code.  */
593   hashcode = (len + 1) * 613 + (unsigned) str[0];
594   for (i = 1; i < len; i += 2)
595     hashcode = ((hashcode * 613) + (unsigned) str[i]);
596   if (hashcode < 0)
597     hashcode = -hashcode;
598
599   /* Search the table for the string.  */
600   for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
601     if (h->hashcode == -hashcode && h->u.str[0] == str[0]
602         && !strncmp (h->u.str, str, len))
603       return h->u.str;                  /* <-- return if found.  */
604
605   /* Not found; create a permanent copy and add it to the hash table.  */
606   new_str = XOBNEWVAR (hash_obstack, char, len + 1);
607   memcpy (new_str, str, len);
608   new_str[len] = '\0';
609   attr_hash_add_string (hashcode, new_str);
610
611   return new_str;                       /* Return the new string.  */
612 }
613
614 /* Check two rtx's for equality of contents,
615    taking advantage of the fact that if both are hashed
616    then they can't be equal unless they are the same object.  */
617
618 static int
619 attr_equal_p (rtx x, rtx y)
620 {
621   return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
622                      && rtx_equal_p (x, y)));
623 }
624
625 /* Copy an attribute value expression,
626    descending to all depths, but not copying any
627    permanent hashed subexpressions.  */
628
629 static rtx
630 attr_copy_rtx (rtx orig)
631 {
632   rtx copy;
633   int i, j;
634   RTX_CODE code;
635   const char *format_ptr;
636
637   /* No need to copy a permanent object.  */
638   if (ATTR_PERMANENT_P (orig))
639     return orig;
640
641   code = GET_CODE (orig);
642
643   switch (code)
644     {
645     case REG:
646     case CONST_INT:
647     case CONST_DOUBLE:
648     case CONST_VECTOR:
649     case SYMBOL_REF:
650     case CODE_LABEL:
651     case PC:
652     case CC0:
653       return orig;
654
655     default:
656       break;
657     }
658
659   copy = rtx_alloc (code);
660   PUT_MODE (copy, GET_MODE (orig));
661   ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
662   ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
663   ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
664
665   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
666
667   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
668     {
669       switch (*format_ptr++)
670         {
671         case 'e':
672           XEXP (copy, i) = XEXP (orig, i);
673           if (XEXP (orig, i) != NULL)
674             XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
675           break;
676
677         case 'E':
678         case 'V':
679           XVEC (copy, i) = XVEC (orig, i);
680           if (XVEC (orig, i) != NULL)
681             {
682               XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
683               for (j = 0; j < XVECLEN (copy, i); j++)
684                 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
685             }
686           break;
687
688         case 'n':
689         case 'i':
690           XINT (copy, i) = XINT (orig, i);
691           break;
692
693         case 'w':
694           XWINT (copy, i) = XWINT (orig, i);
695           break;
696
697         case 's':
698         case 'S':
699           XSTR (copy, i) = XSTR (orig, i);
700           break;
701
702         default:
703           gcc_unreachable ();
704         }
705     }
706   return copy;
707 }
708
709 /* Given a test expression for an attribute, ensure it is validly formed.
710    IS_CONST indicates whether the expression is constant for each compiler
711    run (a constant expression may not test any particular insn).
712
713    Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
714    and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")).  Do the latter
715    test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
716
717    Update the string address in EQ_ATTR expression to be the same used
718    in the attribute (or `alternative_name') to speed up subsequent
719    `find_attr' calls and eliminate most `strcmp' calls.
720
721    Return the new expression, if any.  */
722
723 static rtx
724 check_attr_test (rtx exp, int is_const, int lineno)
725 {
726   struct attr_desc *attr;
727   struct attr_value *av;
728   const char *name_ptr, *p;
729   rtx orexp, newexp;
730
731   switch (GET_CODE (exp))
732     {
733     case EQ_ATTR:
734       /* Handle negation test.  */
735       if (XSTR (exp, 1)[0] == '!')
736         return check_attr_test (attr_rtx (NOT,
737                                           attr_eq (XSTR (exp, 0),
738                                                    &XSTR (exp, 1)[1])),
739                                 is_const, lineno);
740
741       else if (n_comma_elts (XSTR (exp, 1)) == 1)
742         {
743           attr = find_attr (&XSTR (exp, 0), 0);
744           if (attr == NULL)
745             {
746               if (! strcmp (XSTR (exp, 0), "alternative"))
747                 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
748               else
749                 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
750             }
751
752           if (is_const && ! attr->is_const)
753             fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
754                    XSTR (exp, 0));
755
756           /* Copy this just to make it permanent,
757              so expressions using it can be permanent too.  */
758           exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
759
760           /* It shouldn't be possible to simplify the value given to a
761              constant attribute, so don't expand this until it's time to
762              write the test expression.  */
763           if (attr->is_const)
764             ATTR_IND_SIMPLIFIED_P (exp) = 1;
765
766           if (attr->is_numeric)
767             {
768               for (p = XSTR (exp, 1); *p; p++)
769                 if (! ISDIGIT (*p))
770                   fatal ("attribute `%s' takes only numeric values",
771                          XSTR (exp, 0));
772             }
773           else
774             {
775               for (av = attr->first_value; av; av = av->next)
776                 if (GET_CODE (av->value) == CONST_STRING
777                     && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
778                   break;
779
780               if (av == NULL)
781                 fatal ("unknown value `%s' for `%s' attribute",
782                        XSTR (exp, 1), XSTR (exp, 0));
783             }
784         }
785       else
786         {
787           if (! strcmp (XSTR (exp, 0), "alternative"))
788             {
789               int set = 0;
790
791               name_ptr = XSTR (exp, 1);
792               while ((p = next_comma_elt (&name_ptr)) != NULL)
793                 set |= 1 << atoi (p);
794
795               return mk_attr_alt (set);
796             }
797           else
798             {
799               /* Make an IOR tree of the possible values.  */
800               orexp = false_rtx;
801               name_ptr = XSTR (exp, 1);
802               while ((p = next_comma_elt (&name_ptr)) != NULL)
803                 {
804                   newexp = attr_eq (XSTR (exp, 0), p);
805                   orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
806                 }
807
808               return check_attr_test (orexp, is_const, lineno);
809             }
810         }
811       break;
812
813     case ATTR_FLAG:
814       break;
815
816     case CONST_INT:
817       /* Either TRUE or FALSE.  */
818       if (XWINT (exp, 0))
819         return true_rtx;
820       else
821         return false_rtx;
822
823     case IOR:
824     case AND:
825       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
826       XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
827       break;
828
829     case NOT:
830       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
831       break;
832
833     case MATCH_OPERAND:
834       if (is_const)
835         fatal ("RTL operator \"%s\" not valid in constant attribute test",
836                GET_RTX_NAME (GET_CODE (exp)));
837       /* These cases can't be simplified.  */
838       ATTR_IND_SIMPLIFIED_P (exp) = 1;
839       break;
840
841     case LE:  case LT:  case GT:  case GE:
842     case LEU: case LTU: case GTU: case GEU:
843     case NE:  case EQ:
844       if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
845           && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
846         exp = attr_rtx (GET_CODE (exp),
847                         attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
848                         attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
849       /* These cases can't be simplified.  */
850       ATTR_IND_SIMPLIFIED_P (exp) = 1;
851       break;
852
853     case SYMBOL_REF:
854       if (is_const)
855         {
856           /* These cases are valid for constant attributes, but can't be
857              simplified.  */
858           exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
859           ATTR_IND_SIMPLIFIED_P (exp) = 1;
860           break;
861         }
862     default:
863       fatal ("RTL operator \"%s\" not valid in attribute test",
864              GET_RTX_NAME (GET_CODE (exp)));
865     }
866
867   return exp;
868 }
869
870 /* Given an expression, ensure that it is validly formed and that all named
871    attribute values are valid for the given attribute.  Issue a fatal error
872    if not.  If no attribute is specified, assume a numeric attribute.
873
874    Return a perhaps modified replacement expression for the value.  */
875
876 static rtx
877 check_attr_value (rtx exp, struct attr_desc *attr)
878 {
879   struct attr_value *av;
880   const char *p;
881   int i;
882
883   switch (GET_CODE (exp))
884     {
885     case CONST_INT:
886       if (attr && ! attr->is_numeric)
887         {
888           message_with_line (attr->lineno,
889                              "CONST_INT not valid for non-numeric attribute %s",
890                              attr->name);
891           have_error = 1;
892           break;
893         }
894
895       if (INTVAL (exp) < 0)
896         {
897           message_with_line (attr->lineno,
898                              "negative numeric value specified for attribute %s",
899                              attr->name);
900           have_error = 1;
901           break;
902         }
903       break;
904
905     case CONST_STRING:
906       if (! strcmp (XSTR (exp, 0), "*"))
907         break;
908
909       if (attr == 0 || attr->is_numeric)
910         {
911           p = XSTR (exp, 0);
912           for (; *p; p++)
913             if (! ISDIGIT (*p))
914               {
915                 message_with_line (attr ? attr->lineno : 0,
916                                    "non-numeric value for numeric attribute %s",
917                                    attr ? attr->name : "internal");
918                 have_error = 1;
919                 break;
920               }
921           break;
922         }
923
924       for (av = attr->first_value; av; av = av->next)
925         if (GET_CODE (av->value) == CONST_STRING
926             && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
927           break;
928
929       if (av == NULL)
930         {
931           message_with_line (attr->lineno,
932                              "unknown value `%s' for `%s' attribute",
933                              XSTR (exp, 0), attr ? attr->name : "internal");
934           have_error = 1;
935         }
936       break;
937
938     case IF_THEN_ELSE:
939       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
940                                        attr ? attr->is_const : 0,
941                                        attr ? attr->lineno : 0);
942       XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
943       XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
944       break;
945
946     case PLUS:
947     case MINUS:
948     case MULT:
949     case DIV:
950     case MOD:
951       if (attr && !attr->is_numeric)
952         {
953           message_with_line (attr->lineno,
954                              "invalid operation `%s' for non-numeric attribute value",
955                              GET_RTX_NAME (GET_CODE (exp)));
956           have_error = 1;
957           break;
958         }
959       /* Fall through.  */
960
961     case IOR:
962     case AND:
963       XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
964       XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
965       break;
966
967     case FFS:
968     case CLZ:
969     case CTZ:
970     case POPCOUNT:
971     case PARITY:
972     case BSWAP:
973       XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
974       break;
975
976     case COND:
977       if (XVECLEN (exp, 0) % 2 != 0)
978         {
979           message_with_line (attr->lineno,
980                              "first operand of COND must have even length");
981           have_error = 1;
982           break;
983         }
984
985       for (i = 0; i < XVECLEN (exp, 0); i += 2)
986         {
987           XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
988                                                  attr ? attr->is_const : 0,
989                                                  attr ? attr->lineno : 0);
990           XVECEXP (exp, 0, i + 1)
991             = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
992         }
993
994       XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
995       break;
996
997     case ATTR:
998       {
999         struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1000         if (attr2 == NULL)
1001           {
1002             message_with_line (attr ? attr->lineno : 0,
1003                                "unknown attribute `%s' in ATTR",
1004                                XSTR (exp, 0));
1005             have_error = 1;
1006           }
1007         else if (attr && attr->is_const && ! attr2->is_const)
1008           {
1009             message_with_line (attr->lineno,
1010                 "non-constant attribute `%s' referenced from `%s'",
1011                 XSTR (exp, 0), attr->name);
1012             have_error = 1;
1013           }
1014         else if (attr
1015                  && attr->is_numeric != attr2->is_numeric)
1016           {
1017             message_with_line (attr->lineno,
1018                 "numeric attribute mismatch calling `%s' from `%s'",
1019                 XSTR (exp, 0), attr->name);
1020             have_error = 1;
1021           }
1022       }
1023       break;
1024
1025     case SYMBOL_REF:
1026       /* A constant SYMBOL_REF is valid as a constant attribute test and
1027          is expanded later by make_canonical into a COND.  In a non-constant
1028          attribute test, it is left be.  */
1029       return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1030
1031     default:
1032       message_with_line (attr ? attr->lineno : 0,
1033                          "invalid operation `%s' for attribute value",
1034                          GET_RTX_NAME (GET_CODE (exp)));
1035       have_error = 1;
1036       break;
1037     }
1038
1039   return exp;
1040 }
1041
1042 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1043    It becomes a COND with each test being (eq_attr "alternative" "n") */
1044
1045 static rtx
1046 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1047 {
1048   int num_alt = id->num_alternatives;
1049   rtx condexp;
1050   int i;
1051
1052   if (XVECLEN (exp, 1) != num_alt)
1053     {
1054       message_with_line (id->lineno,
1055                          "bad number of entries in SET_ATTR_ALTERNATIVE");
1056       have_error = 1;
1057       return NULL_RTX;
1058     }
1059
1060   /* Make a COND with all tests but the last.  Select the last value via the
1061      default.  */
1062   condexp = rtx_alloc (COND);
1063   XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1064
1065   for (i = 0; i < num_alt - 1; i++)
1066     {
1067       const char *p;
1068       p = attr_numeral (i);
1069
1070       XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1071       XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1072     }
1073
1074   XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1075
1076   return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1077 }
1078
1079 /* Given a SET_ATTR, convert to the appropriate SET.  If a comma-separated
1080    list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */
1081
1082 static rtx
1083 convert_set_attr (rtx exp, struct insn_def *id)
1084 {
1085   rtx newexp;
1086   const char *name_ptr;
1087   char *p;
1088   int n;
1089
1090   /* See how many alternative specified.  */
1091   n = n_comma_elts (XSTR (exp, 1));
1092   if (n == 1)
1093     return attr_rtx (SET,
1094                      attr_rtx (ATTR, XSTR (exp, 0)),
1095                      attr_rtx (CONST_STRING, XSTR (exp, 1)));
1096
1097   newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1098   XSTR (newexp, 0) = XSTR (exp, 0);
1099   XVEC (newexp, 1) = rtvec_alloc (n);
1100
1101   /* Process each comma-separated name.  */
1102   name_ptr = XSTR (exp, 1);
1103   n = 0;
1104   while ((p = next_comma_elt (&name_ptr)) != NULL)
1105     XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1106
1107   return convert_set_attr_alternative (newexp, id);
1108 }
1109
1110 /* Scan all definitions, checking for validity.  Also, convert any SET_ATTR
1111    and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1112    expressions.  */
1113
1114 static void
1115 check_defs (void)
1116 {
1117   struct insn_def *id;
1118   struct attr_desc *attr;
1119   int i;
1120   rtx value;
1121
1122   for (id = defs; id; id = id->next)
1123     {
1124       if (XVEC (id->def, id->vec_idx) == NULL)
1125         continue;
1126
1127       for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1128         {
1129           value = XVECEXP (id->def, id->vec_idx, i);
1130           switch (GET_CODE (value))
1131             {
1132             case SET:
1133               if (GET_CODE (XEXP (value, 0)) != ATTR)
1134                 {
1135                   message_with_line (id->lineno, "bad attribute set");
1136                   have_error = 1;
1137                   value = NULL_RTX;
1138                 }
1139               break;
1140
1141             case SET_ATTR_ALTERNATIVE:
1142               value = convert_set_attr_alternative (value, id);
1143               break;
1144
1145             case SET_ATTR:
1146               value = convert_set_attr (value, id);
1147               break;
1148
1149             default:
1150               message_with_line (id->lineno, "invalid attribute code %s",
1151                                  GET_RTX_NAME (GET_CODE (value)));
1152               have_error = 1;
1153               value = NULL_RTX;
1154             }
1155           if (value == NULL_RTX)
1156             continue;
1157
1158           if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1159             {
1160               message_with_line (id->lineno, "unknown attribute %s",
1161                                  XSTR (XEXP (value, 0), 0));
1162               have_error = 1;
1163               continue;
1164             }
1165
1166           XVECEXP (id->def, id->vec_idx, i) = value;
1167           XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1168         }
1169     }
1170 }
1171
1172 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1173    expressions by converting them into a COND.  This removes cases from this
1174    program.  Also, replace an attribute value of "*" with the default attribute
1175    value.  */
1176
1177 static rtx
1178 make_canonical (struct attr_desc *attr, rtx exp)
1179 {
1180   int i;
1181   rtx newexp;
1182
1183   switch (GET_CODE (exp))
1184     {
1185     case CONST_INT:
1186       exp = make_numeric_value (INTVAL (exp));
1187       break;
1188
1189     case CONST_STRING:
1190       if (! strcmp (XSTR (exp, 0), "*"))
1191         {
1192           if (attr == 0 || attr->default_val == 0)
1193             fatal ("(attr_value \"*\") used in invalid context");
1194           exp = attr->default_val->value;
1195         }
1196       else
1197         XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1198
1199       break;
1200
1201     case SYMBOL_REF:
1202       if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1203         break;
1204       /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1205          This makes the COND something that won't be considered an arbitrary
1206          expression by walk_attr_value.  */
1207       ATTR_IND_SIMPLIFIED_P (exp) = 1;
1208       exp = check_attr_value (exp, attr);
1209       break;
1210
1211     case IF_THEN_ELSE:
1212       newexp = rtx_alloc (COND);
1213       XVEC (newexp, 0) = rtvec_alloc (2);
1214       XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1215       XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1216
1217       XEXP (newexp, 1) = XEXP (exp, 2);
1218
1219       exp = newexp;
1220       /* Fall through to COND case since this is now a COND.  */
1221
1222     case COND:
1223       {
1224         int allsame = 1;
1225         rtx defval;
1226
1227         /* First, check for degenerate COND.  */
1228         if (XVECLEN (exp, 0) == 0)
1229           return make_canonical (attr, XEXP (exp, 1));
1230         defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1231
1232         for (i = 0; i < XVECLEN (exp, 0); i += 2)
1233           {
1234             XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1235             XVECEXP (exp, 0, i + 1)
1236               = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1237             if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1238               allsame = 0;
1239           }
1240         if (allsame)
1241           return defval;
1242       }
1243       break;
1244
1245     default:
1246       break;
1247     }
1248
1249   return exp;
1250 }
1251
1252 static rtx
1253 copy_boolean (rtx exp)
1254 {
1255   if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1256     return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1257                      copy_boolean (XEXP (exp, 1)));
1258   if (GET_CODE (exp) == MATCH_OPERAND)
1259     {
1260       XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1261       XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1262     }
1263   else if (GET_CODE (exp) == EQ_ATTR)
1264     {
1265       XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1266       XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1267     }
1268
1269   return exp;
1270 }
1271
1272 /* Given a value and an attribute description, return a `struct attr_value *'
1273    that represents that value.  This is either an existing structure, if the
1274    value has been previously encountered, or a newly-created structure.
1275
1276    `insn_code' is the code of an insn whose attribute has the specified
1277    value (-2 if not processing an insn).  We ensure that all insns for
1278    a given value have the same number of alternatives if the value checks
1279    alternatives.  */
1280
1281 static struct attr_value *
1282 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1283 {
1284   struct attr_value *av;
1285   int num_alt = 0;
1286
1287   value = make_canonical (attr, value);
1288   if (compares_alternatives_p (value))
1289     {
1290       if (insn_code < 0 || insn_alternatives == NULL)
1291         fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1292       else
1293         num_alt = insn_alternatives[insn_code];
1294     }
1295
1296   for (av = attr->first_value; av; av = av->next)
1297     if (rtx_equal_p (value, av->value)
1298         && (num_alt == 0 || av->first_insn == NULL
1299             || insn_alternatives[av->first_insn->def->insn_code]))
1300       return av;
1301
1302   av = oballoc (struct attr_value);
1303   av->value = value;
1304   av->next = attr->first_value;
1305   attr->first_value = av;
1306   av->first_insn = NULL;
1307   av->num_insns = 0;
1308   av->has_asm_insn = 0;
1309
1310   return av;
1311 }
1312
1313 /* After all DEFINE_DELAYs have been read in, create internal attributes
1314    to generate the required routines.
1315
1316    First, we compute the number of delay slots for each insn (as a COND of
1317    each of the test expressions in DEFINE_DELAYs).  Then, if more than one
1318    delay type is specified, we compute a similar function giving the
1319    DEFINE_DELAY ordinal for each insn.
1320
1321    Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1322    tells whether a given insn can be in that delay slot.
1323
1324    Normal attribute filling and optimization expands these to contain the
1325    information needed to handle delay slots.  */
1326
1327 static void
1328 expand_delays (void)
1329 {
1330   struct delay_desc *delay;
1331   rtx condexp;
1332   rtx newexp;
1333   int i;
1334   char *p;
1335
1336   /* First, generate data for `num_delay_slots' function.  */
1337
1338   condexp = rtx_alloc (COND);
1339   XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1340   XEXP (condexp, 1) = make_numeric_value (0);
1341
1342   for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1343     {
1344       XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1345       XVECEXP (condexp, 0, i + 1)
1346         = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1347     }
1348
1349   make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1350
1351   /* If more than one delay type, do the same for computing the delay type.  */
1352   if (num_delays > 1)
1353     {
1354       condexp = rtx_alloc (COND);
1355       XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1356       XEXP (condexp, 1) = make_numeric_value (0);
1357
1358       for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1359         {
1360           XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1361           XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1362         }
1363
1364       make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1365     }
1366
1367   /* For each delay possibility and delay slot, compute an eligibility
1368      attribute for non-annulled insns and for each type of annulled (annul
1369      if true and annul if false).  */
1370   for (delay = delays; delay; delay = delay->next)
1371     {
1372       for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1373         {
1374           condexp = XVECEXP (delay->def, 1, i);
1375           if (condexp == 0)
1376             condexp = false_rtx;
1377           newexp = attr_rtx (IF_THEN_ELSE, condexp,
1378                              make_numeric_value (1), make_numeric_value (0));
1379
1380           p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1381                            "*delay_%d_%d", delay->num, i / 3);
1382           make_internal_attr (p, newexp, ATTR_SPECIAL);
1383
1384           if (have_annul_true)
1385             {
1386               condexp = XVECEXP (delay->def, 1, i + 1);
1387               if (condexp == 0) condexp = false_rtx;
1388               newexp = attr_rtx (IF_THEN_ELSE, condexp,
1389                                  make_numeric_value (1),
1390                                  make_numeric_value (0));
1391               p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1392                                "*annul_true_%d_%d", delay->num, i / 3);
1393               make_internal_attr (p, newexp, ATTR_SPECIAL);
1394             }
1395
1396           if (have_annul_false)
1397             {
1398               condexp = XVECEXP (delay->def, 1, i + 2);
1399               if (condexp == 0) condexp = false_rtx;
1400               newexp = attr_rtx (IF_THEN_ELSE, condexp,
1401                                  make_numeric_value (1),
1402                                  make_numeric_value (0));
1403               p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1404                                "*annul_false_%d_%d", delay->num, i / 3);
1405               make_internal_attr (p, newexp, ATTR_SPECIAL);
1406             }
1407         }
1408     }
1409 }
1410
1411 /* Once all attributes and insns have been read and checked, we construct for
1412    each attribute value a list of all the insns that have that value for
1413    the attribute.  */
1414
1415 static void
1416 fill_attr (struct attr_desc *attr)
1417 {
1418   struct attr_value *av;
1419   struct insn_ent *ie;
1420   struct insn_def *id;
1421   int i;
1422   rtx value;
1423
1424   /* Don't fill constant attributes.  The value is independent of
1425      any particular insn.  */
1426   if (attr->is_const)
1427     return;
1428
1429   for (id = defs; id; id = id->next)
1430     {
1431       /* If no value is specified for this insn for this attribute, use the
1432          default.  */
1433       value = NULL;
1434       if (XVEC (id->def, id->vec_idx))
1435         for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1436           if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1437                               attr->name))
1438             value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1439
1440       if (value == NULL)
1441         av = attr->default_val;
1442       else
1443         av = get_attr_value (value, attr, id->insn_code);
1444
1445       ie = oballoc (struct insn_ent);
1446       ie->def = id;
1447       insert_insn_ent (av, ie);
1448     }
1449 }
1450
1451 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1452    test that checks relative positions of insns (uses MATCH_DUP or PC).
1453    If so, replace it with what is obtained by passing the expression to
1454    ADDRESS_FN.  If not but it is a COND or IF_THEN_ELSE, call this routine
1455    recursively on each value (including the default value).  Otherwise,
1456    return the value returned by NO_ADDRESS_FN applied to EXP.  */
1457
1458 static rtx
1459 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1460                     rtx (*address_fn) (rtx))
1461 {
1462   int i;
1463   rtx newexp;
1464
1465   if (GET_CODE (exp) == COND)
1466     {
1467       /* See if any tests use addresses.  */
1468       address_used = 0;
1469       for (i = 0; i < XVECLEN (exp, 0); i += 2)
1470         walk_attr_value (XVECEXP (exp, 0, i));
1471
1472       if (address_used)
1473         return (*address_fn) (exp);
1474
1475       /* Make a new copy of this COND, replacing each element.  */
1476       newexp = rtx_alloc (COND);
1477       XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1478       for (i = 0; i < XVECLEN (exp, 0); i += 2)
1479         {
1480           XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1481           XVECEXP (newexp, 0, i + 1)
1482             = substitute_address (XVECEXP (exp, 0, i + 1),
1483                                   no_address_fn, address_fn);
1484         }
1485
1486       XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1487                                              no_address_fn, address_fn);
1488
1489       return newexp;
1490     }
1491
1492   else if (GET_CODE (exp) == IF_THEN_ELSE)
1493     {
1494       address_used = 0;
1495       walk_attr_value (XEXP (exp, 0));
1496       if (address_used)
1497         return (*address_fn) (exp);
1498
1499       return attr_rtx (IF_THEN_ELSE,
1500                        substitute_address (XEXP (exp, 0),
1501                                            no_address_fn, address_fn),
1502                        substitute_address (XEXP (exp, 1),
1503                                            no_address_fn, address_fn),
1504                        substitute_address (XEXP (exp, 2),
1505                                            no_address_fn, address_fn));
1506     }
1507
1508   return (*no_address_fn) (exp);
1509 }
1510
1511 /* Make new attributes from the `length' attribute.  The following are made,
1512    each corresponding to a function called from `shorten_branches' or
1513    `get_attr_length':
1514
1515    *insn_default_length         This is the length of the insn to be returned
1516                                 by `get_attr_length' before `shorten_branches'
1517                                 has been called.  In each case where the length
1518                                 depends on relative addresses, the largest
1519                                 possible is used.  This routine is also used
1520                                 to compute the initial size of the insn.
1521
1522    *insn_variable_length_p      This returns 1 if the insn's length depends
1523                                 on relative addresses, zero otherwise.
1524
1525    *insn_current_length         This is only called when it is known that the
1526                                 insn has a variable length and returns the
1527                                 current length, based on relative addresses.
1528   */
1529
1530 static void
1531 make_length_attrs (void)
1532 {
1533   static const char *new_names[] =
1534     {
1535       "*insn_default_length",
1536       "*insn_min_length",
1537       "*insn_variable_length_p",
1538       "*insn_current_length"
1539     };
1540   static rtx (*const no_address_fn[]) (rtx)
1541     = {identity_fn,identity_fn, zero_fn, zero_fn};
1542   static rtx (*const address_fn[]) (rtx)
1543     = {max_fn, min_fn, one_fn, identity_fn};
1544   size_t i;
1545   struct attr_desc *length_attr, *new_attr;
1546   struct attr_value *av, *new_av;
1547   struct insn_ent *ie, *new_ie;
1548
1549   /* See if length attribute is defined.  If so, it must be numeric.  Make
1550      it special so we don't output anything for it.  */
1551   length_attr = find_attr (&length_str, 0);
1552   if (length_attr == 0)
1553     return;
1554
1555   if (! length_attr->is_numeric)
1556     fatal ("length attribute must be numeric");
1557
1558   length_attr->is_const = 0;
1559   length_attr->is_special = 1;
1560
1561   /* Make each new attribute, in turn.  */
1562   for (i = 0; i < ARRAY_SIZE (new_names); i++)
1563     {
1564       make_internal_attr (new_names[i],
1565                           substitute_address (length_attr->default_val->value,
1566                                               no_address_fn[i], address_fn[i]),
1567                           ATTR_NONE);
1568       new_attr = find_attr (&new_names[i], 0);
1569       for (av = length_attr->first_value; av; av = av->next)
1570         for (ie = av->first_insn; ie; ie = ie->next)
1571           {
1572             new_av = get_attr_value (substitute_address (av->value,
1573                                                          no_address_fn[i],
1574                                                          address_fn[i]),
1575                                      new_attr, ie->def->insn_code);
1576             new_ie = oballoc (struct insn_ent);
1577             new_ie->def = ie->def;
1578             insert_insn_ent (new_av, new_ie);
1579           }
1580     }
1581 }
1582
1583 /* Utility functions called from above routine.  */
1584
1585 static rtx
1586 identity_fn (rtx exp)
1587 {
1588   return exp;
1589 }
1590
1591 static rtx
1592 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1593 {
1594   return make_numeric_value (0);
1595 }
1596
1597 static rtx
1598 one_fn (rtx exp ATTRIBUTE_UNUSED)
1599 {
1600   return make_numeric_value (1);
1601 }
1602
1603 static rtx
1604 max_fn (rtx exp)
1605 {
1606   int unknown;
1607   return make_numeric_value (max_attr_value (exp, &unknown));
1608 }
1609
1610 static rtx
1611 min_fn (rtx exp)
1612 {
1613   int unknown;
1614   return make_numeric_value (min_attr_value (exp, &unknown));
1615 }
1616
1617 static void
1618 write_length_unit_log (void)
1619 {
1620   struct attr_desc *length_attr = find_attr (&length_str, 0);
1621   struct attr_value *av;
1622   struct insn_ent *ie;
1623   unsigned int length_unit_log, length_or;
1624   int unknown = 0;
1625
1626   if (length_attr == 0)
1627     return;
1628   length_or = or_attr_value (length_attr->default_val->value, &unknown);
1629   for (av = length_attr->first_value; av; av = av->next)
1630     for (ie = av->first_insn; ie; ie = ie->next)
1631       length_or |= or_attr_value (av->value, &unknown);
1632
1633   if (unknown)
1634     length_unit_log = 0;
1635   else
1636     {
1637       length_or = ~length_or;
1638       for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1639         length_unit_log++;
1640     }
1641   printf ("EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1642 }
1643
1644 /* Take a COND expression and see if any of the conditions in it can be
1645    simplified.  If any are known true or known false for the particular insn
1646    code, the COND can be further simplified.
1647
1648    Also call ourselves on any COND operations that are values of this COND.
1649
1650    We do not modify EXP; rather, we make and return a new rtx.  */
1651
1652 static rtx
1653 simplify_cond (rtx exp, int insn_code, int insn_index)
1654 {
1655   int i, j;
1656   /* We store the desired contents here,
1657      then build a new expression if they don't match EXP.  */
1658   rtx defval = XEXP (exp, 1);
1659   rtx new_defval = XEXP (exp, 1);
1660   int len = XVECLEN (exp, 0);
1661   rtx *tests = XNEWVEC (rtx, len);
1662   int allsame = 1;
1663   rtx ret;
1664
1665   /* This lets us free all storage allocated below, if appropriate.  */
1666   obstack_finish (rtl_obstack);
1667
1668   memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1669
1670   /* See if default value needs simplification.  */
1671   if (GET_CODE (defval) == COND)
1672     new_defval = simplify_cond (defval, insn_code, insn_index);
1673
1674   /* Simplify the subexpressions, and see what tests we can get rid of.  */
1675
1676   for (i = 0; i < len; i += 2)
1677     {
1678       rtx newtest, newval;
1679
1680       /* Simplify this test.  */
1681       newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1682       tests[i] = newtest;
1683
1684       newval = tests[i + 1];
1685       /* See if this value may need simplification.  */
1686       if (GET_CODE (newval) == COND)
1687         newval = simplify_cond (newval, insn_code, insn_index);
1688
1689       /* Look for ways to delete or combine this test.  */
1690       if (newtest == true_rtx)
1691         {
1692           /* If test is true, make this value the default
1693              and discard this + any following tests.  */
1694           len = i;
1695           defval = tests[i + 1];
1696           new_defval = newval;
1697         }
1698
1699       else if (newtest == false_rtx)
1700         {
1701           /* If test is false, discard it and its value.  */
1702           for (j = i; j < len - 2; j++)
1703             tests[j] = tests[j + 2];
1704           i -= 2;
1705           len -= 2;
1706         }
1707
1708       else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1709         {
1710           /* If this value and the value for the prev test are the same,
1711              merge the tests.  */
1712
1713           tests[i - 2]
1714             = insert_right_side (IOR, tests[i - 2], newtest,
1715                                  insn_code, insn_index);
1716
1717           /* Delete this test/value.  */
1718           for (j = i; j < len - 2; j++)
1719             tests[j] = tests[j + 2];
1720           len -= 2;
1721           i -= 2;
1722         }
1723
1724       else
1725         tests[i + 1] = newval;
1726     }
1727
1728   /* If the last test in a COND has the same value
1729      as the default value, that test isn't needed.  */
1730
1731   while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1732     len -= 2;
1733
1734   /* See if we changed anything.  */
1735   if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1736     allsame = 0;
1737   else
1738     for (i = 0; i < len; i++)
1739       if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1740         {
1741           allsame = 0;
1742           break;
1743         }
1744
1745   if (len == 0)
1746     {
1747       if (GET_CODE (defval) == COND)
1748         ret = simplify_cond (defval, insn_code, insn_index);
1749       else
1750         ret = defval;
1751     }
1752   else if (allsame)
1753     ret = exp;
1754   else
1755     {
1756       rtx newexp = rtx_alloc (COND);
1757
1758       XVEC (newexp, 0) = rtvec_alloc (len);
1759       memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1760       XEXP (newexp, 1) = new_defval;
1761       ret = newexp;
1762     }
1763   free (tests);
1764   return ret;
1765 }
1766
1767 /* Remove an insn entry from an attribute value.  */
1768
1769 static void
1770 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1771 {
1772   struct insn_ent *previe;
1773
1774   if (av->first_insn == ie)
1775     av->first_insn = ie->next;
1776   else
1777     {
1778       for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1779         ;
1780       previe->next = ie->next;
1781     }
1782
1783   av->num_insns--;
1784   if (ie->def->insn_code == -1)
1785     av->has_asm_insn = 0;
1786
1787   num_insn_ents--;
1788 }
1789
1790 /* Insert an insn entry in an attribute value list.  */
1791
1792 static void
1793 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1794 {
1795   ie->next = av->first_insn;
1796   av->first_insn = ie;
1797   av->num_insns++;
1798   if (ie->def->insn_code == -1)
1799     av->has_asm_insn = 1;
1800
1801   num_insn_ents++;
1802 }
1803
1804 /* This is a utility routine to take an expression that is a tree of either
1805    AND or IOR expressions and insert a new term.  The new term will be
1806    inserted at the right side of the first node whose code does not match
1807    the root.  A new node will be created with the root's code.  Its left
1808    side will be the old right side and its right side will be the new
1809    term.
1810
1811    If the `term' is itself a tree, all its leaves will be inserted.  */
1812
1813 static rtx
1814 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1815 {
1816   rtx newexp;
1817
1818   /* Avoid consing in some special cases.  */
1819   if (code == AND && term == true_rtx)
1820     return exp;
1821   if (code == AND && term == false_rtx)
1822     return false_rtx;
1823   if (code == AND && exp == true_rtx)
1824     return term;
1825   if (code == AND && exp == false_rtx)
1826     return false_rtx;
1827   if (code == IOR && term == true_rtx)
1828     return true_rtx;
1829   if (code == IOR && term == false_rtx)
1830     return exp;
1831   if (code == IOR && exp == true_rtx)
1832     return true_rtx;
1833   if (code == IOR && exp == false_rtx)
1834     return term;
1835   if (attr_equal_p (exp, term))
1836     return exp;
1837
1838   if (GET_CODE (term) == code)
1839     {
1840       exp = insert_right_side (code, exp, XEXP (term, 0),
1841                                insn_code, insn_index);
1842       exp = insert_right_side (code, exp, XEXP (term, 1),
1843                                insn_code, insn_index);
1844
1845       return exp;
1846     }
1847
1848   if (GET_CODE (exp) == code)
1849     {
1850       rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1851                                        term, insn_code, insn_index);
1852       if (new_rtx != XEXP (exp, 1))
1853         /* Make a copy of this expression and call recursively.  */
1854         newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1855       else
1856         newexp = exp;
1857     }
1858   else
1859     {
1860       /* Insert the new term.  */
1861       newexp = attr_rtx (code, exp, term);
1862     }
1863
1864   return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1865 }
1866
1867 /* If we have an expression which AND's a bunch of
1868         (not (eq_attrq "alternative" "n"))
1869    terms, we may have covered all or all but one of the possible alternatives.
1870    If so, we can optimize.  Similarly for IOR's of EQ_ATTR.
1871
1872    This routine is passed an expression and either AND or IOR.  It returns a
1873    bitmask indicating which alternatives are mentioned within EXP.  */
1874
1875 static int
1876 compute_alternative_mask (rtx exp, enum rtx_code code)
1877 {
1878   const char *string;
1879   if (GET_CODE (exp) == code)
1880     return compute_alternative_mask (XEXP (exp, 0), code)
1881            | compute_alternative_mask (XEXP (exp, 1), code);
1882
1883   else if (code == AND && GET_CODE (exp) == NOT
1884            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1885            && XSTR (XEXP (exp, 0), 0) == alternative_name)
1886     string = XSTR (XEXP (exp, 0), 1);
1887
1888   else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1889            && XSTR (exp, 0) == alternative_name)
1890     string = XSTR (exp, 1);
1891
1892   else if (GET_CODE (exp) == EQ_ATTR_ALT)
1893     {
1894       if (code == AND && XINT (exp, 1))
1895         return XINT (exp, 0);
1896
1897       if (code == IOR && !XINT (exp, 1))
1898         return XINT (exp, 0);
1899
1900       return 0;
1901     }
1902   else
1903     return 0;
1904
1905   if (string[1] == 0)
1906     return 1 << (string[0] - '0');
1907   return 1 << atoi (string);
1908 }
1909
1910 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1911    attribute with the value represented by that bit.  */
1912
1913 static rtx
1914 make_alternative_compare (int mask)
1915 {
1916   return mk_attr_alt (mask);
1917 }
1918
1919 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1920    of "attr" for this insn code.  From that value, we can compute a test
1921    showing when the EQ_ATTR will be true.  This routine performs that
1922    computation.  If a test condition involves an address, we leave the EQ_ATTR
1923    intact because addresses are only valid for the `length' attribute.
1924
1925    EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1926    for the insn corresponding to INSN_CODE and INSN_INDEX.  */
1927
1928 static rtx
1929 evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
1930 {
1931   rtx orexp, andexp;
1932   rtx right;
1933   rtx newexp;
1934   int i;
1935
1936   switch (GET_CODE (value))
1937     {
1938     case CONST_STRING:
1939       if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
1940         newexp = true_rtx;
1941       else
1942         newexp = false_rtx;
1943       break;
1944       
1945     case SYMBOL_REF:
1946       {
1947         char *p;
1948         char string[256];
1949         
1950         gcc_assert (GET_CODE (exp) == EQ_ATTR);
1951         gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
1952                     <= 256);
1953         
1954         strcpy (string, XSTR (exp, 0));
1955         strcat (string, "_");
1956         strcat (string, XSTR (exp, 1));
1957         for (p = string; *p; p++)
1958           *p = TOUPPER (*p);
1959         
1960         newexp = attr_rtx (EQ, value,
1961                            attr_rtx (SYMBOL_REF,
1962                                      DEF_ATTR_STRING (string)));
1963         break;
1964       }
1965
1966     case COND:
1967       /* We construct an IOR of all the cases for which the
1968          requested attribute value is present.  Since we start with
1969          FALSE, if it is not present, FALSE will be returned.
1970           
1971          Each case is the AND of the NOT's of the previous conditions with the
1972          current condition; in the default case the current condition is TRUE.
1973           
1974          For each possible COND value, call ourselves recursively.
1975           
1976          The extra TRUE and FALSE expressions will be eliminated by another
1977          call to the simplification routine.  */
1978
1979       orexp = false_rtx;
1980       andexp = true_rtx;
1981
1982       for (i = 0; i < XVECLEN (value, 0); i += 2)
1983         {
1984           rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
1985                                                     insn_code, insn_index);
1986
1987           right = insert_right_side (AND, andexp, this_cond,
1988                                      insn_code, insn_index);
1989           right = insert_right_side (AND, right,
1990                                      evaluate_eq_attr (exp,
1991                                                        XVECEXP (value, 0,
1992                                                                 i + 1),
1993                                                        insn_code, insn_index),
1994                                      insn_code, insn_index);
1995           orexp = insert_right_side (IOR, orexp, right,
1996                                      insn_code, insn_index);
1997
1998           /* Add this condition into the AND expression.  */
1999           newexp = attr_rtx (NOT, this_cond);
2000           andexp = insert_right_side (AND, andexp, newexp,
2001                                       insn_code, insn_index);
2002         }
2003
2004       /* Handle the default case.  */
2005       right = insert_right_side (AND, andexp,
2006                                  evaluate_eq_attr (exp, XEXP (value, 1),
2007                                                    insn_code, insn_index),
2008                                  insn_code, insn_index);
2009       newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2010       break;
2011
2012     default:
2013       gcc_unreachable ();
2014     }
2015
2016   /* If uses an address, must return original expression.  But set the
2017      ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again.  */
2018
2019   address_used = 0;
2020   walk_attr_value (newexp);
2021
2022   if (address_used)
2023     {
2024       if (! ATTR_IND_SIMPLIFIED_P (exp))
2025         return copy_rtx_unchanging (exp);
2026       return exp;
2027     }
2028   else
2029     return newexp;
2030 }
2031
2032 /* This routine is called when an AND of a term with a tree of AND's is
2033    encountered.  If the term or its complement is present in the tree, it
2034    can be replaced with TRUE or FALSE, respectively.
2035
2036    Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2037    be true and hence are complementary.
2038
2039    There is one special case:  If we see
2040         (and (not (eq_attr "att" "v1"))
2041              (eq_attr "att" "v2"))
2042    this can be replaced by (eq_attr "att" "v2").  To do this we need to
2043    replace the term, not anything in the AND tree.  So we pass a pointer to
2044    the term.  */
2045
2046 static rtx
2047 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2048 {
2049   rtx left, right;
2050   rtx newexp;
2051   rtx temp;
2052   int left_eliminates_term, right_eliminates_term;
2053
2054   if (GET_CODE (exp) == AND)
2055     {
2056       left  = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2057       right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2058       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2059         {
2060           newexp = attr_rtx (AND, left, right);
2061
2062           exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2063         }
2064     }
2065
2066   else if (GET_CODE (exp) == IOR)
2067     {
2068       /* For the IOR case, we do the same as above, except that we can
2069          only eliminate `term' if both sides of the IOR would do so.  */
2070       temp = *pterm;
2071       left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2072       left_eliminates_term = (temp == true_rtx);
2073
2074       temp = *pterm;
2075       right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2076       right_eliminates_term = (temp == true_rtx);
2077
2078       if (left_eliminates_term && right_eliminates_term)
2079         *pterm = true_rtx;
2080
2081       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2082         {
2083           newexp = attr_rtx (IOR, left, right);
2084
2085           exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2086         }
2087     }
2088
2089   /* Check for simplifications.  Do some extra checking here since this
2090      routine is called so many times.  */
2091
2092   if (exp == *pterm)
2093     return true_rtx;
2094
2095   else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2096     return false_rtx;
2097
2098   else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2099     return false_rtx;
2100
2101   else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2102     {
2103       if (attr_alt_subset_p (*pterm, exp))
2104         return true_rtx;
2105
2106       if (attr_alt_subset_of_compl_p (*pterm, exp))
2107         return false_rtx;
2108
2109       if (attr_alt_subset_p (exp, *pterm))
2110         *pterm = true_rtx;
2111         
2112       return exp;
2113     }
2114
2115   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2116     {
2117       if (XSTR (exp, 0) != XSTR (*pterm, 0))
2118         return exp;
2119
2120       if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2121         return true_rtx;
2122       else
2123         return false_rtx;
2124     }
2125
2126   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2127            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2128     {
2129       if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2130         return exp;
2131
2132       if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2133         return false_rtx;
2134       else
2135         return true_rtx;
2136     }
2137
2138   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2139            && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2140     {
2141       if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2142         return exp;
2143
2144       if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2145         return false_rtx;
2146       else
2147         *pterm = true_rtx;
2148     }
2149
2150   else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2151     {
2152       if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2153         return true_rtx;
2154     }
2155
2156   else if (GET_CODE (exp) == NOT)
2157     {
2158       if (attr_equal_p (XEXP (exp, 0), *pterm))
2159         return false_rtx;
2160     }
2161
2162   else if (GET_CODE (*pterm) == NOT)
2163     {
2164       if (attr_equal_p (XEXP (*pterm, 0), exp))
2165         return false_rtx;
2166     }
2167
2168   else if (attr_equal_p (exp, *pterm))
2169     return true_rtx;
2170
2171   return exp;
2172 }
2173
2174 /* Similar to `simplify_and_tree', but for IOR trees.  */
2175
2176 static rtx
2177 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2178 {
2179   rtx left, right;
2180   rtx newexp;
2181   rtx temp;
2182   int left_eliminates_term, right_eliminates_term;
2183
2184   if (GET_CODE (exp) == IOR)
2185     {
2186       left  = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2187       right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2188       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2189         {
2190           newexp = attr_rtx (GET_CODE (exp), left, right);
2191
2192           exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2193         }
2194     }
2195
2196   else if (GET_CODE (exp) == AND)
2197     {
2198       /* For the AND case, we do the same as above, except that we can
2199          only eliminate `term' if both sides of the AND would do so.  */
2200       temp = *pterm;
2201       left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2202       left_eliminates_term = (temp == false_rtx);
2203
2204       temp = *pterm;
2205       right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2206       right_eliminates_term = (temp == false_rtx);
2207
2208       if (left_eliminates_term && right_eliminates_term)
2209         *pterm = false_rtx;
2210
2211       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2212         {
2213           newexp = attr_rtx (GET_CODE (exp), left, right);
2214
2215           exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2216         }
2217     }
2218
2219   if (attr_equal_p (exp, *pterm))
2220     return false_rtx;
2221
2222   else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2223     return true_rtx;
2224
2225   else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2226     return true_rtx;
2227
2228   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2229            && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2230            && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2231     *pterm = false_rtx;
2232
2233   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2234            && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2235            && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2236     return false_rtx;
2237
2238   return exp;
2239 }
2240
2241 /* Compute approximate cost of the expression.  Used to decide whether
2242    expression is cheap enough for inline.  */
2243 static int
2244 attr_rtx_cost (rtx x)
2245 {
2246   int cost = 0;
2247   enum rtx_code code;
2248   if (!x)
2249     return 0;
2250   code = GET_CODE (x);
2251   switch (code)
2252     {
2253     case MATCH_OPERAND:
2254       if (XSTR (x, 1)[0])
2255         return 10;
2256       else
2257         return 0;
2258
2259     case EQ_ATTR_ALT:
2260       return 0;
2261
2262     case EQ_ATTR:
2263       /* Alternatives don't result into function call.  */
2264       if (!strcmp_check (XSTR (x, 0), alternative_name))
2265         return 0;
2266       else
2267         return 5;
2268     default:
2269       {
2270         int i, j;
2271         const char *fmt = GET_RTX_FORMAT (code);
2272         for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2273           {
2274             switch (fmt[i])
2275               {
2276               case 'V':
2277               case 'E':
2278                 for (j = 0; j < XVECLEN (x, i); j++)
2279                   cost += attr_rtx_cost (XVECEXP (x, i, j));
2280                 break;
2281               case 'e':
2282                 cost += attr_rtx_cost (XEXP (x, i));
2283                 break;
2284               }
2285           }
2286       }
2287       break;
2288     }
2289   return cost;
2290 }
2291
2292 /* Simplify test expression and use temporary obstack in order to avoid
2293    memory bloat.  Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2294    and avoid unnecessary copying if possible.  */
2295
2296 static rtx
2297 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2298 {
2299   rtx x;
2300   struct obstack *old;
2301   if (ATTR_IND_SIMPLIFIED_P (exp))
2302     return exp;
2303   old = rtl_obstack;
2304   rtl_obstack = temp_obstack;
2305   x = simplify_test_exp (exp, insn_code, insn_index);
2306   rtl_obstack = old;
2307   if (x == exp || rtl_obstack == temp_obstack)
2308     return x;
2309   return attr_copy_rtx (x);
2310 }
2311
2312 /* Returns true if S1 is a subset of S2.  */
2313
2314 static bool
2315 attr_alt_subset_p (rtx s1, rtx s2)
2316 {
2317   switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2318     {
2319     case (0 << 1) | 0:
2320       return !(XINT (s1, 0) &~ XINT (s2, 0));
2321
2322     case (0 << 1) | 1:
2323       return !(XINT (s1, 0) & XINT (s2, 0));
2324
2325     case (1 << 1) | 0:
2326       return false;
2327
2328     case (1 << 1) | 1:
2329       return !(XINT (s2, 0) &~ XINT (s1, 0));
2330
2331     default:
2332       gcc_unreachable ();
2333     }
2334 }
2335
2336 /* Returns true if S1 is a subset of complement of S2.  */
2337
2338 static bool
2339 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2340 {
2341   switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2342     {
2343     case (0 << 1) | 0:
2344       return !(XINT (s1, 0) & XINT (s2, 0));
2345
2346     case (0 << 1) | 1:
2347       return !(XINT (s1, 0) & ~XINT (s2, 0));
2348
2349     case (1 << 1) | 0:
2350       return !(XINT (s2, 0) &~ XINT (s1, 0));
2351
2352     case (1 << 1) | 1:
2353       return false;
2354
2355     default:
2356       gcc_unreachable ();
2357     }
2358 }
2359
2360 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2.  */
2361
2362 static rtx
2363 attr_alt_intersection (rtx s1, rtx s2)
2364 {
2365   rtx result = rtx_alloc (EQ_ATTR_ALT);
2366
2367   switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2368     {
2369     case (0 << 1) | 0:
2370       XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2371       break;
2372     case (0 << 1) | 1:
2373       XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2374       break;
2375     case (1 << 1) | 0:
2376       XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2377       break;
2378     case (1 << 1) | 1:
2379       XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2380       break;
2381     default:
2382       gcc_unreachable ();
2383     }
2384   XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2385
2386   return result;
2387 }
2388
2389 /* Return EQ_ATTR_ALT expression representing union of S1 and S2.  */
2390
2391 static rtx
2392 attr_alt_union (rtx s1, rtx s2)
2393 {
2394   rtx result = rtx_alloc (EQ_ATTR_ALT);
2395
2396   switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2397     {
2398     case (0 << 1) | 0:
2399       XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2400       break;
2401     case (0 << 1) | 1:
2402       XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2403       break;
2404     case (1 << 1) | 0:
2405       XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2406       break;
2407     case (1 << 1) | 1:
2408       XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2409       break;
2410     default:
2411       gcc_unreachable ();
2412     }
2413
2414   XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2415   return result;
2416 }
2417
2418 /* Return EQ_ATTR_ALT expression representing complement of S.  */
2419
2420 static rtx
2421 attr_alt_complement (rtx s)
2422 {
2423   rtx result = rtx_alloc (EQ_ATTR_ALT);
2424
2425   XINT (result, 0) = XINT (s, 0);
2426   XINT (result, 1) = 1 - XINT (s, 1);
2427
2428   return result;
2429 }
2430
2431 /* Return EQ_ATTR_ALT expression representing set containing elements set
2432    in E.  */
2433
2434 static rtx
2435 mk_attr_alt (int e)
2436 {
2437   rtx result = rtx_alloc (EQ_ATTR_ALT);
2438
2439   XINT (result, 0) = e;
2440   XINT (result, 1) = 0;
2441
2442   return result;
2443 }
2444
2445 /* Given an expression, see if it can be simplified for a particular insn
2446    code based on the values of other attributes being tested.  This can
2447    eliminate nested get_attr_... calls.
2448
2449    Note that if an endless recursion is specified in the patterns, the
2450    optimization will loop.  However, it will do so in precisely the cases where
2451    an infinite recursion loop could occur during compilation.  It's better that
2452    it occurs here!  */
2453
2454 static rtx
2455 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2456 {
2457   rtx left, right;
2458   struct attr_desc *attr;
2459   struct attr_value *av;
2460   struct insn_ent *ie;
2461   struct attr_value_list *iv;
2462   int i;
2463   rtx newexp = exp;
2464   bool left_alt, right_alt;
2465
2466   /* Don't re-simplify something we already simplified.  */
2467   if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2468     return exp;
2469
2470   switch (GET_CODE (exp))
2471     {
2472     case AND:
2473       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2474       if (left == false_rtx)
2475         return false_rtx;
2476       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2477       if (right == false_rtx)
2478         return false_rtx;
2479
2480       if (GET_CODE (left) == EQ_ATTR_ALT
2481           && GET_CODE (right) == EQ_ATTR_ALT)
2482         {
2483           exp = attr_alt_intersection (left, right);
2484           return simplify_test_exp (exp, insn_code, insn_index);
2485         }
2486
2487       /* If either side is an IOR and we have (eq_attr "alternative" ..")
2488          present on both sides, apply the distributive law since this will
2489          yield simplifications.  */
2490       if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2491           && compute_alternative_mask (left, IOR)
2492           && compute_alternative_mask (right, IOR))
2493         {
2494           if (GET_CODE (left) == IOR)
2495             {
2496               rtx tem = left;
2497               left = right;
2498               right = tem;
2499             }
2500
2501           newexp = attr_rtx (IOR,
2502                              attr_rtx (AND, left, XEXP (right, 0)),
2503                              attr_rtx (AND, left, XEXP (right, 1)));
2504
2505           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2506         }
2507
2508       /* Try with the term on both sides.  */
2509       right = simplify_and_tree (right, &left, insn_code, insn_index);
2510       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2511         left = simplify_and_tree (left, &right, insn_code, insn_index);
2512
2513       if (left == false_rtx || right == false_rtx)
2514         return false_rtx;
2515       else if (left == true_rtx)
2516         {
2517           return right;
2518         }
2519       else if (right == true_rtx)
2520         {
2521           return left;
2522         }
2523       /* See if all or all but one of the insn's alternatives are specified
2524          in this tree.  Optimize if so.  */
2525
2526       if (GET_CODE (left) == NOT)
2527         left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2528                     && XSTR (XEXP (left, 0), 0) == alternative_name);
2529       else
2530         left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2531                     && XINT (left, 1));
2532
2533       if (GET_CODE (right) == NOT)
2534         right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2535                      && XSTR (XEXP (right, 0), 0) == alternative_name);
2536       else
2537         right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2538                      && XINT (right, 1));
2539
2540       if (insn_code >= 0
2541           && (GET_CODE (left) == AND
2542               || left_alt
2543               || GET_CODE (right) == AND
2544               || right_alt))
2545         {
2546           i = compute_alternative_mask (exp, AND);
2547           if (i & ~insn_alternatives[insn_code])
2548             fatal ("invalid alternative specified for pattern number %d",
2549                    insn_index);
2550
2551           /* If all alternatives are excluded, this is false.  */
2552           i ^= insn_alternatives[insn_code];
2553           if (i == 0)
2554             return false_rtx;
2555           else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2556             {
2557               /* If just one excluded, AND a comparison with that one to the
2558                  front of the tree.  The others will be eliminated by
2559                  optimization.  We do not want to do this if the insn has one
2560                  alternative and we have tested none of them!  */
2561               left = make_alternative_compare (i);
2562               right = simplify_and_tree (exp, &left, insn_code, insn_index);
2563               newexp = attr_rtx (AND, left, right);
2564
2565               return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2566             }
2567         }
2568
2569       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2570         {
2571           newexp = attr_rtx (AND, left, right);
2572           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2573         }
2574       break;
2575
2576     case IOR:
2577       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2578       if (left == true_rtx)
2579         return true_rtx;
2580       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2581       if (right == true_rtx)
2582         return true_rtx;
2583
2584       if (GET_CODE (left) == EQ_ATTR_ALT
2585           && GET_CODE (right) == EQ_ATTR_ALT)
2586         {
2587           exp = attr_alt_union (left, right);
2588           return simplify_test_exp (exp, insn_code, insn_index);
2589         }
2590
2591       right = simplify_or_tree (right, &left, insn_code, insn_index);
2592       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2593         left = simplify_or_tree (left, &right, insn_code, insn_index);
2594
2595       if (right == true_rtx || left == true_rtx)
2596         return true_rtx;
2597       else if (left == false_rtx)
2598         {
2599           return right;
2600         }
2601       else if (right == false_rtx)
2602         {
2603           return left;
2604         }
2605
2606       /* Test for simple cases where the distributive law is useful.  I.e.,
2607             convert (ior (and (x) (y))
2608                          (and (x) (z)))
2609             to      (and (x)
2610                          (ior (y) (z)))
2611        */
2612
2613       else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2614                && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2615         {
2616           newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2617
2618           left = XEXP (left, 0);
2619           right = newexp;
2620           newexp = attr_rtx (AND, left, right);
2621           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2622         }
2623
2624       /* See if all or all but one of the insn's alternatives are specified
2625          in this tree.  Optimize if so.  */
2626
2627       else if (insn_code >= 0
2628                && (GET_CODE (left) == IOR
2629                    || (GET_CODE (left) == EQ_ATTR_ALT
2630                        && !XINT (left, 1))
2631                    || (GET_CODE (left) == EQ_ATTR
2632                        && XSTR (left, 0) == alternative_name)
2633                    || GET_CODE (right) == IOR
2634                    || (GET_CODE (right) == EQ_ATTR_ALT
2635                        && !XINT (right, 1))
2636                    || (GET_CODE (right) == EQ_ATTR
2637                        && XSTR (right, 0) == alternative_name)))
2638         {
2639           i = compute_alternative_mask (exp, IOR);
2640           if (i & ~insn_alternatives[insn_code])
2641             fatal ("invalid alternative specified for pattern number %d",
2642                    insn_index);
2643
2644           /* If all alternatives are included, this is true.  */
2645           i ^= insn_alternatives[insn_code];
2646           if (i == 0)
2647             return true_rtx;
2648           else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2649             {
2650               /* If just one excluded, IOR a comparison with that one to the
2651                  front of the tree.  The others will be eliminated by
2652                  optimization.  We do not want to do this if the insn has one
2653                  alternative and we have tested none of them!  */
2654               left = make_alternative_compare (i);
2655               right = simplify_and_tree (exp, &left, insn_code, insn_index);
2656               newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2657
2658               return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2659             }
2660         }
2661
2662       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2663         {
2664           newexp = attr_rtx (IOR, left, right);
2665           return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2666         }
2667       break;
2668
2669     case NOT:
2670       if (GET_CODE (XEXP (exp, 0)) == NOT)
2671         {
2672           left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2673                                     insn_code, insn_index);
2674           return left;
2675         }
2676
2677       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2678       if (GET_CODE (left) == NOT)
2679         return XEXP (left, 0);
2680
2681       if (left == false_rtx)
2682         return true_rtx;
2683       if (left == true_rtx)
2684         return false_rtx;
2685
2686       if (GET_CODE (left) == EQ_ATTR_ALT)
2687         {
2688           exp = attr_alt_complement (left);
2689           return simplify_test_exp (exp, insn_code, insn_index);
2690         }
2691
2692       /* Try to apply De`Morgan's laws.  */
2693       if (GET_CODE (left) == IOR)
2694         {
2695           newexp = attr_rtx (AND,
2696                              attr_rtx (NOT, XEXP (left, 0)),
2697                              attr_rtx (NOT, XEXP (left, 1)));
2698
2699           newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2700         }
2701       else if (GET_CODE (left) == AND)
2702         {
2703           newexp = attr_rtx (IOR,
2704                              attr_rtx (NOT, XEXP (left, 0)),
2705                              attr_rtx (NOT, XEXP (left, 1)));
2706
2707           newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2708         }
2709       else if (left != XEXP (exp, 0))
2710         {
2711           newexp = attr_rtx (NOT, left);
2712         }
2713       break;
2714
2715     case EQ_ATTR_ALT:
2716       if (!XINT (exp, 0))
2717         return XINT (exp, 1) ? true_rtx : false_rtx;
2718       break;
2719
2720     case EQ_ATTR:
2721       if (XSTR (exp, 0) == alternative_name)
2722         {
2723           newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2724           break;
2725         }
2726
2727       /* Look at the value for this insn code in the specified attribute.
2728          We normally can replace this comparison with the condition that
2729          would give this insn the values being tested for.  */
2730       if (insn_code >= 0
2731           && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2732         {
2733           rtx x;
2734
2735           av = NULL;
2736           if (insn_code_values)
2737             {
2738               for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2739                 if (iv->attr == attr)
2740                   {
2741                     av = iv->av;
2742                     break;
2743                   }
2744             }
2745           else
2746             {
2747               for (av = attr->first_value; av; av = av->next)
2748                 for (ie = av->first_insn; ie; ie = ie->next)
2749                   if (ie->def->insn_code == insn_code)
2750                     goto got_av;
2751             }
2752
2753           if (av)
2754             {
2755             got_av:
2756               x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2757               x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2758               if (attr_rtx_cost(x) < 20)
2759                 return x;
2760             }
2761         }
2762       break;
2763
2764     default:
2765       break;
2766     }
2767
2768   /* We have already simplified this expression.  Simplifying it again
2769      won't buy anything unless we weren't given a valid insn code
2770      to process (i.e., we are canonicalizing something.).  */
2771   if (insn_code != -2
2772       && ! ATTR_IND_SIMPLIFIED_P (newexp))
2773     return copy_rtx_unchanging (newexp);
2774
2775   return newexp;
2776 }
2777
2778 /* Optimize the attribute lists by seeing if we can determine conditional
2779    values from the known values of other attributes.  This will save subroutine
2780    calls during the compilation.  */
2781
2782 static void
2783 optimize_attrs (void)
2784 {
2785   struct attr_desc *attr;
2786   struct attr_value *av;
2787   struct insn_ent *ie;
2788   rtx newexp;
2789   int i;
2790   struct attr_value_list *ivbuf;
2791   struct attr_value_list *iv;
2792
2793   /* For each insn code, make a list of all the insn_ent's for it,
2794      for all values for all attributes.  */
2795
2796   if (num_insn_ents == 0)
2797     return;
2798
2799   /* Make 2 extra elements, for "code" values -2 and -1.  */
2800   insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
2801
2802   /* Offset the table address so we can index by -2 or -1.  */
2803   insn_code_values += 2;
2804
2805   iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2806
2807   for (i = 0; i < MAX_ATTRS_INDEX; i++)
2808     for (attr = attrs[i]; attr; attr = attr->next)
2809       for (av = attr->first_value; av; av = av->next)
2810         for (ie = av->first_insn; ie; ie = ie->next)
2811           {
2812             iv->attr = attr;
2813             iv->av = av;
2814             iv->ie = ie;
2815             iv->next = insn_code_values[ie->def->insn_code];
2816             insn_code_values[ie->def->insn_code] = iv;
2817             iv++;
2818           }
2819
2820   /* Sanity check on num_insn_ents.  */
2821   gcc_assert (iv == ivbuf + num_insn_ents);
2822
2823   /* Process one insn code at a time.  */
2824   for (i = -2; i < insn_code_number; i++)
2825     {
2826       /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2827          We use it to mean "already simplified for this insn".  */
2828       for (iv = insn_code_values[i]; iv; iv = iv->next)
2829         clear_struct_flag (iv->av->value);
2830
2831       for (iv = insn_code_values[i]; iv; iv = iv->next)
2832         {
2833           struct obstack *old = rtl_obstack;
2834
2835           attr = iv->attr;
2836           av = iv->av;
2837           ie = iv->ie;
2838           if (GET_CODE (av->value) != COND)
2839             continue;
2840
2841           rtl_obstack = temp_obstack;
2842           newexp = av->value;
2843           while (GET_CODE (newexp) == COND)
2844             {
2845               rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2846                                            ie->def->insn_index);
2847               if (newexp2 == newexp)
2848                 break;
2849               newexp = newexp2;
2850             }
2851
2852           rtl_obstack = old;
2853           if (newexp != av->value)
2854             {
2855               newexp = attr_copy_rtx (newexp);
2856               remove_insn_ent (av, ie);
2857               av = get_attr_value (newexp, attr, ie->def->insn_code);
2858               iv->av = av;
2859               insert_insn_ent (av, ie);
2860             }
2861         }
2862     }
2863
2864   free (ivbuf);
2865   free (insn_code_values - 2);
2866   insn_code_values = NULL;
2867 }
2868
2869 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions.  */
2870
2871 static void
2872 clear_struct_flag (rtx x)
2873 {
2874   int i;
2875   int j;
2876   enum rtx_code code;
2877   const char *fmt;
2878
2879   ATTR_CURR_SIMPLIFIED_P (x) = 0;
2880   if (ATTR_IND_SIMPLIFIED_P (x))
2881     return;
2882
2883   code = GET_CODE (x);
2884
2885   switch (code)
2886     {
2887     case REG:
2888     case CONST_INT:
2889     case CONST_DOUBLE:
2890     case CONST_VECTOR:
2891     case SYMBOL_REF:
2892     case CODE_LABEL:
2893     case PC:
2894     case CC0:
2895     case EQ_ATTR:
2896     case ATTR_FLAG:
2897       return;
2898
2899     default:
2900       break;
2901     }
2902
2903   /* Compare the elements.  If any pair of corresponding elements
2904      fail to match, return 0 for the whole things.  */
2905
2906   fmt = GET_RTX_FORMAT (code);
2907   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2908     {
2909       switch (fmt[i])
2910         {
2911         case 'V':
2912         case 'E':
2913           for (j = 0; j < XVECLEN (x, i); j++)
2914             clear_struct_flag (XVECEXP (x, i, j));
2915           break;
2916
2917         case 'e':
2918           clear_struct_flag (XEXP (x, i));
2919           break;
2920         }
2921     }
2922 }
2923
2924 /* Create table entries for DEFINE_ATTR.  */
2925
2926 static void
2927 gen_attr (rtx exp, int lineno)
2928 {
2929   struct attr_desc *attr;
2930   struct attr_value *av;
2931   const char *name_ptr;
2932   char *p;
2933
2934   /* Make a new attribute structure.  Check for duplicate by looking at
2935      attr->default_val, since it is initialized by this routine.  */
2936   attr = find_attr (&XSTR (exp, 0), 1);
2937   if (attr->default_val)
2938     {
2939       message_with_line (lineno, "duplicate definition for attribute %s",
2940                          attr->name);
2941       message_with_line (attr->lineno, "previous definition");
2942       have_error = 1;
2943       return;
2944     }
2945   attr->lineno = lineno;
2946
2947   if (*XSTR (exp, 1) == '\0')
2948     attr->is_numeric = 1;
2949   else
2950     {
2951       name_ptr = XSTR (exp, 1);
2952       while ((p = next_comma_elt (&name_ptr)) != NULL)
2953         {
2954           av = oballoc (struct attr_value);
2955           av->value = attr_rtx (CONST_STRING, p);
2956           av->next = attr->first_value;
2957           attr->first_value = av;
2958           av->first_insn = NULL;
2959           av->num_insns = 0;
2960           av->has_asm_insn = 0;
2961         }
2962     }
2963
2964   if (GET_CODE (XEXP (exp, 2)) == CONST)
2965     {
2966       attr->is_const = 1;
2967       if (attr->is_numeric)
2968         {
2969           message_with_line (lineno,
2970                              "constant attributes may not take numeric values");
2971           have_error = 1;
2972         }
2973
2974       /* Get rid of the CONST node.  It is allowed only at top-level.  */
2975       XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
2976     }
2977
2978   if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
2979     {
2980       message_with_line (lineno,
2981                          "`length' attribute must take numeric values");
2982       have_error = 1;
2983     }
2984
2985   /* Set up the default value.  */
2986   XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
2987   attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
2988 }
2989
2990 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2991    alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
2992    number of alternatives as this should be checked elsewhere.  */
2993
2994 static int
2995 count_alternatives (rtx exp)
2996 {
2997   int i, j, n;
2998   const char *fmt;
2999
3000   if (GET_CODE (exp) == MATCH_OPERAND)
3001     return n_comma_elts (XSTR (exp, 2));
3002
3003   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3004        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3005     switch (*fmt++)
3006       {
3007       case 'e':
3008       case 'u':
3009         n = count_alternatives (XEXP (exp, i));
3010         if (n)
3011           return n;
3012         break;
3013
3014       case 'E':
3015       case 'V':
3016         if (XVEC (exp, i) != NULL)
3017           for (j = 0; j < XVECLEN (exp, i); j++)
3018             {
3019               n = count_alternatives (XVECEXP (exp, i, j));
3020               if (n)
3021                 return n;
3022             }
3023       }
3024
3025   return 0;
3026 }
3027
3028 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3029    `alternative' attribute.  */
3030
3031 static int
3032 compares_alternatives_p (rtx exp)
3033 {
3034   int i, j;
3035   const char *fmt;
3036
3037   if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3038     return 1;
3039
3040   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3041        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3042     switch (*fmt++)
3043       {
3044       case 'e':
3045       case 'u':
3046         if (compares_alternatives_p (XEXP (exp, i)))
3047           return 1;
3048         break;
3049
3050       case 'E':
3051         for (j = 0; j < XVECLEN (exp, i); j++)
3052           if (compares_alternatives_p (XVECEXP (exp, i, j)))
3053             return 1;
3054         break;
3055       }
3056
3057   return 0;
3058 }
3059
3060 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
3061
3062 static void
3063 gen_insn (rtx exp, int lineno)
3064 {
3065   struct insn_def *id;
3066
3067   id = oballoc (struct insn_def);
3068   id->next = defs;
3069   defs = id;
3070   id->def = exp;
3071   id->lineno = lineno;
3072
3073   switch (GET_CODE (exp))
3074     {
3075     case DEFINE_INSN:
3076       id->insn_code = insn_code_number;
3077       id->insn_index = insn_index_number;
3078       id->num_alternatives = count_alternatives (exp);
3079       if (id->num_alternatives == 0)
3080         id->num_alternatives = 1;
3081       id->vec_idx = 4;
3082       break;
3083
3084     case DEFINE_PEEPHOLE:
3085       id->insn_code = insn_code_number;
3086       id->insn_index = insn_index_number;
3087       id->num_alternatives = count_alternatives (exp);
3088       if (id->num_alternatives == 0)
3089         id->num_alternatives = 1;
3090       id->vec_idx = 3;
3091       break;
3092
3093     case DEFINE_ASM_ATTRIBUTES:
3094       id->insn_code = -1;
3095       id->insn_index = -1;
3096       id->num_alternatives = 1;
3097       id->vec_idx = 0;
3098       got_define_asm_attributes = 1;
3099       break;
3100
3101     default:
3102       gcc_unreachable ();
3103     }
3104 }
3105
3106 /* Process a DEFINE_DELAY.  Validate the vector length, check if annul
3107    true or annul false is specified, and make a `struct delay_desc'.  */
3108
3109 static void
3110 gen_delay (rtx def, int lineno)
3111 {
3112   struct delay_desc *delay;
3113   int i;
3114
3115   if (XVECLEN (def, 1) % 3 != 0)
3116     {
3117       message_with_line (lineno,
3118                          "number of elements in DEFINE_DELAY must be multiple of three");
3119       have_error = 1;
3120       return;
3121     }
3122
3123   for (i = 0; i < XVECLEN (def, 1); i += 3)
3124     {
3125       if (XVECEXP (def, 1, i + 1))
3126         have_annul_true = 1;
3127       if (XVECEXP (def, 1, i + 2))
3128         have_annul_false = 1;
3129     }
3130
3131   delay = oballoc (struct delay_desc);
3132   delay->def = def;
3133   delay->num = ++num_delays;
3134   delay->next = delays;
3135   delay->lineno = lineno;
3136   delays = delay;
3137 }
3138
3139 /* Given a piece of RTX, print a C expression to test its truth value.
3140    We use AND and IOR both for logical and bit-wise operations, so
3141    interpret them as logical unless they are inside a comparison expression.
3142    The first bit of FLAGS will be nonzero in that case.
3143
3144    Set the second bit of FLAGS to make references to attribute values use
3145    a cached local variable instead of calling a function.  */
3146
3147 static void
3148 write_test_expr (rtx exp, int flags)
3149 {
3150   int comparison_operator = 0;
3151   RTX_CODE code;
3152   struct attr_desc *attr;
3153
3154   /* In order not to worry about operator precedence, surround our part of
3155      the expression with parentheses.  */
3156
3157   printf ("(");
3158   code = GET_CODE (exp);
3159   switch (code)
3160     {
3161     /* Binary operators.  */
3162     case GEU: case GTU:
3163     case LEU: case LTU:
3164       printf ("(unsigned) ");
3165       /* Fall through.  */
3166
3167     case EQ: case NE:
3168     case GE: case GT:
3169     case LE: case LT:
3170       comparison_operator = 1;
3171
3172     case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
3173     case AND:    case IOR:    case XOR:
3174     case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3175       write_test_expr (XEXP (exp, 0), flags | comparison_operator);
3176       switch (code)
3177         {
3178         case EQ:
3179           printf (" == ");
3180           break;
3181         case NE:
3182           printf (" != ");
3183           break;
3184         case GE:
3185           printf (" >= ");
3186           break;
3187         case GT:
3188           printf (" > ");
3189           break;
3190         case GEU:
3191           printf (" >= (unsigned) ");
3192           break;
3193         case GTU:
3194           printf (" > (unsigned) ");
3195           break;
3196         case LE:
3197           printf (" <= ");
3198           break;
3199         case LT:
3200           printf (" < ");
3201           break;
3202         case LEU:
3203           printf (" <= (unsigned) ");
3204           break;
3205         case LTU:
3206           printf (" < (unsigned) ");
3207           break;
3208         case PLUS:
3209           printf (" + ");
3210           break;
3211         case MINUS:
3212           printf (" - ");
3213           break;
3214         case MULT:
3215           printf (" * ");
3216           break;
3217         case DIV:
3218           printf (" / ");
3219           break;
3220         case MOD:
3221           printf (" %% ");
3222           break;
3223         case AND:
3224           if (flags & 1)
3225             printf (" & ");
3226           else
3227             printf (" && ");
3228           break;
3229         case IOR:
3230           if (flags & 1)
3231             printf (" | ");
3232           else
3233             printf (" || ");
3234           break;
3235         case XOR:
3236           printf (" ^ ");
3237           break;
3238         case ASHIFT:
3239           printf (" << ");
3240           break;
3241         case LSHIFTRT:
3242         case ASHIFTRT:
3243           printf (" >> ");
3244           break;
3245         default:
3246           gcc_unreachable ();
3247         }
3248
3249       write_test_expr (XEXP (exp, 1), flags | comparison_operator);
3250       break;
3251
3252     case NOT:
3253       /* Special-case (not (eq_attrq "alternative" "x")) */
3254       if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3255           && XSTR (XEXP (exp, 0), 0) == alternative_name)
3256         {
3257           printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3258           break;
3259         }
3260
3261       /* Otherwise, fall through to normal unary operator.  */
3262
3263     /* Unary operators.  */
3264     case ABS:  case NEG:
3265       switch (code)
3266         {
3267         case NOT:
3268           if (flags & 1)
3269             printf ("~ ");
3270           else
3271             printf ("! ");
3272           break;
3273         case ABS:
3274           printf ("abs ");
3275           break;
3276         case NEG:
3277           printf ("-");
3278           break;
3279         default:
3280           gcc_unreachable ();
3281         }
3282
3283       write_test_expr (XEXP (exp, 0), flags);
3284       break;
3285
3286     case EQ_ATTR_ALT:
3287         {
3288           int set = XINT (exp, 0), bit = 0;
3289
3290           if (flags & 1)
3291             fatal ("EQ_ATTR_ALT not valid inside comparison");
3292
3293           if (!set)
3294             fatal ("Empty EQ_ATTR_ALT should be optimized out");
3295
3296           if (!(set & (set - 1)))
3297             {
3298               if (!(set & 0xffff))
3299                 {
3300                   bit += 16;
3301                   set >>= 16;
3302                 }
3303               if (!(set & 0xff))
3304                 {
3305                   bit += 8;
3306                   set >>= 8;
3307                 }
3308               if (!(set & 0xf))
3309                 {
3310                   bit += 4;
3311                   set >>= 4;
3312                 }
3313               if (!(set & 0x3))
3314                 {
3315                   bit += 2;
3316                   set >>= 2;
3317                 }
3318               if (!(set & 1))
3319                 bit++;
3320
3321               printf ("which_alternative %s= %d",
3322                       XINT (exp, 1) ? "!" : "=", bit);
3323             }
3324           else
3325             {
3326               printf ("%s((1 << which_alternative) & 0x%x)",
3327                       XINT (exp, 1) ? "!" : "", set);
3328             }
3329         }
3330       break;
3331
3332     /* Comparison test of an attribute with a value.  Most of these will
3333        have been removed by optimization.   Handle "alternative"
3334        specially and give error if EQ_ATTR present inside a comparison.  */
3335     case EQ_ATTR:
3336       if (flags & 1)
3337         fatal ("EQ_ATTR not valid inside comparison");
3338
3339       if (XSTR (exp, 0) == alternative_name)
3340         {
3341           printf ("which_alternative == %s", XSTR (exp, 1));
3342           break;
3343         }
3344
3345       attr = find_attr (&XSTR (exp, 0), 0);
3346       gcc_assert (attr);
3347
3348       /* Now is the time to expand the value of a constant attribute.  */
3349       if (attr->is_const)
3350         {
3351           write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
3352                                              -2, -2),
3353                            flags);
3354         }
3355       else
3356         {
3357           if (flags & 2)
3358             printf ("attr_%s", attr->name);
3359           else
3360             printf ("get_attr_%s (insn)", attr->name);
3361           printf (" == ");
3362           write_attr_valueq (attr, XSTR (exp, 1));
3363         }
3364       break;
3365
3366     /* Comparison test of flags for define_delays.  */
3367     case ATTR_FLAG:
3368       if (flags & 1)
3369         fatal ("ATTR_FLAG not valid inside comparison");
3370       printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3371       break;
3372
3373     /* See if an operand matches a predicate.  */
3374     case MATCH_OPERAND:
3375       /* If only a mode is given, just ensure the mode matches the operand.
3376          If neither a mode nor predicate is given, error.  */
3377       if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3378         {
3379           if (GET_MODE (exp) == VOIDmode)
3380             fatal ("null MATCH_OPERAND specified as test");
3381           else
3382             printf ("GET_MODE (operands[%d]) == %smode",
3383                     XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3384         }
3385       else
3386         printf ("%s (operands[%d], %smode)",
3387                 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3388       break;
3389
3390     /* Constant integer.  */
3391     case CONST_INT:
3392       printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3393       break;
3394
3395     /* A random C expression.  */
3396     case SYMBOL_REF:
3397       print_c_condition (XSTR (exp, 0));
3398       break;
3399
3400     /* The address of the branch target.  */
3401     case MATCH_DUP:
3402       printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3403               XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3404       break;
3405
3406     case PC:
3407       /* The address of the current insn.  We implement this actually as the
3408          address of the current insn for backward branches, but the last
3409          address of the next insn for forward branches, and both with
3410          adjustments that account for the worst-case possible stretching of
3411          intervening alignments between this insn and its destination.  */
3412       printf ("insn_current_reference_address (insn)");
3413       break;
3414
3415     case CONST_STRING:
3416       printf ("%s", XSTR (exp, 0));
3417       break;
3418
3419     case IF_THEN_ELSE:
3420       write_test_expr (XEXP (exp, 0), flags & 2);
3421       printf (" ? ");
3422       write_test_expr (XEXP (exp, 1), flags | 1);
3423       printf (" : ");
3424       write_test_expr (XEXP (exp, 2), flags | 1);
3425       break;
3426
3427     default:
3428       fatal ("bad RTX code `%s' in attribute calculation\n",
3429              GET_RTX_NAME (code));
3430     }
3431
3432   printf (")");
3433 }
3434
3435 /* Given an attribute value, return the maximum CONST_STRING argument
3436    encountered.  Set *UNKNOWNP and return INT_MAX if the value is unknown.  */
3437
3438 static int
3439 max_attr_value (rtx exp, int *unknownp)
3440 {
3441   int current_max;
3442   int i, n;
3443
3444   switch (GET_CODE (exp))
3445     {
3446     case CONST_STRING:
3447       current_max = atoi (XSTR (exp, 0));
3448       break;
3449
3450     case COND:
3451       current_max = max_attr_value (XEXP (exp, 1), unknownp);
3452       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3453         {
3454           n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3455           if (n > current_max)
3456             current_max = n;
3457         }
3458       break;
3459
3460     case IF_THEN_ELSE:
3461       current_max = max_attr_value (XEXP (exp, 1), unknownp);
3462       n = max_attr_value (XEXP (exp, 2), unknownp);
3463       if (n > current_max)
3464         current_max = n;
3465       break;
3466
3467     default:
3468       *unknownp = 1;
3469       current_max = INT_MAX;
3470       break;
3471     }
3472
3473   return current_max;
3474 }
3475
3476 /* Given an attribute value, return the minimum CONST_STRING argument
3477    encountered.  Set *UNKNOWNP and return 0 if the value is unknown.  */
3478
3479 static int
3480 min_attr_value (rtx exp, int *unknownp)
3481 {
3482   int current_min;
3483   int i, n;
3484
3485   switch (GET_CODE (exp))
3486     {
3487     case CONST_STRING:
3488       current_min = atoi (XSTR (exp, 0));
3489       break;
3490
3491     case COND:
3492       current_min = min_attr_value (XEXP (exp, 1), unknownp);
3493       for (i = 0; i < XVECLEN (exp, 0); i += 2)
3494         {
3495           n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3496           if (n < current_min)
3497             current_min = n;
3498         }
3499       break;
3500
3501     case IF_THEN_ELSE:
3502       current_min = min_attr_value (XEXP (exp, 1), unknownp);
3503       n = min_attr_value (XEXP (exp, 2), unknownp);
3504       if (n < current_min)
3505         current_min = n;
3506       break;
3507
3508     default:
3509       *unknownp = 1;
3510       current_min = INT_MAX;
3511       break;
3512     }
3513
3514   return current_min;
3515 }
3516
3517 /* Given an attribute value, return the result of ORing together all
3518    CONST_STRING arguments encountered.  Set *UNKNOWNP and return -1
3519    if the numeric value is not known.  */
3520
3521 static int
3522 or_attr_value (rtx exp, int *unknownp)
3523 {
3524   int current_or;
3525   int i;
3526