2011-10-07 Tom de Vries <tom@codesourcery.com>
[official-gcc.git] / gcc / genattrtab.c
blob4a4c2a2c8aaa6fd759ad12fc06d941f765f28293
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, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
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.
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.
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/>. */
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
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.
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).
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.
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'.
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.
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
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.
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.
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.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
77 will be written.
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).
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). */
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))
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
107 #include "bconfig.h"
108 #include "system.h"
109 #include "coretypes.h"
110 #include "tm.h"
111 #include "rtl.h"
112 #include "obstack.h"
113 #include "errors.h"
114 #include "read-md.h"
115 #include "gensupport.h"
116 #include "vecprim.h"
117 #include "fnmatch.h"
119 /* Flags for make_internal_attr's `special' parameter. */
120 #define ATTR_NONE 0
121 #define ATTR_SPECIAL (1 << 0)
123 static struct obstack obstack1, obstack2;
124 static struct obstack *hash_obstack = &obstack1;
125 static struct obstack *temp_obstack = &obstack2;
127 /* enough space to reserve for printing out ints */
128 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
130 /* Define structures used to record attributes and values. */
132 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
133 encountered, we store all the relevant information into a
134 `struct insn_def'. This is done to allow attribute definitions to occur
135 anywhere in the file. */
137 struct insn_def
139 struct insn_def *next; /* Next insn in chain. */
140 rtx def; /* The DEFINE_... */
141 int insn_code; /* Instruction number. */
142 int insn_index; /* Expression number in file, for errors. */
143 int lineno; /* Line number. */
144 int num_alternatives; /* Number of alternatives. */
145 int vec_idx; /* Index of attribute vector in `def'. */
148 /* Once everything has been read in, we store in each attribute value a list
149 of insn codes that have that value. Here is the structure used for the
150 list. */
152 struct insn_ent
154 struct insn_ent *next; /* Next in chain. */
155 struct insn_def *def; /* Instruction definition. */
158 /* Each value of an attribute (either constant or computed) is assigned a
159 structure which is used as the listhead of the insns that have that
160 value. */
162 struct attr_value
164 rtx value; /* Value of attribute. */
165 struct attr_value *next; /* Next attribute value in chain. */
166 struct insn_ent *first_insn; /* First insn with this value. */
167 int num_insns; /* Number of insns with this value. */
168 int has_asm_insn; /* True if this value used for `asm' insns */
171 /* Structure for each attribute. */
173 struct attr_desc
175 char *name; /* Name of attribute. */
176 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */
177 struct attr_desc *next; /* Next attribute. */
178 struct attr_value *first_value; /* First value of this attribute. */
179 struct attr_value *default_val; /* Default value for this attribute. */
180 int lineno : 24; /* Line number. */
181 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
182 unsigned is_const : 1; /* Attribute value constant for each run. */
183 unsigned is_special : 1; /* Don't call `write_attr_set'. */
186 /* Structure for each DEFINE_DELAY. */
188 struct delay_desc
190 rtx def; /* DEFINE_DELAY expression. */
191 struct delay_desc *next; /* Next DEFINE_DELAY. */
192 int num; /* Number of DEFINE_DELAY, starting at 1. */
193 int lineno; /* Line number. */
196 struct attr_value_list
198 struct attr_value *av;
199 struct insn_ent *ie;
200 struct attr_desc *attr;
201 struct attr_value_list *next;
204 /* Listheads of above structures. */
206 /* This one is indexed by the first character of the attribute name. */
207 #define MAX_ATTRS_INDEX 256
208 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
209 static struct insn_def *defs;
210 static struct delay_desc *delays;
211 struct attr_value_list **insn_code_values;
213 /* Other variables. */
215 static int insn_code_number;
216 static int insn_index_number;
217 static int got_define_asm_attributes;
218 static int must_extract;
219 static int must_constrain;
220 static int address_used;
221 static int length_used;
222 static int num_delays;
223 static int have_annul_true, have_annul_false;
224 static int num_insn_ents;
226 /* Stores, for each insn code, the number of constraint alternatives. */
228 static int *insn_n_alternatives;
230 /* Stores, for each insn code, a bitmap that has bits on for each possible
231 alternative. */
233 static int *insn_alternatives;
235 /* Used to simplify expressions. */
237 static rtx true_rtx, false_rtx;
239 /* Used to reduce calls to `strcmp' */
241 static const char *alternative_name;
242 static const char *length_str;
243 static const char *delay_type_str;
244 static const char *delay_1_0_str;
245 static const char *num_delay_slots_str;
247 /* Simplify an expression. Only call the routine if there is something to
248 simplify. */
249 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
250 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
251 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
253 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
255 /* Forward declarations of functions used before their definitions, only. */
256 static char *attr_string (const char *, int);
257 static char *attr_printf (unsigned int, const char *, ...)
258 ATTRIBUTE_PRINTF_2;
259 static rtx make_numeric_value (int);
260 static struct attr_desc *find_attr (const char **, int);
261 static rtx mk_attr_alt (int);
262 static char *next_comma_elt (const char **);
263 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
264 static rtx copy_boolean (rtx);
265 static int compares_alternatives_p (rtx);
266 static void make_internal_attr (const char *, rtx, int);
267 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
268 static void walk_attr_value (rtx);
269 static int max_attr_value (rtx, int*);
270 static int min_attr_value (rtx, int*);
271 static int or_attr_value (rtx, int*);
272 static rtx simplify_test_exp (rtx, int, int);
273 static rtx simplify_test_exp_in_temp (rtx, int, int);
274 static rtx copy_rtx_unchanging (rtx);
275 static bool attr_alt_subset_p (rtx, rtx);
276 static bool attr_alt_subset_of_compl_p (rtx, rtx);
277 static void clear_struct_flag (rtx);
278 static void write_attr_valueq (struct attr_desc *, const char *);
279 static struct attr_value *find_most_used (struct attr_desc *);
280 static void write_attr_set (struct attr_desc *, int, rtx,
281 const char *, const char *, rtx,
282 int, int, unsigned int);
283 static void write_attr_case (struct attr_desc *, struct attr_value *,
284 int, const char *, const char *, int, rtx);
285 static void write_attr_value (struct attr_desc *, rtx);
286 static void write_upcase (const char *);
287 static void write_indent (int);
288 static rtx identity_fn (rtx);
289 static rtx zero_fn (rtx);
290 static rtx one_fn (rtx);
291 static rtx max_fn (rtx);
292 static rtx min_fn (rtx);
294 #define oballoc(T) XOBNEW (hash_obstack, T)
295 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
297 /* Hash table for sharing RTL and strings. */
299 /* Each hash table slot is a bucket containing a chain of these structures.
300 Strings are given negative hash codes; RTL expressions are given positive
301 hash codes. */
303 struct attr_hash
305 struct attr_hash *next; /* Next structure in the bucket. */
306 int hashcode; /* Hash code of this rtx or string. */
307 union
309 char *str; /* The string (negative hash codes) */
310 rtx rtl; /* or the RTL recorded here. */
311 } u;
314 /* Now here is the hash table. When recording an RTL, it is added to
315 the slot whose index is the hash code mod the table size. Note
316 that the hash table is used for several kinds of RTL (see attr_rtx)
317 and for strings. While all these live in the same table, they are
318 completely independent, and the hash code is computed differently
319 for each. */
321 #define RTL_HASH_SIZE 4093
322 static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
324 /* Here is how primitive or already-shared RTL's hash
325 codes are made. */
326 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
328 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
330 static void
331 attr_hash_add_rtx (int hashcode, rtx rtl)
333 struct attr_hash *h;
335 h = XOBNEW (hash_obstack, struct attr_hash);
336 h->hashcode = hashcode;
337 h->u.rtl = rtl;
338 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
339 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
342 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
344 static void
345 attr_hash_add_string (int hashcode, char *str)
347 struct attr_hash *h;
349 h = XOBNEW (hash_obstack, struct attr_hash);
350 h->hashcode = -hashcode;
351 h->u.str = str;
352 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
353 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
356 /* Generate an RTL expression, but avoid duplicates.
357 Set the ATTR_PERMANENT_P flag for these permanent objects.
359 In some cases we cannot uniquify; then we return an ordinary
360 impermanent rtx with ATTR_PERMANENT_P clear.
362 Args are as follows:
364 rtx attr_rtx (code, [element1, ..., elementn]) */
366 static rtx
367 attr_rtx_1 (enum rtx_code code, va_list p)
369 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
370 int hashcode;
371 struct attr_hash *h;
372 struct obstack *old_obstack = rtl_obstack;
374 /* For each of several cases, search the hash table for an existing entry.
375 Use that entry if one is found; otherwise create a new RTL and add it
376 to the table. */
378 if (GET_RTX_CLASS (code) == RTX_UNARY)
380 rtx arg0 = va_arg (p, rtx);
382 /* A permanent object cannot point to impermanent ones. */
383 if (! ATTR_PERMANENT_P (arg0))
385 rt_val = rtx_alloc (code);
386 XEXP (rt_val, 0) = arg0;
387 return rt_val;
390 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
391 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
392 if (h->hashcode == hashcode
393 && GET_CODE (h->u.rtl) == code
394 && XEXP (h->u.rtl, 0) == arg0)
395 return h->u.rtl;
397 if (h == 0)
399 rtl_obstack = hash_obstack;
400 rt_val = rtx_alloc (code);
401 XEXP (rt_val, 0) = arg0;
404 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
405 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
406 || GET_RTX_CLASS (code) == RTX_COMPARE
407 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
409 rtx arg0 = va_arg (p, rtx);
410 rtx arg1 = va_arg (p, rtx);
412 /* A permanent object cannot point to impermanent ones. */
413 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
415 rt_val = rtx_alloc (code);
416 XEXP (rt_val, 0) = arg0;
417 XEXP (rt_val, 1) = arg1;
418 return rt_val;
421 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
422 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
423 if (h->hashcode == hashcode
424 && GET_CODE (h->u.rtl) == code
425 && XEXP (h->u.rtl, 0) == arg0
426 && XEXP (h->u.rtl, 1) == arg1)
427 return h->u.rtl;
429 if (h == 0)
431 rtl_obstack = hash_obstack;
432 rt_val = rtx_alloc (code);
433 XEXP (rt_val, 0) = arg0;
434 XEXP (rt_val, 1) = arg1;
437 else if (code == SYMBOL_REF
438 || (GET_RTX_LENGTH (code) == 1
439 && GET_RTX_FORMAT (code)[0] == 's'))
441 char *arg0 = va_arg (p, char *);
443 arg0 = DEF_ATTR_STRING (arg0);
445 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
446 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
447 if (h->hashcode == hashcode
448 && GET_CODE (h->u.rtl) == code
449 && XSTR (h->u.rtl, 0) == arg0)
450 return h->u.rtl;
452 if (h == 0)
454 rtl_obstack = hash_obstack;
455 rt_val = rtx_alloc (code);
456 XSTR (rt_val, 0) = arg0;
457 if (code == SYMBOL_REF)
459 X0EXP (rt_val, 1) = NULL_RTX;
460 X0EXP (rt_val, 2) = NULL_RTX;
464 else if (GET_RTX_LENGTH (code) == 2
465 && GET_RTX_FORMAT (code)[0] == 's'
466 && GET_RTX_FORMAT (code)[1] == 's')
468 char *arg0 = va_arg (p, char *);
469 char *arg1 = va_arg (p, char *);
471 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
472 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
473 if (h->hashcode == hashcode
474 && GET_CODE (h->u.rtl) == code
475 && XSTR (h->u.rtl, 0) == arg0
476 && XSTR (h->u.rtl, 1) == arg1)
477 return h->u.rtl;
479 if (h == 0)
481 rtl_obstack = hash_obstack;
482 rt_val = rtx_alloc (code);
483 XSTR (rt_val, 0) = arg0;
484 XSTR (rt_val, 1) = arg1;
487 else if (code == CONST_INT)
489 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
490 if (arg0 == 0)
491 return false_rtx;
492 else if (arg0 == 1)
493 return true_rtx;
494 else
495 goto nohash;
497 else
499 int i; /* Array indices... */
500 const char *fmt; /* Current rtx's format... */
501 nohash:
502 rt_val = rtx_alloc (code); /* Allocate the storage space. */
504 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
505 for (i = 0; i < GET_RTX_LENGTH (code); i++)
507 switch (*fmt++)
509 case '0': /* Unused field. */
510 break;
512 case 'i': /* An integer? */
513 XINT (rt_val, i) = va_arg (p, int);
514 break;
516 case 'w': /* A wide integer? */
517 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
518 break;
520 case 's': /* A string? */
521 XSTR (rt_val, i) = va_arg (p, char *);
522 break;
524 case 'e': /* An expression? */
525 case 'u': /* An insn? Same except when printing. */
526 XEXP (rt_val, i) = va_arg (p, rtx);
527 break;
529 case 'E': /* An RTX vector? */
530 XVEC (rt_val, i) = va_arg (p, rtvec);
531 break;
533 default:
534 gcc_unreachable ();
537 return rt_val;
540 rtl_obstack = old_obstack;
541 attr_hash_add_rtx (hashcode, rt_val);
542 ATTR_PERMANENT_P (rt_val) = 1;
543 return rt_val;
546 static rtx
547 attr_rtx (enum rtx_code code, ...)
549 rtx result;
550 va_list p;
552 va_start (p, code);
553 result = attr_rtx_1 (code, p);
554 va_end (p);
555 return result;
558 /* Create a new string printed with the printf line arguments into a space
559 of at most LEN bytes:
561 rtx attr_printf (len, format, [arg1, ..., argn]) */
563 static char *
564 attr_printf (unsigned int len, const char *fmt, ...)
566 char str[256];
567 va_list p;
569 va_start (p, fmt);
571 gcc_assert (len < sizeof str); /* Leave room for \0. */
573 vsprintf (str, fmt, p);
574 va_end (p);
576 return DEF_ATTR_STRING (str);
579 static rtx
580 attr_eq (const char *name, const char *value)
582 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
585 static const char *
586 attr_numeral (int n)
588 return XSTR (make_numeric_value (n), 0);
591 /* Return a permanent (possibly shared) copy of a string STR (not assumed
592 to be null terminated) with LEN bytes. */
594 static char *
595 attr_string (const char *str, int len)
597 struct attr_hash *h;
598 int hashcode;
599 int i;
600 char *new_str;
602 /* Compute the hash code. */
603 hashcode = (len + 1) * 613 + (unsigned) str[0];
604 for (i = 1; i < len; i += 2)
605 hashcode = ((hashcode * 613) + (unsigned) str[i]);
606 if (hashcode < 0)
607 hashcode = -hashcode;
609 /* Search the table for the string. */
610 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
611 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
612 && !strncmp (h->u.str, str, len))
613 return h->u.str; /* <-- return if found. */
615 /* Not found; create a permanent copy and add it to the hash table. */
616 new_str = XOBNEWVAR (hash_obstack, char, len + 1);
617 memcpy (new_str, str, len);
618 new_str[len] = '\0';
619 attr_hash_add_string (hashcode, new_str);
620 copy_md_ptr_loc (new_str, str);
622 return new_str; /* Return the new string. */
625 /* Check two rtx's for equality of contents,
626 taking advantage of the fact that if both are hashed
627 then they can't be equal unless they are the same object. */
629 static int
630 attr_equal_p (rtx x, rtx y)
632 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
633 && rtx_equal_p (x, y)));
636 /* Copy an attribute value expression,
637 descending to all depths, but not copying any
638 permanent hashed subexpressions. */
640 static rtx
641 attr_copy_rtx (rtx orig)
643 rtx copy;
644 int i, j;
645 RTX_CODE code;
646 const char *format_ptr;
648 /* No need to copy a permanent object. */
649 if (ATTR_PERMANENT_P (orig))
650 return orig;
652 code = GET_CODE (orig);
654 switch (code)
656 case REG:
657 case CONST_INT:
658 case CONST_DOUBLE:
659 case CONST_VECTOR:
660 case SYMBOL_REF:
661 case MATCH_TEST:
662 case CODE_LABEL:
663 case PC:
664 case CC0:
665 return orig;
667 default:
668 break;
671 copy = rtx_alloc (code);
672 PUT_MODE (copy, GET_MODE (orig));
673 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
674 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
675 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
677 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
679 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
681 switch (*format_ptr++)
683 case 'e':
684 XEXP (copy, i) = XEXP (orig, i);
685 if (XEXP (orig, i) != NULL)
686 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
687 break;
689 case 'E':
690 case 'V':
691 XVEC (copy, i) = XVEC (orig, i);
692 if (XVEC (orig, i) != NULL)
694 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
695 for (j = 0; j < XVECLEN (copy, i); j++)
696 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
698 break;
700 case 'n':
701 case 'i':
702 XINT (copy, i) = XINT (orig, i);
703 break;
705 case 'w':
706 XWINT (copy, i) = XWINT (orig, i);
707 break;
709 case 's':
710 case 'S':
711 XSTR (copy, i) = XSTR (orig, i);
712 break;
714 default:
715 gcc_unreachable ();
718 return copy;
721 /* Given a test expression for an attribute, ensure it is validly formed.
722 IS_CONST indicates whether the expression is constant for each compiler
723 run (a constant expression may not test any particular insn).
725 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
726 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
727 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
729 Update the string address in EQ_ATTR expression to be the same used
730 in the attribute (or `alternative_name') to speed up subsequent
731 `find_attr' calls and eliminate most `strcmp' calls.
733 Return the new expression, if any. */
735 static rtx
736 check_attr_test (rtx exp, int is_const, int lineno)
738 struct attr_desc *attr;
739 struct attr_value *av;
740 const char *name_ptr, *p;
741 rtx orexp, newexp;
743 switch (GET_CODE (exp))
745 case EQ_ATTR:
746 /* Handle negation test. */
747 if (XSTR (exp, 1)[0] == '!')
748 return check_attr_test (attr_rtx (NOT,
749 attr_eq (XSTR (exp, 0),
750 &XSTR (exp, 1)[1])),
751 is_const, lineno);
753 else if (n_comma_elts (XSTR (exp, 1)) == 1)
755 attr = find_attr (&XSTR (exp, 0), 0);
756 if (attr == NULL)
758 if (! strcmp (XSTR (exp, 0), "alternative"))
759 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
760 else
761 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
764 if (is_const && ! attr->is_const)
765 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
766 XSTR (exp, 0));
768 /* Copy this just to make it permanent,
769 so expressions using it can be permanent too. */
770 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
772 /* It shouldn't be possible to simplify the value given to a
773 constant attribute, so don't expand this until it's time to
774 write the test expression. */
775 if (attr->is_const)
776 ATTR_IND_SIMPLIFIED_P (exp) = 1;
778 if (attr->is_numeric)
780 for (p = XSTR (exp, 1); *p; p++)
781 if (! ISDIGIT (*p))
782 fatal ("attribute `%s' takes only numeric values",
783 XSTR (exp, 0));
785 else
787 for (av = attr->first_value; av; av = av->next)
788 if (GET_CODE (av->value) == CONST_STRING
789 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
790 break;
792 if (av == NULL)
793 fatal ("unknown value `%s' for `%s' attribute",
794 XSTR (exp, 1), XSTR (exp, 0));
797 else
799 if (! strcmp (XSTR (exp, 0), "alternative"))
801 int set = 0;
803 name_ptr = XSTR (exp, 1);
804 while ((p = next_comma_elt (&name_ptr)) != NULL)
805 set |= 1 << atoi (p);
807 return mk_attr_alt (set);
809 else
811 /* Make an IOR tree of the possible values. */
812 orexp = false_rtx;
813 name_ptr = XSTR (exp, 1);
814 while ((p = next_comma_elt (&name_ptr)) != NULL)
816 newexp = attr_eq (XSTR (exp, 0), p);
817 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
820 return check_attr_test (orexp, is_const, lineno);
823 break;
825 case ATTR_FLAG:
826 break;
828 case CONST_INT:
829 /* Either TRUE or FALSE. */
830 if (XWINT (exp, 0))
831 return true_rtx;
832 else
833 return false_rtx;
835 case IOR:
836 case AND:
837 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
838 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
839 break;
841 case NOT:
842 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
843 break;
845 case MATCH_TEST:
846 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
847 ATTR_IND_SIMPLIFIED_P (exp) = 1;
848 break;
850 case MATCH_OPERAND:
851 if (is_const)
852 fatal ("RTL operator \"%s\" not valid in constant attribute test",
853 GET_RTX_NAME (GET_CODE (exp)));
854 /* These cases can't be simplified. */
855 ATTR_IND_SIMPLIFIED_P (exp) = 1;
856 break;
858 case LE: case LT: case GT: case GE:
859 case LEU: case LTU: case GTU: case GEU:
860 case NE: case EQ:
861 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
862 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
863 exp = attr_rtx (GET_CODE (exp),
864 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
865 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
866 /* These cases can't be simplified. */
867 ATTR_IND_SIMPLIFIED_P (exp) = 1;
868 break;
870 case SYMBOL_REF:
871 if (is_const)
873 /* These cases are valid for constant attributes, but can't be
874 simplified. */
875 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
876 ATTR_IND_SIMPLIFIED_P (exp) = 1;
877 break;
879 default:
880 fatal ("RTL operator \"%s\" not valid in attribute test",
881 GET_RTX_NAME (GET_CODE (exp)));
884 return exp;
887 /* Given an expression, ensure that it is validly formed and that all named
888 attribute values are valid for the given attribute. Issue a fatal error
889 if not. If no attribute is specified, assume a numeric attribute.
891 Return a perhaps modified replacement expression for the value. */
893 static rtx
894 check_attr_value (rtx exp, struct attr_desc *attr)
896 struct attr_value *av;
897 const char *p;
898 int i;
900 switch (GET_CODE (exp))
902 case CONST_INT:
903 if (attr && ! attr->is_numeric)
905 error_with_line (attr->lineno,
906 "CONST_INT not valid for non-numeric attribute %s",
907 attr->name);
908 break;
911 if (INTVAL (exp) < 0)
913 error_with_line (attr->lineno,
914 "negative numeric value specified for attribute %s",
915 attr->name);
916 break;
918 break;
920 case CONST_STRING:
921 if (! strcmp (XSTR (exp, 0), "*"))
922 break;
924 if (attr == 0 || attr->is_numeric)
926 p = XSTR (exp, 0);
927 for (; *p; p++)
928 if (! ISDIGIT (*p))
930 error_with_line (attr ? attr->lineno : 0,
931 "non-numeric value for numeric attribute %s",
932 attr ? attr->name : "internal");
933 break;
935 break;
938 for (av = attr->first_value; av; av = av->next)
939 if (GET_CODE (av->value) == CONST_STRING
940 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
941 break;
943 if (av == NULL)
944 error_with_line (attr->lineno,
945 "unknown value `%s' for `%s' attribute",
946 XSTR (exp, 0), attr ? attr->name : "internal");
947 break;
949 case IF_THEN_ELSE:
950 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
951 attr ? attr->is_const : 0,
952 attr ? attr->lineno : 0);
953 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
954 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
955 break;
957 case PLUS:
958 case MINUS:
959 case MULT:
960 case DIV:
961 case MOD:
962 if (attr && !attr->is_numeric)
964 error_with_line (attr->lineno,
965 "invalid operation `%s' for non-numeric"
966 " attribute value", GET_RTX_NAME (GET_CODE (exp)));
967 break;
969 /* Fall through. */
971 case IOR:
972 case AND:
973 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
974 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
975 break;
977 case FFS:
978 case CLZ:
979 case CTZ:
980 case POPCOUNT:
981 case PARITY:
982 case BSWAP:
983 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
984 break;
986 case COND:
987 if (XVECLEN (exp, 0) % 2 != 0)
989 error_with_line (attr->lineno,
990 "first operand of COND must have even length");
991 break;
994 for (i = 0; i < XVECLEN (exp, 0); i += 2)
996 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
997 attr ? attr->is_const : 0,
998 attr ? attr->lineno : 0);
999 XVECEXP (exp, 0, i + 1)
1000 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1003 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1004 break;
1006 case ATTR:
1008 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1009 if (attr2 == NULL)
1010 error_with_line (attr ? attr->lineno : 0,
1011 "unknown attribute `%s' in ATTR",
1012 XSTR (exp, 0));
1013 else if (attr && attr->is_const && ! attr2->is_const)
1014 error_with_line (attr->lineno,
1015 "non-constant attribute `%s' referenced from `%s'",
1016 XSTR (exp, 0), attr->name);
1017 else if (attr
1018 && attr->is_numeric != attr2->is_numeric)
1019 error_with_line (attr->lineno,
1020 "numeric attribute mismatch calling `%s' from `%s'",
1021 XSTR (exp, 0), attr->name);
1023 break;
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));
1031 default:
1032 error_with_line (attr ? attr->lineno : 0,
1033 "invalid operation `%s' for attribute value",
1034 GET_RTX_NAME (GET_CODE (exp)));
1035 break;
1038 return exp;
1041 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1042 It becomes a COND with each test being (eq_attr "alternative" "n") */
1044 static rtx
1045 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1047 int num_alt = id->num_alternatives;
1048 rtx condexp;
1049 int i;
1051 if (XVECLEN (exp, 1) != num_alt)
1053 error_with_line (id->lineno,
1054 "bad number of entries in SET_ATTR_ALTERNATIVE");
1055 return NULL_RTX;
1058 /* Make a COND with all tests but the last. Select the last value via the
1059 default. */
1060 condexp = rtx_alloc (COND);
1061 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1063 for (i = 0; i < num_alt - 1; i++)
1065 const char *p;
1066 p = attr_numeral (i);
1068 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1069 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1072 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1074 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1077 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1078 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1080 static rtx
1081 convert_set_attr (rtx exp, struct insn_def *id)
1083 rtx newexp;
1084 const char *name_ptr;
1085 char *p;
1086 int n;
1088 /* See how many alternative specified. */
1089 n = n_comma_elts (XSTR (exp, 1));
1090 if (n == 1)
1091 return attr_rtx (SET,
1092 attr_rtx (ATTR, XSTR (exp, 0)),
1093 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1095 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1096 XSTR (newexp, 0) = XSTR (exp, 0);
1097 XVEC (newexp, 1) = rtvec_alloc (n);
1099 /* Process each comma-separated name. */
1100 name_ptr = XSTR (exp, 1);
1101 n = 0;
1102 while ((p = next_comma_elt (&name_ptr)) != NULL)
1103 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1105 return convert_set_attr_alternative (newexp, id);
1108 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1109 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1110 expressions. */
1112 static void
1113 check_defs (void)
1115 struct insn_def *id;
1116 struct attr_desc *attr;
1117 int i;
1118 rtx value;
1120 for (id = defs; id; id = id->next)
1122 if (XVEC (id->def, id->vec_idx) == NULL)
1123 continue;
1125 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1127 value = XVECEXP (id->def, id->vec_idx, i);
1128 switch (GET_CODE (value))
1130 case SET:
1131 if (GET_CODE (XEXP (value, 0)) != ATTR)
1133 error_with_line (id->lineno, "bad attribute set");
1134 value = NULL_RTX;
1136 break;
1138 case SET_ATTR_ALTERNATIVE:
1139 value = convert_set_attr_alternative (value, id);
1140 break;
1142 case SET_ATTR:
1143 value = convert_set_attr (value, id);
1144 break;
1146 default:
1147 error_with_line (id->lineno, "invalid attribute code %s",
1148 GET_RTX_NAME (GET_CODE (value)));
1149 value = NULL_RTX;
1151 if (value == NULL_RTX)
1152 continue;
1154 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1156 error_with_line (id->lineno, "unknown attribute %s",
1157 XSTR (XEXP (value, 0), 0));
1158 continue;
1161 XVECEXP (id->def, id->vec_idx, i) = value;
1162 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1167 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1168 expressions by converting them into a COND. This removes cases from this
1169 program. Also, replace an attribute value of "*" with the default attribute
1170 value. */
1172 static rtx
1173 make_canonical (struct attr_desc *attr, rtx exp)
1175 int i;
1176 rtx newexp;
1178 switch (GET_CODE (exp))
1180 case CONST_INT:
1181 exp = make_numeric_value (INTVAL (exp));
1182 break;
1184 case CONST_STRING:
1185 if (! strcmp (XSTR (exp, 0), "*"))
1187 if (attr == 0 || attr->default_val == 0)
1188 fatal ("(attr_value \"*\") used in invalid context");
1189 exp = attr->default_val->value;
1191 else
1192 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1194 break;
1196 case SYMBOL_REF:
1197 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1198 break;
1199 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1200 This makes the COND something that won't be considered an arbitrary
1201 expression by walk_attr_value. */
1202 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1203 exp = check_attr_value (exp, attr);
1204 break;
1206 case IF_THEN_ELSE:
1207 newexp = rtx_alloc (COND);
1208 XVEC (newexp, 0) = rtvec_alloc (2);
1209 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1210 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1212 XEXP (newexp, 1) = XEXP (exp, 2);
1214 exp = newexp;
1215 /* Fall through to COND case since this is now a COND. */
1217 case COND:
1219 int allsame = 1;
1220 rtx defval;
1222 /* First, check for degenerate COND. */
1223 if (XVECLEN (exp, 0) == 0)
1224 return make_canonical (attr, XEXP (exp, 1));
1225 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1227 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1229 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1230 XVECEXP (exp, 0, i + 1)
1231 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1232 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1233 allsame = 0;
1235 if (allsame)
1236 return defval;
1238 break;
1240 default:
1241 break;
1244 return exp;
1247 static rtx
1248 copy_boolean (rtx exp)
1250 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1251 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1252 copy_boolean (XEXP (exp, 1)));
1253 if (GET_CODE (exp) == MATCH_OPERAND)
1255 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1256 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1258 else if (GET_CODE (exp) == EQ_ATTR)
1260 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1261 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1264 return exp;
1267 /* Given a value and an attribute description, return a `struct attr_value *'
1268 that represents that value. This is either an existing structure, if the
1269 value has been previously encountered, or a newly-created structure.
1271 `insn_code' is the code of an insn whose attribute has the specified
1272 value (-2 if not processing an insn). We ensure that all insns for
1273 a given value have the same number of alternatives if the value checks
1274 alternatives. */
1276 static struct attr_value *
1277 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1279 struct attr_value *av;
1280 int num_alt = 0;
1282 value = make_canonical (attr, value);
1283 if (compares_alternatives_p (value))
1285 if (insn_code < 0 || insn_alternatives == NULL)
1286 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1287 else
1288 num_alt = insn_alternatives[insn_code];
1291 for (av = attr->first_value; av; av = av->next)
1292 if (rtx_equal_p (value, av->value)
1293 && (num_alt == 0 || av->first_insn == NULL
1294 || insn_alternatives[av->first_insn->def->insn_code]))
1295 return av;
1297 av = oballoc (struct attr_value);
1298 av->value = value;
1299 av->next = attr->first_value;
1300 attr->first_value = av;
1301 av->first_insn = NULL;
1302 av->num_insns = 0;
1303 av->has_asm_insn = 0;
1305 return av;
1308 /* After all DEFINE_DELAYs have been read in, create internal attributes
1309 to generate the required routines.
1311 First, we compute the number of delay slots for each insn (as a COND of
1312 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1313 delay type is specified, we compute a similar function giving the
1314 DEFINE_DELAY ordinal for each insn.
1316 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1317 tells whether a given insn can be in that delay slot.
1319 Normal attribute filling and optimization expands these to contain the
1320 information needed to handle delay slots. */
1322 static void
1323 expand_delays (void)
1325 struct delay_desc *delay;
1326 rtx condexp;
1327 rtx newexp;
1328 int i;
1329 char *p;
1331 /* First, generate data for `num_delay_slots' function. */
1333 condexp = rtx_alloc (COND);
1334 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1335 XEXP (condexp, 1) = make_numeric_value (0);
1337 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1339 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1340 XVECEXP (condexp, 0, i + 1)
1341 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1344 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1346 /* If more than one delay type, do the same for computing the delay type. */
1347 if (num_delays > 1)
1349 condexp = rtx_alloc (COND);
1350 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1351 XEXP (condexp, 1) = make_numeric_value (0);
1353 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1355 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1356 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1359 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1362 /* For each delay possibility and delay slot, compute an eligibility
1363 attribute for non-annulled insns and for each type of annulled (annul
1364 if true and annul if false). */
1365 for (delay = delays; delay; delay = delay->next)
1367 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1369 condexp = XVECEXP (delay->def, 1, i);
1370 if (condexp == 0)
1371 condexp = false_rtx;
1372 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1373 make_numeric_value (1), make_numeric_value (0));
1375 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1376 "*delay_%d_%d", delay->num, i / 3);
1377 make_internal_attr (p, newexp, ATTR_SPECIAL);
1379 if (have_annul_true)
1381 condexp = XVECEXP (delay->def, 1, i + 1);
1382 if (condexp == 0) condexp = false_rtx;
1383 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1384 make_numeric_value (1),
1385 make_numeric_value (0));
1386 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1387 "*annul_true_%d_%d", delay->num, i / 3);
1388 make_internal_attr (p, newexp, ATTR_SPECIAL);
1391 if (have_annul_false)
1393 condexp = XVECEXP (delay->def, 1, i + 2);
1394 if (condexp == 0) condexp = false_rtx;
1395 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1396 make_numeric_value (1),
1397 make_numeric_value (0));
1398 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1399 "*annul_false_%d_%d", delay->num, i / 3);
1400 make_internal_attr (p, newexp, ATTR_SPECIAL);
1406 /* Once all attributes and insns have been read and checked, we construct for
1407 each attribute value a list of all the insns that have that value for
1408 the attribute. */
1410 static void
1411 fill_attr (struct attr_desc *attr)
1413 struct attr_value *av;
1414 struct insn_ent *ie;
1415 struct insn_def *id;
1416 int i;
1417 rtx value;
1419 /* Don't fill constant attributes. The value is independent of
1420 any particular insn. */
1421 if (attr->is_const)
1422 return;
1424 for (id = defs; id; id = id->next)
1426 /* If no value is specified for this insn for this attribute, use the
1427 default. */
1428 value = NULL;
1429 if (XVEC (id->def, id->vec_idx))
1430 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1431 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1432 attr->name))
1433 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1435 if (value == NULL)
1436 av = attr->default_val;
1437 else
1438 av = get_attr_value (value, attr, id->insn_code);
1440 ie = oballoc (struct insn_ent);
1441 ie->def = id;
1442 insert_insn_ent (av, ie);
1446 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1447 test that checks relative positions of insns (uses MATCH_DUP or PC).
1448 If so, replace it with what is obtained by passing the expression to
1449 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1450 recursively on each value (including the default value). Otherwise,
1451 return the value returned by NO_ADDRESS_FN applied to EXP. */
1453 static rtx
1454 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1455 rtx (*address_fn) (rtx))
1457 int i;
1458 rtx newexp;
1460 if (GET_CODE (exp) == COND)
1462 /* See if any tests use addresses. */
1463 address_used = 0;
1464 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1465 walk_attr_value (XVECEXP (exp, 0, i));
1467 if (address_used)
1468 return (*address_fn) (exp);
1470 /* Make a new copy of this COND, replacing each element. */
1471 newexp = rtx_alloc (COND);
1472 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1473 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1475 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1476 XVECEXP (newexp, 0, i + 1)
1477 = substitute_address (XVECEXP (exp, 0, i + 1),
1478 no_address_fn, address_fn);
1481 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1482 no_address_fn, address_fn);
1484 return newexp;
1487 else if (GET_CODE (exp) == IF_THEN_ELSE)
1489 address_used = 0;
1490 walk_attr_value (XEXP (exp, 0));
1491 if (address_used)
1492 return (*address_fn) (exp);
1494 return attr_rtx (IF_THEN_ELSE,
1495 substitute_address (XEXP (exp, 0),
1496 no_address_fn, address_fn),
1497 substitute_address (XEXP (exp, 1),
1498 no_address_fn, address_fn),
1499 substitute_address (XEXP (exp, 2),
1500 no_address_fn, address_fn));
1503 return (*no_address_fn) (exp);
1506 /* Make new attributes from the `length' attribute. The following are made,
1507 each corresponding to a function called from `shorten_branches' or
1508 `get_attr_length':
1510 *insn_default_length This is the length of the insn to be returned
1511 by `get_attr_length' before `shorten_branches'
1512 has been called. In each case where the length
1513 depends on relative addresses, the largest
1514 possible is used. This routine is also used
1515 to compute the initial size of the insn.
1517 *insn_variable_length_p This returns 1 if the insn's length depends
1518 on relative addresses, zero otherwise.
1520 *insn_current_length This is only called when it is known that the
1521 insn has a variable length and returns the
1522 current length, based on relative addresses.
1525 static void
1526 make_length_attrs (void)
1528 static const char *new_names[] =
1530 "*insn_default_length",
1531 "*insn_min_length",
1532 "*insn_variable_length_p",
1533 "*insn_current_length"
1535 static rtx (*const no_address_fn[]) (rtx)
1536 = {identity_fn,identity_fn, zero_fn, zero_fn};
1537 static rtx (*const address_fn[]) (rtx)
1538 = {max_fn, min_fn, one_fn, identity_fn};
1539 size_t i;
1540 struct attr_desc *length_attr, *new_attr;
1541 struct attr_value *av, *new_av;
1542 struct insn_ent *ie, *new_ie;
1544 /* See if length attribute is defined. If so, it must be numeric. Make
1545 it special so we don't output anything for it. */
1546 length_attr = find_attr (&length_str, 0);
1547 if (length_attr == 0)
1548 return;
1550 if (! length_attr->is_numeric)
1551 fatal ("length attribute must be numeric");
1553 length_attr->is_const = 0;
1554 length_attr->is_special = 1;
1556 /* Make each new attribute, in turn. */
1557 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1559 make_internal_attr (new_names[i],
1560 substitute_address (length_attr->default_val->value,
1561 no_address_fn[i], address_fn[i]),
1562 ATTR_NONE);
1563 new_attr = find_attr (&new_names[i], 0);
1564 for (av = length_attr->first_value; av; av = av->next)
1565 for (ie = av->first_insn; ie; ie = ie->next)
1567 new_av = get_attr_value (substitute_address (av->value,
1568 no_address_fn[i],
1569 address_fn[i]),
1570 new_attr, ie->def->insn_code);
1571 new_ie = oballoc (struct insn_ent);
1572 new_ie->def = ie->def;
1573 insert_insn_ent (new_av, new_ie);
1578 /* Utility functions called from above routine. */
1580 static rtx
1581 identity_fn (rtx exp)
1583 return exp;
1586 static rtx
1587 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1589 return make_numeric_value (0);
1592 static rtx
1593 one_fn (rtx exp ATTRIBUTE_UNUSED)
1595 return make_numeric_value (1);
1598 static rtx
1599 max_fn (rtx exp)
1601 int unknown;
1602 return make_numeric_value (max_attr_value (exp, &unknown));
1605 static rtx
1606 min_fn (rtx exp)
1608 int unknown;
1609 return make_numeric_value (min_attr_value (exp, &unknown));
1612 static void
1613 write_length_unit_log (void)
1615 struct attr_desc *length_attr = find_attr (&length_str, 0);
1616 struct attr_value *av;
1617 struct insn_ent *ie;
1618 unsigned int length_unit_log, length_or;
1619 int unknown = 0;
1621 if (length_attr == 0)
1622 return;
1623 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1624 for (av = length_attr->first_value; av; av = av->next)
1625 for (ie = av->first_insn; ie; ie = ie->next)
1626 length_or |= or_attr_value (av->value, &unknown);
1628 if (unknown)
1629 length_unit_log = 0;
1630 else
1632 length_or = ~length_or;
1633 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1634 length_unit_log++;
1636 printf ("EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1639 /* Take a COND expression and see if any of the conditions in it can be
1640 simplified. If any are known true or known false for the particular insn
1641 code, the COND can be further simplified.
1643 Also call ourselves on any COND operations that are values of this COND.
1645 We do not modify EXP; rather, we make and return a new rtx. */
1647 static rtx
1648 simplify_cond (rtx exp, int insn_code, int insn_index)
1650 int i, j;
1651 /* We store the desired contents here,
1652 then build a new expression if they don't match EXP. */
1653 rtx defval = XEXP (exp, 1);
1654 rtx new_defval = XEXP (exp, 1);
1655 int len = XVECLEN (exp, 0);
1656 rtx *tests = XNEWVEC (rtx, len);
1657 int allsame = 1;
1658 rtx ret;
1660 /* This lets us free all storage allocated below, if appropriate. */
1661 obstack_finish (rtl_obstack);
1663 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1665 /* See if default value needs simplification. */
1666 if (GET_CODE (defval) == COND)
1667 new_defval = simplify_cond (defval, insn_code, insn_index);
1669 /* Simplify the subexpressions, and see what tests we can get rid of. */
1671 for (i = 0; i < len; i += 2)
1673 rtx newtest, newval;
1675 /* Simplify this test. */
1676 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1677 tests[i] = newtest;
1679 newval = tests[i + 1];
1680 /* See if this value may need simplification. */
1681 if (GET_CODE (newval) == COND)
1682 newval = simplify_cond (newval, insn_code, insn_index);
1684 /* Look for ways to delete or combine this test. */
1685 if (newtest == true_rtx)
1687 /* If test is true, make this value the default
1688 and discard this + any following tests. */
1689 len = i;
1690 defval = tests[i + 1];
1691 new_defval = newval;
1694 else if (newtest == false_rtx)
1696 /* If test is false, discard it and its value. */
1697 for (j = i; j < len - 2; j++)
1698 tests[j] = tests[j + 2];
1699 i -= 2;
1700 len -= 2;
1703 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1705 /* If this value and the value for the prev test are the same,
1706 merge the tests. */
1708 tests[i - 2]
1709 = insert_right_side (IOR, tests[i - 2], newtest,
1710 insn_code, insn_index);
1712 /* Delete this test/value. */
1713 for (j = i; j < len - 2; j++)
1714 tests[j] = tests[j + 2];
1715 len -= 2;
1716 i -= 2;
1719 else
1720 tests[i + 1] = newval;
1723 /* If the last test in a COND has the same value
1724 as the default value, that test isn't needed. */
1726 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1727 len -= 2;
1729 /* See if we changed anything. */
1730 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1731 allsame = 0;
1732 else
1733 for (i = 0; i < len; i++)
1734 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1736 allsame = 0;
1737 break;
1740 if (len == 0)
1742 if (GET_CODE (defval) == COND)
1743 ret = simplify_cond (defval, insn_code, insn_index);
1744 else
1745 ret = defval;
1747 else if (allsame)
1748 ret = exp;
1749 else
1751 rtx newexp = rtx_alloc (COND);
1753 XVEC (newexp, 0) = rtvec_alloc (len);
1754 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1755 XEXP (newexp, 1) = new_defval;
1756 ret = newexp;
1758 free (tests);
1759 return ret;
1762 /* Remove an insn entry from an attribute value. */
1764 static void
1765 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1767 struct insn_ent *previe;
1769 if (av->first_insn == ie)
1770 av->first_insn = ie->next;
1771 else
1773 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1775 previe->next = ie->next;
1778 av->num_insns--;
1779 if (ie->def->insn_code == -1)
1780 av->has_asm_insn = 0;
1782 num_insn_ents--;
1785 /* Insert an insn entry in an attribute value list. */
1787 static void
1788 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1790 ie->next = av->first_insn;
1791 av->first_insn = ie;
1792 av->num_insns++;
1793 if (ie->def->insn_code == -1)
1794 av->has_asm_insn = 1;
1796 num_insn_ents++;
1799 /* This is a utility routine to take an expression that is a tree of either
1800 AND or IOR expressions and insert a new term. The new term will be
1801 inserted at the right side of the first node whose code does not match
1802 the root. A new node will be created with the root's code. Its left
1803 side will be the old right side and its right side will be the new
1804 term.
1806 If the `term' is itself a tree, all its leaves will be inserted. */
1808 static rtx
1809 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1811 rtx newexp;
1813 /* Avoid consing in some special cases. */
1814 if (code == AND && term == true_rtx)
1815 return exp;
1816 if (code == AND && term == false_rtx)
1817 return false_rtx;
1818 if (code == AND && exp == true_rtx)
1819 return term;
1820 if (code == AND && exp == false_rtx)
1821 return false_rtx;
1822 if (code == IOR && term == true_rtx)
1823 return true_rtx;
1824 if (code == IOR && term == false_rtx)
1825 return exp;
1826 if (code == IOR && exp == true_rtx)
1827 return true_rtx;
1828 if (code == IOR && exp == false_rtx)
1829 return term;
1830 if (attr_equal_p (exp, term))
1831 return exp;
1833 if (GET_CODE (term) == code)
1835 exp = insert_right_side (code, exp, XEXP (term, 0),
1836 insn_code, insn_index);
1837 exp = insert_right_side (code, exp, XEXP (term, 1),
1838 insn_code, insn_index);
1840 return exp;
1843 if (GET_CODE (exp) == code)
1845 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1846 term, insn_code, insn_index);
1847 if (new_rtx != XEXP (exp, 1))
1848 /* Make a copy of this expression and call recursively. */
1849 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1850 else
1851 newexp = exp;
1853 else
1855 /* Insert the new term. */
1856 newexp = attr_rtx (code, exp, term);
1859 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1862 /* If we have an expression which AND's a bunch of
1863 (not (eq_attrq "alternative" "n"))
1864 terms, we may have covered all or all but one of the possible alternatives.
1865 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1867 This routine is passed an expression and either AND or IOR. It returns a
1868 bitmask indicating which alternatives are mentioned within EXP. */
1870 static int
1871 compute_alternative_mask (rtx exp, enum rtx_code code)
1873 const char *string;
1874 if (GET_CODE (exp) == code)
1875 return compute_alternative_mask (XEXP (exp, 0), code)
1876 | compute_alternative_mask (XEXP (exp, 1), code);
1878 else if (code == AND && GET_CODE (exp) == NOT
1879 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1880 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1881 string = XSTR (XEXP (exp, 0), 1);
1883 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1884 && XSTR (exp, 0) == alternative_name)
1885 string = XSTR (exp, 1);
1887 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1889 if (code == AND && XINT (exp, 1))
1890 return XINT (exp, 0);
1892 if (code == IOR && !XINT (exp, 1))
1893 return XINT (exp, 0);
1895 return 0;
1897 else
1898 return 0;
1900 if (string[1] == 0)
1901 return 1 << (string[0] - '0');
1902 return 1 << atoi (string);
1905 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1906 attribute with the value represented by that bit. */
1908 static rtx
1909 make_alternative_compare (int mask)
1911 return mk_attr_alt (mask);
1914 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1915 of "attr" for this insn code. From that value, we can compute a test
1916 showing when the EQ_ATTR will be true. This routine performs that
1917 computation. If a test condition involves an address, we leave the EQ_ATTR
1918 intact because addresses are only valid for the `length' attribute.
1920 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1921 it refers. VALUE is the value of that attribute for the insn
1922 corresponding to INSN_CODE and INSN_INDEX. */
1924 static rtx
1925 evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
1926 int insn_code, int insn_index)
1928 rtx orexp, andexp;
1929 rtx right;
1930 rtx newexp;
1931 int i;
1933 while (GET_CODE (value) == ATTR)
1935 struct attr_value *av = NULL;
1937 attr = find_attr (&XSTR (value, 0), 0);
1939 if (insn_code_values)
1941 struct attr_value_list *iv;
1942 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
1943 if (iv->attr == attr)
1945 av = iv->av;
1946 break;
1949 else
1951 struct insn_ent *ie;
1952 for (av = attr->first_value; av; av = av->next)
1953 for (ie = av->first_insn; ie; ie = ie->next)
1954 if (ie->def->insn_code == insn_code)
1955 goto got_av;
1957 if (av)
1959 got_av:
1960 value = av->value;
1964 switch (GET_CODE (value))
1966 case CONST_STRING:
1967 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
1968 newexp = true_rtx;
1969 else
1970 newexp = false_rtx;
1971 break;
1973 case SYMBOL_REF:
1975 const char *prefix;
1976 char *string, *p;
1978 gcc_assert (GET_CODE (exp) == EQ_ATTR);
1979 prefix = attr->enum_name ? attr->enum_name : attr->name;
1980 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
1981 for (p = string; *p; p++)
1982 *p = TOUPPER (*p);
1984 newexp = attr_rtx (EQ, value,
1985 attr_rtx (SYMBOL_REF,
1986 DEF_ATTR_STRING (string)));
1987 break;
1990 case COND:
1991 /* We construct an IOR of all the cases for which the
1992 requested attribute value is present. Since we start with
1993 FALSE, if it is not present, FALSE will be returned.
1995 Each case is the AND of the NOT's of the previous conditions with the
1996 current condition; in the default case the current condition is TRUE.
1998 For each possible COND value, call ourselves recursively.
2000 The extra TRUE and FALSE expressions will be eliminated by another
2001 call to the simplification routine. */
2003 orexp = false_rtx;
2004 andexp = true_rtx;
2006 for (i = 0; i < XVECLEN (value, 0); i += 2)
2008 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2009 insn_code, insn_index);
2011 right = insert_right_side (AND, andexp, this_cond,
2012 insn_code, insn_index);
2013 right = insert_right_side (AND, right,
2014 evaluate_eq_attr (exp, attr,
2015 XVECEXP (value, 0,
2016 i + 1),
2017 insn_code, insn_index),
2018 insn_code, insn_index);
2019 orexp = insert_right_side (IOR, orexp, right,
2020 insn_code, insn_index);
2022 /* Add this condition into the AND expression. */
2023 newexp = attr_rtx (NOT, this_cond);
2024 andexp = insert_right_side (AND, andexp, newexp,
2025 insn_code, insn_index);
2028 /* Handle the default case. */
2029 right = insert_right_side (AND, andexp,
2030 evaluate_eq_attr (exp, attr, XEXP (value, 1),
2031 insn_code, insn_index),
2032 insn_code, insn_index);
2033 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2034 break;
2036 default:
2037 gcc_unreachable ();
2040 /* If uses an address, must return original expression. But set the
2041 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2043 address_used = 0;
2044 walk_attr_value (newexp);
2046 if (address_used)
2048 if (! ATTR_IND_SIMPLIFIED_P (exp))
2049 return copy_rtx_unchanging (exp);
2050 return exp;
2052 else
2053 return newexp;
2056 /* This routine is called when an AND of a term with a tree of AND's is
2057 encountered. If the term or its complement is present in the tree, it
2058 can be replaced with TRUE or FALSE, respectively.
2060 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2061 be true and hence are complementary.
2063 There is one special case: If we see
2064 (and (not (eq_attr "att" "v1"))
2065 (eq_attr "att" "v2"))
2066 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2067 replace the term, not anything in the AND tree. So we pass a pointer to
2068 the term. */
2070 static rtx
2071 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2073 rtx left, right;
2074 rtx newexp;
2075 rtx temp;
2076 int left_eliminates_term, right_eliminates_term;
2078 if (GET_CODE (exp) == AND)
2080 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2081 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2082 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2084 newexp = attr_rtx (AND, left, right);
2086 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2090 else if (GET_CODE (exp) == IOR)
2092 /* For the IOR case, we do the same as above, except that we can
2093 only eliminate `term' if both sides of the IOR would do so. */
2094 temp = *pterm;
2095 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2096 left_eliminates_term = (temp == true_rtx);
2098 temp = *pterm;
2099 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2100 right_eliminates_term = (temp == true_rtx);
2102 if (left_eliminates_term && right_eliminates_term)
2103 *pterm = true_rtx;
2105 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2107 newexp = attr_rtx (IOR, left, right);
2109 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2113 /* Check for simplifications. Do some extra checking here since this
2114 routine is called so many times. */
2116 if (exp == *pterm)
2117 return true_rtx;
2119 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2120 return false_rtx;
2122 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2123 return false_rtx;
2125 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2127 if (attr_alt_subset_p (*pterm, exp))
2128 return true_rtx;
2130 if (attr_alt_subset_of_compl_p (*pterm, exp))
2131 return false_rtx;
2133 if (attr_alt_subset_p (exp, *pterm))
2134 *pterm = true_rtx;
2136 return exp;
2139 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2141 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2142 return exp;
2144 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2145 return true_rtx;
2146 else
2147 return false_rtx;
2150 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2151 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2153 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2154 return exp;
2156 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2157 return false_rtx;
2158 else
2159 return true_rtx;
2162 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2163 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2165 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2166 return exp;
2168 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2169 return false_rtx;
2170 else
2171 *pterm = true_rtx;
2174 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2176 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2177 return true_rtx;
2180 else if (GET_CODE (exp) == NOT)
2182 if (attr_equal_p (XEXP (exp, 0), *pterm))
2183 return false_rtx;
2186 else if (GET_CODE (*pterm) == NOT)
2188 if (attr_equal_p (XEXP (*pterm, 0), exp))
2189 return false_rtx;
2192 else if (attr_equal_p (exp, *pterm))
2193 return true_rtx;
2195 return exp;
2198 /* Similar to `simplify_and_tree', but for IOR trees. */
2200 static rtx
2201 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2203 rtx left, right;
2204 rtx newexp;
2205 rtx temp;
2206 int left_eliminates_term, right_eliminates_term;
2208 if (GET_CODE (exp) == IOR)
2210 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2211 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2212 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2214 newexp = attr_rtx (GET_CODE (exp), left, right);
2216 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2220 else if (GET_CODE (exp) == AND)
2222 /* For the AND case, we do the same as above, except that we can
2223 only eliminate `term' if both sides of the AND would do so. */
2224 temp = *pterm;
2225 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2226 left_eliminates_term = (temp == false_rtx);
2228 temp = *pterm;
2229 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2230 right_eliminates_term = (temp == false_rtx);
2232 if (left_eliminates_term && right_eliminates_term)
2233 *pterm = false_rtx;
2235 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2237 newexp = attr_rtx (GET_CODE (exp), left, right);
2239 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2243 if (attr_equal_p (exp, *pterm))
2244 return false_rtx;
2246 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2247 return true_rtx;
2249 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2250 return true_rtx;
2252 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2253 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2254 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2255 *pterm = false_rtx;
2257 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2258 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2259 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2260 return false_rtx;
2262 return exp;
2265 /* Compute approximate cost of the expression. Used to decide whether
2266 expression is cheap enough for inline. */
2267 static int
2268 attr_rtx_cost (rtx x)
2270 int cost = 0;
2271 enum rtx_code code;
2272 if (!x)
2273 return 0;
2274 code = GET_CODE (x);
2275 switch (code)
2277 case MATCH_OPERAND:
2278 if (XSTR (x, 1)[0])
2279 return 10;
2280 else
2281 return 0;
2283 case EQ_ATTR_ALT:
2284 return 0;
2286 case EQ_ATTR:
2287 /* Alternatives don't result into function call. */
2288 if (!strcmp_check (XSTR (x, 0), alternative_name))
2289 return 0;
2290 else
2291 return 5;
2292 default:
2294 int i, j;
2295 const char *fmt = GET_RTX_FORMAT (code);
2296 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2298 switch (fmt[i])
2300 case 'V':
2301 case 'E':
2302 for (j = 0; j < XVECLEN (x, i); j++)
2303 cost += attr_rtx_cost (XVECEXP (x, i, j));
2304 break;
2305 case 'e':
2306 cost += attr_rtx_cost (XEXP (x, i));
2307 break;
2311 break;
2313 return cost;
2316 /* Simplify test expression and use temporary obstack in order to avoid
2317 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2318 and avoid unnecessary copying if possible. */
2320 static rtx
2321 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2323 rtx x;
2324 struct obstack *old;
2325 if (ATTR_IND_SIMPLIFIED_P (exp))
2326 return exp;
2327 old = rtl_obstack;
2328 rtl_obstack = temp_obstack;
2329 x = simplify_test_exp (exp, insn_code, insn_index);
2330 rtl_obstack = old;
2331 if (x == exp || rtl_obstack == temp_obstack)
2332 return x;
2333 return attr_copy_rtx (x);
2336 /* Returns true if S1 is a subset of S2. */
2338 static bool
2339 attr_alt_subset_p (rtx s1, rtx s2)
2341 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2343 case (0 << 1) | 0:
2344 return !(XINT (s1, 0) &~ XINT (s2, 0));
2346 case (0 << 1) | 1:
2347 return !(XINT (s1, 0) & XINT (s2, 0));
2349 case (1 << 1) | 0:
2350 return false;
2352 case (1 << 1) | 1:
2353 return !(XINT (s2, 0) &~ XINT (s1, 0));
2355 default:
2356 gcc_unreachable ();
2360 /* Returns true if S1 is a subset of complement of S2. */
2362 static bool
2363 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2365 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2367 case (0 << 1) | 0:
2368 return !(XINT (s1, 0) & XINT (s2, 0));
2370 case (0 << 1) | 1:
2371 return !(XINT (s1, 0) & ~XINT (s2, 0));
2373 case (1 << 1) | 0:
2374 return !(XINT (s2, 0) &~ XINT (s1, 0));
2376 case (1 << 1) | 1:
2377 return false;
2379 default:
2380 gcc_unreachable ();
2384 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2386 static rtx
2387 attr_alt_intersection (rtx s1, rtx s2)
2389 rtx result = rtx_alloc (EQ_ATTR_ALT);
2391 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2393 case (0 << 1) | 0:
2394 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2395 break;
2396 case (0 << 1) | 1:
2397 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2398 break;
2399 case (1 << 1) | 0:
2400 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2401 break;
2402 case (1 << 1) | 1:
2403 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2404 break;
2405 default:
2406 gcc_unreachable ();
2408 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2410 return result;
2413 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2415 static rtx
2416 attr_alt_union (rtx s1, rtx s2)
2418 rtx result = rtx_alloc (EQ_ATTR_ALT);
2420 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2422 case (0 << 1) | 0:
2423 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2424 break;
2425 case (0 << 1) | 1:
2426 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2427 break;
2428 case (1 << 1) | 0:
2429 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2430 break;
2431 case (1 << 1) | 1:
2432 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2433 break;
2434 default:
2435 gcc_unreachable ();
2438 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2439 return result;
2442 /* Return EQ_ATTR_ALT expression representing complement of S. */
2444 static rtx
2445 attr_alt_complement (rtx s)
2447 rtx result = rtx_alloc (EQ_ATTR_ALT);
2449 XINT (result, 0) = XINT (s, 0);
2450 XINT (result, 1) = 1 - XINT (s, 1);
2452 return result;
2455 /* Return EQ_ATTR_ALT expression representing set containing elements set
2456 in E. */
2458 static rtx
2459 mk_attr_alt (int e)
2461 rtx result = rtx_alloc (EQ_ATTR_ALT);
2463 XINT (result, 0) = e;
2464 XINT (result, 1) = 0;
2466 return result;
2469 /* Given an expression, see if it can be simplified for a particular insn
2470 code based on the values of other attributes being tested. This can
2471 eliminate nested get_attr_... calls.
2473 Note that if an endless recursion is specified in the patterns, the
2474 optimization will loop. However, it will do so in precisely the cases where
2475 an infinite recursion loop could occur during compilation. It's better that
2476 it occurs here! */
2478 static rtx
2479 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2481 rtx left, right;
2482 struct attr_desc *attr;
2483 struct attr_value *av;
2484 struct insn_ent *ie;
2485 struct attr_value_list *iv;
2486 int i;
2487 rtx newexp = exp;
2488 bool left_alt, right_alt;
2490 /* Don't re-simplify something we already simplified. */
2491 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2492 return exp;
2494 switch (GET_CODE (exp))
2496 case AND:
2497 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2498 if (left == false_rtx)
2499 return false_rtx;
2500 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2501 if (right == false_rtx)
2502 return false_rtx;
2504 if (GET_CODE (left) == EQ_ATTR_ALT
2505 && GET_CODE (right) == EQ_ATTR_ALT)
2507 exp = attr_alt_intersection (left, right);
2508 return simplify_test_exp (exp, insn_code, insn_index);
2511 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2512 present on both sides, apply the distributive law since this will
2513 yield simplifications. */
2514 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2515 && compute_alternative_mask (left, IOR)
2516 && compute_alternative_mask (right, IOR))
2518 if (GET_CODE (left) == IOR)
2520 rtx tem = left;
2521 left = right;
2522 right = tem;
2525 newexp = attr_rtx (IOR,
2526 attr_rtx (AND, left, XEXP (right, 0)),
2527 attr_rtx (AND, left, XEXP (right, 1)));
2529 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2532 /* Try with the term on both sides. */
2533 right = simplify_and_tree (right, &left, insn_code, insn_index);
2534 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2535 left = simplify_and_tree (left, &right, insn_code, insn_index);
2537 if (left == false_rtx || right == false_rtx)
2538 return false_rtx;
2539 else if (left == true_rtx)
2541 return right;
2543 else if (right == true_rtx)
2545 return left;
2547 /* See if all or all but one of the insn's alternatives are specified
2548 in this tree. Optimize if so. */
2550 if (GET_CODE (left) == NOT)
2551 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2552 && XSTR (XEXP (left, 0), 0) == alternative_name);
2553 else
2554 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2555 && XINT (left, 1));
2557 if (GET_CODE (right) == NOT)
2558 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2559 && XSTR (XEXP (right, 0), 0) == alternative_name);
2560 else
2561 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2562 && XINT (right, 1));
2564 if (insn_code >= 0
2565 && (GET_CODE (left) == AND
2566 || left_alt
2567 || GET_CODE (right) == AND
2568 || right_alt))
2570 i = compute_alternative_mask (exp, AND);
2571 if (i & ~insn_alternatives[insn_code])
2572 fatal ("invalid alternative specified for pattern number %d",
2573 insn_index);
2575 /* If all alternatives are excluded, this is false. */
2576 i ^= insn_alternatives[insn_code];
2577 if (i == 0)
2578 return false_rtx;
2579 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2581 /* If just one excluded, AND a comparison with that one to the
2582 front of the tree. The others will be eliminated by
2583 optimization. We do not want to do this if the insn has one
2584 alternative and we have tested none of them! */
2585 left = make_alternative_compare (i);
2586 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2587 newexp = attr_rtx (AND, left, right);
2589 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2593 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2595 newexp = attr_rtx (AND, left, right);
2596 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2598 break;
2600 case IOR:
2601 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2602 if (left == true_rtx)
2603 return true_rtx;
2604 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2605 if (right == true_rtx)
2606 return true_rtx;
2608 if (GET_CODE (left) == EQ_ATTR_ALT
2609 && GET_CODE (right) == EQ_ATTR_ALT)
2611 exp = attr_alt_union (left, right);
2612 return simplify_test_exp (exp, insn_code, insn_index);
2615 right = simplify_or_tree (right, &left, insn_code, insn_index);
2616 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2617 left = simplify_or_tree (left, &right, insn_code, insn_index);
2619 if (right == true_rtx || left == true_rtx)
2620 return true_rtx;
2621 else if (left == false_rtx)
2623 return right;
2625 else if (right == false_rtx)
2627 return left;
2630 /* Test for simple cases where the distributive law is useful. I.e.,
2631 convert (ior (and (x) (y))
2632 (and (x) (z)))
2633 to (and (x)
2634 (ior (y) (z)))
2637 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2638 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2640 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2642 left = XEXP (left, 0);
2643 right = newexp;
2644 newexp = attr_rtx (AND, left, right);
2645 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2648 /* See if all or all but one of the insn's alternatives are specified
2649 in this tree. Optimize if so. */
2651 else if (insn_code >= 0
2652 && (GET_CODE (left) == IOR
2653 || (GET_CODE (left) == EQ_ATTR_ALT
2654 && !XINT (left, 1))
2655 || (GET_CODE (left) == EQ_ATTR
2656 && XSTR (left, 0) == alternative_name)
2657 || GET_CODE (right) == IOR
2658 || (GET_CODE (right) == EQ_ATTR_ALT
2659 && !XINT (right, 1))
2660 || (GET_CODE (right) == EQ_ATTR
2661 && XSTR (right, 0) == alternative_name)))
2663 i = compute_alternative_mask (exp, IOR);
2664 if (i & ~insn_alternatives[insn_code])
2665 fatal ("invalid alternative specified for pattern number %d",
2666 insn_index);
2668 /* If all alternatives are included, this is true. */
2669 i ^= insn_alternatives[insn_code];
2670 if (i == 0)
2671 return true_rtx;
2672 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2674 /* If just one excluded, IOR a comparison with that one to the
2675 front of the tree. The others will be eliminated by
2676 optimization. We do not want to do this if the insn has one
2677 alternative and we have tested none of them! */
2678 left = make_alternative_compare (i);
2679 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2680 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2682 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2686 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2688 newexp = attr_rtx (IOR, left, right);
2689 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2691 break;
2693 case NOT:
2694 if (GET_CODE (XEXP (exp, 0)) == NOT)
2696 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2697 insn_code, insn_index);
2698 return left;
2701 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2702 if (GET_CODE (left) == NOT)
2703 return XEXP (left, 0);
2705 if (left == false_rtx)
2706 return true_rtx;
2707 if (left == true_rtx)
2708 return false_rtx;
2710 if (GET_CODE (left) == EQ_ATTR_ALT)
2712 exp = attr_alt_complement (left);
2713 return simplify_test_exp (exp, insn_code, insn_index);
2716 /* Try to apply De`Morgan's laws. */
2717 if (GET_CODE (left) == IOR)
2719 newexp = attr_rtx (AND,
2720 attr_rtx (NOT, XEXP (left, 0)),
2721 attr_rtx (NOT, XEXP (left, 1)));
2723 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2725 else if (GET_CODE (left) == AND)
2727 newexp = attr_rtx (IOR,
2728 attr_rtx (NOT, XEXP (left, 0)),
2729 attr_rtx (NOT, XEXP (left, 1)));
2731 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2733 else if (left != XEXP (exp, 0))
2735 newexp = attr_rtx (NOT, left);
2737 break;
2739 case EQ_ATTR_ALT:
2740 if (!XINT (exp, 0))
2741 return XINT (exp, 1) ? true_rtx : false_rtx;
2742 break;
2744 case EQ_ATTR:
2745 if (XSTR (exp, 0) == alternative_name)
2747 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2748 break;
2751 /* Look at the value for this insn code in the specified attribute.
2752 We normally can replace this comparison with the condition that
2753 would give this insn the values being tested for. */
2754 if (insn_code >= 0
2755 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2757 rtx x;
2759 av = NULL;
2760 if (insn_code_values)
2762 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2763 if (iv->attr == attr)
2765 av = iv->av;
2766 break;
2769 else
2771 for (av = attr->first_value; av; av = av->next)
2772 for (ie = av->first_insn; ie; ie = ie->next)
2773 if (ie->def->insn_code == insn_code)
2774 goto got_av;
2777 if (av)
2779 got_av:
2780 x = evaluate_eq_attr (exp, attr, av->value,
2781 insn_code, insn_index);
2782 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2783 if (attr_rtx_cost(x) < 20)
2784 return x;
2787 break;
2789 default:
2790 break;
2793 /* We have already simplified this expression. Simplifying it again
2794 won't buy anything unless we weren't given a valid insn code
2795 to process (i.e., we are canonicalizing something.). */
2796 if (insn_code != -2
2797 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2798 return copy_rtx_unchanging (newexp);
2800 return newexp;
2803 /* Optimize the attribute lists by seeing if we can determine conditional
2804 values from the known values of other attributes. This will save subroutine
2805 calls during the compilation. */
2807 static void
2808 optimize_attrs (void)
2810 struct attr_desc *attr;
2811 struct attr_value *av;
2812 struct insn_ent *ie;
2813 rtx newexp;
2814 int i;
2815 struct attr_value_list *ivbuf;
2816 struct attr_value_list *iv;
2818 /* For each insn code, make a list of all the insn_ent's for it,
2819 for all values for all attributes. */
2821 if (num_insn_ents == 0)
2822 return;
2824 /* Make 2 extra elements, for "code" values -2 and -1. */
2825 insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
2827 /* Offset the table address so we can index by -2 or -1. */
2828 insn_code_values += 2;
2830 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2832 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2833 for (attr = attrs[i]; attr; attr = attr->next)
2834 for (av = attr->first_value; av; av = av->next)
2835 for (ie = av->first_insn; ie; ie = ie->next)
2837 iv->attr = attr;
2838 iv->av = av;
2839 iv->ie = ie;
2840 iv->next = insn_code_values[ie->def->insn_code];
2841 insn_code_values[ie->def->insn_code] = iv;
2842 iv++;
2845 /* Sanity check on num_insn_ents. */
2846 gcc_assert (iv == ivbuf + num_insn_ents);
2848 /* Process one insn code at a time. */
2849 for (i = -2; i < insn_code_number; i++)
2851 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2852 We use it to mean "already simplified for this insn". */
2853 for (iv = insn_code_values[i]; iv; iv = iv->next)
2854 clear_struct_flag (iv->av->value);
2856 for (iv = insn_code_values[i]; iv; iv = iv->next)
2858 struct obstack *old = rtl_obstack;
2860 attr = iv->attr;
2861 av = iv->av;
2862 ie = iv->ie;
2863 if (GET_CODE (av->value) != COND)
2864 continue;
2866 rtl_obstack = temp_obstack;
2867 newexp = av->value;
2868 while (GET_CODE (newexp) == COND)
2870 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2871 ie->def->insn_index);
2872 if (newexp2 == newexp)
2873 break;
2874 newexp = newexp2;
2877 rtl_obstack = old;
2878 if (newexp != av->value)
2880 newexp = attr_copy_rtx (newexp);
2881 remove_insn_ent (av, ie);
2882 av = get_attr_value (newexp, attr, ie->def->insn_code);
2883 iv->av = av;
2884 insert_insn_ent (av, ie);
2889 free (ivbuf);
2890 free (insn_code_values - 2);
2891 insn_code_values = NULL;
2894 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2896 static void
2897 clear_struct_flag (rtx x)
2899 int i;
2900 int j;
2901 enum rtx_code code;
2902 const char *fmt;
2904 ATTR_CURR_SIMPLIFIED_P (x) = 0;
2905 if (ATTR_IND_SIMPLIFIED_P (x))
2906 return;
2908 code = GET_CODE (x);
2910 switch (code)
2912 case REG:
2913 case CONST_INT:
2914 case CONST_DOUBLE:
2915 case CONST_VECTOR:
2916 case MATCH_TEST:
2917 case SYMBOL_REF:
2918 case CODE_LABEL:
2919 case PC:
2920 case CC0:
2921 case EQ_ATTR:
2922 case ATTR_FLAG:
2923 return;
2925 default:
2926 break;
2929 /* Compare the elements. If any pair of corresponding elements
2930 fail to match, return 0 for the whole things. */
2932 fmt = GET_RTX_FORMAT (code);
2933 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2935 switch (fmt[i])
2937 case 'V':
2938 case 'E':
2939 for (j = 0; j < XVECLEN (x, i); j++)
2940 clear_struct_flag (XVECEXP (x, i, j));
2941 break;
2943 case 'e':
2944 clear_struct_flag (XEXP (x, i));
2945 break;
2950 /* Add attribute value NAME to the beginning of ATTR's list. */
2952 static void
2953 add_attr_value (struct attr_desc *attr, const char *name)
2955 struct attr_value *av;
2957 av = oballoc (struct attr_value);
2958 av->value = attr_rtx (CONST_STRING, name);
2959 av->next = attr->first_value;
2960 attr->first_value = av;
2961 av->first_insn = NULL;
2962 av->num_insns = 0;
2963 av->has_asm_insn = 0;
2966 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
2968 static void
2969 gen_attr (rtx exp, int lineno)
2971 struct enum_type *et;
2972 struct enum_value *ev;
2973 struct attr_desc *attr;
2974 const char *name_ptr;
2975 char *p;
2977 /* Make a new attribute structure. Check for duplicate by looking at
2978 attr->default_val, since it is initialized by this routine. */
2979 attr = find_attr (&XSTR (exp, 0), 1);
2980 if (attr->default_val)
2982 error_with_line (lineno, "duplicate definition for attribute %s",
2983 attr->name);
2984 message_with_line (attr->lineno, "previous definition");
2985 return;
2987 attr->lineno = lineno;
2989 if (GET_CODE (exp) == DEFINE_ENUM_ATTR)
2991 attr->enum_name = XSTR (exp, 1);
2992 et = lookup_enum_type (XSTR (exp, 1));
2993 if (!et || !et->md_p)
2994 error_with_line (lineno, "No define_enum called `%s' defined",
2995 attr->name);
2996 for (ev = et->values; ev; ev = ev->next)
2997 add_attr_value (attr, ev->name);
2999 else if (*XSTR (exp, 1) == '\0')
3000 attr->is_numeric = 1;
3001 else
3003 name_ptr = XSTR (exp, 1);
3004 while ((p = next_comma_elt (&name_ptr)) != NULL)
3005 add_attr_value (attr, p);
3008 if (GET_CODE (XEXP (exp, 2)) == CONST)
3010 attr->is_const = 1;
3011 if (attr->is_numeric)
3012 error_with_line (lineno,
3013 "constant attributes may not take numeric values");
3015 /* Get rid of the CONST node. It is allowed only at top-level. */
3016 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3019 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3020 error_with_line (lineno, "`length' attribute must take numeric values");
3022 /* Set up the default value. */
3023 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3024 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3027 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3028 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3029 number of alternatives as this should be checked elsewhere. */
3031 static int
3032 count_alternatives (rtx exp)
3034 int i, j, n;
3035 const char *fmt;
3037 if (GET_CODE (exp) == MATCH_OPERAND)
3038 return n_comma_elts (XSTR (exp, 2));
3040 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3041 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3042 switch (*fmt++)
3044 case 'e':
3045 case 'u':
3046 n = count_alternatives (XEXP (exp, i));
3047 if (n)
3048 return n;
3049 break;
3051 case 'E':
3052 case 'V':
3053 if (XVEC (exp, i) != NULL)
3054 for (j = 0; j < XVECLEN (exp, i); j++)
3056 n = count_alternatives (XVECEXP (exp, i, j));
3057 if (n)
3058 return n;
3062 return 0;
3065 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3066 `alternative' attribute. */
3068 static int
3069 compares_alternatives_p (rtx exp)
3071 int i, j;
3072 const char *fmt;
3074 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3075 return 1;
3077 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3078 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3079 switch (*fmt++)
3081 case 'e':
3082 case 'u':
3083 if (compares_alternatives_p (XEXP (exp, i)))
3084 return 1;
3085 break;
3087 case 'E':
3088 for (j = 0; j < XVECLEN (exp, i); j++)
3089 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3090 return 1;
3091 break;
3094 return 0;
3097 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3099 static void
3100 gen_insn (rtx exp, int lineno)
3102 struct insn_def *id;
3104 id = oballoc (struct insn_def);
3105 id->next = defs;
3106 defs = id;
3107 id->def = exp;
3108 id->lineno = lineno;
3110 switch (GET_CODE (exp))
3112 case DEFINE_INSN:
3113 id->insn_code = insn_code_number;
3114 id->insn_index = insn_index_number;
3115 id->num_alternatives = count_alternatives (exp);
3116 if (id->num_alternatives == 0)
3117 id->num_alternatives = 1;
3118 id->vec_idx = 4;
3119 break;
3121 case DEFINE_PEEPHOLE:
3122 id->insn_code = insn_code_number;
3123 id->insn_index = insn_index_number;
3124 id->num_alternatives = count_alternatives (exp);
3125 if (id->num_alternatives == 0)
3126 id->num_alternatives = 1;
3127 id->vec_idx = 3;
3128 break;
3130 case DEFINE_ASM_ATTRIBUTES:
3131 id->insn_code = -1;
3132 id->insn_index = -1;
3133 id->num_alternatives = 1;
3134 id->vec_idx = 0;
3135 got_define_asm_attributes = 1;
3136 break;
3138 default:
3139 gcc_unreachable ();
3143 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3144 true or annul false is specified, and make a `struct delay_desc'. */
3146 static void
3147 gen_delay (rtx def, int lineno)
3149 struct delay_desc *delay;
3150 int i;
3152 if (XVECLEN (def, 1) % 3 != 0)
3154 error_with_line (lineno,
3155 "number of elements in DEFINE_DELAY must"
3156 " be multiple of three");
3157 return;
3160 for (i = 0; i < XVECLEN (def, 1); i += 3)
3162 if (XVECEXP (def, 1, i + 1))
3163 have_annul_true = 1;
3164 if (XVECEXP (def, 1, i + 2))
3165 have_annul_false = 1;
3168 delay = oballoc (struct delay_desc);
3169 delay->def = def;
3170 delay->num = ++num_delays;
3171 delay->next = delays;
3172 delay->lineno = lineno;
3173 delays = delay;
3176 /* Names of attributes that could be possibly cached. */
3177 static const char *cached_attrs[32];
3178 /* Number of such attributes. */
3179 static int cached_attr_count;
3180 /* Bitmasks of possibly cached attributes. */
3181 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3182 static unsigned int attrs_to_cache;
3183 static unsigned int attrs_cached_inside, attrs_cached_after;
3185 /* Finds non-const attributes that could be possibly cached.
3186 When create is TRUE, fills in cached_attrs array.
3187 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3188 bitmasks. */
3190 static void
3191 find_attrs_to_cache (rtx exp, bool create)
3193 int i;
3194 const char *name;
3195 struct attr_desc *attr;
3197 if (exp == NULL)
3198 return;
3200 switch (GET_CODE (exp))
3202 case NOT:
3203 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3204 find_attrs_to_cache (XEXP (exp, 0), create);
3205 return;
3207 case EQ_ATTR:
3208 name = XSTR (exp, 0);
3209 if (name == alternative_name)
3210 return;
3211 for (i = 0; i < cached_attr_count; i++)
3212 if (name == cached_attrs[i])
3214 if ((attrs_seen_once & (1U << i)) != 0)
3215 attrs_seen_more_than_once |= (1U << i);
3216 else
3217 attrs_seen_once |= (1U << i);
3218 return;
3220 if (!create)
3221 return;
3222 attr = find_attr (&name, 0);
3223 gcc_assert (attr);
3224 if (attr->is_const)
3225 return;
3226 if (cached_attr_count == 32)
3227 return;
3228 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3229 attrs_seen_once |= (1U << cached_attr_count);
3230 cached_attr_count++;
3231 return;
3233 case AND:
3234 case IOR:
3235 find_attrs_to_cache (XEXP (exp, 0), create);
3236 find_attrs_to_cache (XEXP (exp, 1), create);
3237 return;
3239 case COND:
3240 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3241 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3242 return;
3244 default:
3245 return;
3249 /* Given a piece of RTX, print a C expression to test its truth value.
3250 We use AND and IOR both for logical and bit-wise operations, so
3251 interpret them as logical unless they are inside a comparison expression. */
3253 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3254 #define FLG_BITWISE 1
3255 /* Set if cached attribute will be known initialized in else block after
3256 this condition. This is true for LHS of toplevel && and || and
3257 even for RHS of ||, but not for RHS of &&. */
3258 #define FLG_AFTER 2
3259 /* Set if cached attribute will be known initialized in then block after
3260 this condition. This is true for LHS of toplevel && and || and
3261 even for RHS of &&, but not for RHS of ||. */
3262 #define FLG_INSIDE 4
3263 /* Cleared when an operand of &&. */
3264 #define FLG_OUTSIDE_AND 8
3266 static unsigned int
3267 write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
3269 int comparison_operator = 0;
3270 RTX_CODE code;
3271 struct attr_desc *attr;
3273 /* In order not to worry about operator precedence, surround our part of
3274 the expression with parentheses. */
3276 printf ("(");
3277 code = GET_CODE (exp);
3278 switch (code)
3280 /* Binary operators. */
3281 case GEU: case GTU:
3282 case LEU: case LTU:
3283 printf ("(unsigned) ");
3284 /* Fall through. */
3286 case EQ: case NE:
3287 case GE: case GT:
3288 case LE: case LT:
3289 comparison_operator = FLG_BITWISE;
3291 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3292 case AND: case IOR: case XOR:
3293 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3294 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3296 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3297 write_test_expr (XEXP (exp, 0), attrs_cached,
3298 flags | comparison_operator);
3300 else
3302 if (code == AND)
3303 flags &= ~FLG_OUTSIDE_AND;
3304 if (GET_CODE (XEXP (exp, 0)) == code
3305 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3306 || (GET_CODE (XEXP (exp, 0)) == NOT
3307 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3308 attrs_cached
3309 = write_test_expr (XEXP (exp, 0), attrs_cached, flags);
3310 else
3311 write_test_expr (XEXP (exp, 0), attrs_cached, flags);
3313 switch (code)
3315 case EQ:
3316 printf (" == ");
3317 break;
3318 case NE:
3319 printf (" != ");
3320 break;
3321 case GE:
3322 printf (" >= ");
3323 break;
3324 case GT:
3325 printf (" > ");
3326 break;
3327 case GEU:
3328 printf (" >= (unsigned) ");
3329 break;
3330 case GTU:
3331 printf (" > (unsigned) ");
3332 break;
3333 case LE:
3334 printf (" <= ");
3335 break;
3336 case LT:
3337 printf (" < ");
3338 break;
3339 case LEU:
3340 printf (" <= (unsigned) ");
3341 break;
3342 case LTU:
3343 printf (" < (unsigned) ");
3344 break;
3345 case PLUS:
3346 printf (" + ");
3347 break;
3348 case MINUS:
3349 printf (" - ");
3350 break;
3351 case MULT:
3352 printf (" * ");
3353 break;
3354 case DIV:
3355 printf (" / ");
3356 break;
3357 case MOD:
3358 printf (" %% ");
3359 break;
3360 case AND:
3361 if (flags & FLG_BITWISE)
3362 printf (" & ");
3363 else
3364 printf (" && ");
3365 break;
3366 case IOR:
3367 if (flags & FLG_BITWISE)
3368 printf (" | ");
3369 else
3370 printf (" || ");
3371 break;
3372 case XOR:
3373 printf (" ^ ");
3374 break;
3375 case ASHIFT:
3376 printf (" << ");
3377 break;
3378 case LSHIFTRT:
3379 case ASHIFTRT:
3380 printf (" >> ");
3381 break;
3382 default:
3383 gcc_unreachable ();
3386 if (code == AND)
3388 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3389 cached_x is only known to be initialized in then block. */
3390 flags &= ~FLG_AFTER;
3392 else if (code == IOR)
3394 if (flags & FLG_OUTSIDE_AND)
3395 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3396 cached_x is only known to be initialized in else block
3397 and else if conditions. */
3398 flags &= ~FLG_INSIDE;
3399 else
3400 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3401 && something_else)
3402 cached_x is not know to be initialized anywhere. */
3403 flags &= ~(FLG_AFTER | FLG_INSIDE);
3405 if ((code == AND || code == IOR)
3406 && (GET_CODE (XEXP (exp, 1)) == code
3407 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3408 || (GET_CODE (XEXP (exp, 1)) == NOT
3409 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3410 attrs_cached
3411 = write_test_expr (XEXP (exp, 1), attrs_cached, flags);
3412 else
3413 write_test_expr (XEXP (exp, 1), attrs_cached,
3414 flags | comparison_operator);
3415 break;
3417 case NOT:
3418 /* Special-case (not (eq_attrq "alternative" "x")) */
3419 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3421 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3423 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3424 break;
3427 printf ("! ");
3428 attrs_cached = write_test_expr (XEXP (exp, 0), attrs_cached, flags);
3429 break;
3432 /* Otherwise, fall through to normal unary operator. */
3434 /* Unary operators. */
3435 case ABS: case NEG:
3436 switch (code)
3438 case NOT:
3439 if (flags & FLG_BITWISE)
3440 printf ("~ ");
3441 else
3442 printf ("! ");
3443 break;
3444 case ABS:
3445 printf ("abs ");
3446 break;
3447 case NEG:
3448 printf ("-");
3449 break;
3450 default:
3451 gcc_unreachable ();
3454 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3455 write_test_expr (XEXP (exp, 0), attrs_cached, flags);
3456 break;
3458 case EQ_ATTR_ALT:
3460 int set = XINT (exp, 0), bit = 0;
3462 if (flags & FLG_BITWISE)
3463 fatal ("EQ_ATTR_ALT not valid inside comparison");
3465 if (!set)
3466 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3468 if (!(set & (set - 1)))
3470 if (!(set & 0xffff))
3472 bit += 16;
3473 set >>= 16;
3475 if (!(set & 0xff))
3477 bit += 8;
3478 set >>= 8;
3480 if (!(set & 0xf))
3482 bit += 4;
3483 set >>= 4;
3485 if (!(set & 0x3))
3487 bit += 2;
3488 set >>= 2;
3490 if (!(set & 1))
3491 bit++;
3493 printf ("which_alternative %s= %d",
3494 XINT (exp, 1) ? "!" : "=", bit);
3496 else
3498 printf ("%s((1 << which_alternative) & %#x)",
3499 XINT (exp, 1) ? "!" : "", set);
3502 break;
3504 /* Comparison test of an attribute with a value. Most of these will
3505 have been removed by optimization. Handle "alternative"
3506 specially and give error if EQ_ATTR present inside a comparison. */
3507 case EQ_ATTR:
3508 if (flags & FLG_BITWISE)
3509 fatal ("EQ_ATTR not valid inside comparison");
3511 if (XSTR (exp, 0) == alternative_name)
3513 printf ("which_alternative == %s", XSTR (exp, 1));
3514 break;
3517 attr = find_attr (&XSTR (exp, 0), 0);
3518 gcc_assert (attr);
3520 /* Now is the time to expand the value of a constant attribute. */
3521 if (attr->is_const)
3523 write_test_expr (evaluate_eq_attr (exp, attr,
3524 attr->default_val->value, -2, -2),
3525 attrs_cached, 0);
3527 else
3529 int i;
3530 for (i = 0; i < cached_attr_count; i++)
3531 if (attr->name == cached_attrs[i])
3532 break;
3533 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3534 printf ("cached_%s", attr->name);
3535 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3537 printf ("(cached_%s = get_attr_%s (insn))",
3538 attr->name, attr->name);
3539 if (flags & FLG_AFTER)
3540 attrs_cached_after |= (1U << i);
3541 if (flags & FLG_INSIDE)
3542 attrs_cached_inside |= (1U << i);
3543 attrs_cached |= (1U << i);
3545 else
3546 printf ("get_attr_%s (insn)", attr->name);
3547 printf (" == ");
3548 write_attr_valueq (attr, XSTR (exp, 1));
3550 break;
3552 /* Comparison test of flags for define_delays. */
3553 case ATTR_FLAG:
3554 if (flags & FLG_BITWISE)
3555 fatal ("ATTR_FLAG not valid inside comparison");
3556 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3557 break;
3559 /* See if an operand matches a predicate. */
3560 case MATCH_OPERAND:
3561 /* If only a mode is given, just ensure the mode matches the operand.
3562 If neither a mode nor predicate is given, error. */
3563 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3565 if (GET_MODE (exp) == VOIDmode)
3566 fatal ("null MATCH_OPERAND specified as test");
3567 else
3568 printf ("GET_MODE (operands[%d]) == %smode",
3569 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3571 else
3572 printf ("%s (operands[%d], %smode)",
3573 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3574 break;
3576 /* Constant integer. */
3577 case CONST_INT:
3578 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3579 break;
3581 case MATCH_TEST:
3582 print_c_condition (XSTR (exp, 0));
3583 if (flags & FLG_BITWISE)
3584 printf (" != 0");
3585 break;
3587 /* A random C expression. */
3588 case SYMBOL_REF:
3589 print_c_condition (XSTR (exp, 0));
3590 break;
3592 /* The address of the branch target. */
3593 case MATCH_DUP:
3594 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3595 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3596 break;
3598 case PC:
3599 /* The address of the current insn. We implement this actually as the
3600 address of the current insn for backward branches, but the last
3601 address of the next insn for forward branches, and both with
3602 adjustments that account for the worst-case possible stretching of
3603 intervening alignments between this insn and its destination. */
3604 printf ("insn_current_reference_address (insn)");
3605 break;
3607 case CONST_STRING:
3608 printf ("%s", XSTR (exp, 0));
3609 break;
3611 case IF_THEN_ELSE:
3612 write_test_expr (XEXP (exp, 0), attrs_cached, 0);
3613 printf (" ? ");
3614 write_test_expr (XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3615 printf (" : ");
3616 write_test_expr (XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3617 break;
3619 default:
3620 fatal ("bad RTX code `%s' in attribute calculation\n",
3621 GET_RTX_NAME (code));
3624 printf (")");
3625 return attrs_cached;
3628 /* Given an attribute value, return the maximum CONST_STRING argument
3629 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3631 static int
3632 max_attr_value (rtx exp, int *unknownp)
3634 int current_max;
3635 int i, n;
3637 switch (GET_CODE (exp))
3639 case CONST_STRING:
3640 current_max = atoi (XSTR (exp, 0));
3641 break;
3643 case COND:
3644 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3645 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3647 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3648 if (n > current_max)
3649 current_max = n;
3651 break;
3653 case IF_THEN_ELSE:
3654 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3655 n = max_attr_value (XEXP (exp, 2), unknownp);
3656 if (n > current_max)
3657 current_max = n;
3658 break;
3660 default:
3661 *unknownp = 1;
3662 current_max = INT_MAX;
3663 break;
3666 return current_max;
3669 /* Given an attribute value, return the minimum CONST_STRING argument
3670 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3672 static int
3673 min_attr_value (rtx exp, int *unknownp)
3675 int current_min;
3676 int i, n;
3678 switch (GET_CODE (exp))
3680 case CONST_STRING:
3681 current_min = atoi (XSTR (exp, 0));
3682 break;
3684 case COND:
3685 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3686 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3688 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3689 if (n < current_min)
3690 current_min = n;
3692 break;
3694 case IF_THEN_ELSE:
3695 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3696 n = min_attr_value (XEXP (exp, 2), unknownp);
3697 if (n < current_min)
3698 current_min = n;
3699 break;
3701 default:
3702 *unknownp = 1;
3703 current_min = INT_MAX;
3704 break;
3707 return current_min;
3710 /* Given an attribute value, return the result of ORing together all
3711 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3712 if the numeric value is not known. */
3714 static int
3715 or_attr_value (rtx exp, int *unknownp)
3717 int current_or;
3718 int i;
3720 switch (GET_CODE (exp))
3722 case CONST_STRING:
3723 current_or = atoi (XSTR (exp, 0));
3724 break;
3726 case COND:
3727 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3728 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3729 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3730 break;
3732 case IF_THEN_ELSE:
3733 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3734 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3735 break;
3737 default:
3738 *unknownp = 1;
3739 current_or = -1;
3740 break;
3743 return current_or;
3746 /* Scan an attribute value, possibly a conditional, and record what actions
3747 will be required to do any conditional tests in it.
3749 Specifically, set
3750 `must_extract' if we need to extract the insn operands
3751 `must_constrain' if we must compute `which_alternative'
3752 `address_used' if an address expression was used
3753 `length_used' if an (eq_attr "length" ...) was used
3756 static void
3757 walk_attr_value (rtx exp)
3759 int i, j;
3760 const char *fmt;
3761 RTX_CODE code;
3763 if (exp == NULL)
3764 return;
3766 code = GET_CODE (exp);
3767 switch (code)
3769 case SYMBOL_REF:
3770 if (! ATTR_IND_SIMPLIFIED_P (exp))
3771 /* Since this is an arbitrary expression, it can look at anything.
3772 However, constant expressions do not depend on any particular
3773 insn. */
3774 must_extract = must_constrain = 1;
3775 return;
3777 case MATCH_OPERAND:
3778 must_extract = 1;
3779 return;
3781 case MATCH_TEST:
3782 case EQ_ATTR_ALT:
3783 must_extract = must_constrain = 1;
3784 break;
3786 case EQ_ATTR:
3787 if (XSTR (exp, 0) == alternative_name)
3788 must_extract = must_constrain = 1;
3789 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3790 length_used = 1;
3791 return;
3793 case MATCH_DUP:
3794 must_extract = 1;
3795 address_used = 1;
3796 return;
3798 case PC:
3799 address_used = 1;
3800 return;
3802 case ATTR_FLAG:
3803 return;
3805 default:
3806 break;
3809 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3810 switch (*fmt++)
3812 case 'e':
3813 case 'u':
3814 walk_attr_value (XEXP (exp, i));
3815 break;
3817 case 'E':
3818 if (XVEC (exp, i) != NULL)
3819 for (j = 0; j < XVECLEN (exp, i); j++)
3820 walk_attr_value (XVECEXP (exp, i, j));
3821 break;
3825 /* Write out a function to obtain the attribute for a given INSN. */
3827 static void
3828 write_attr_get (struct attr_desc *attr)
3830 struct attr_value *av, *common_av;
3831 int i, j;
3833 /* Find the most used attribute value. Handle that as the `default' of the
3834 switch we will generate. */
3835 common_av = find_most_used (attr);
3837 /* Write out start of function, then all values with explicit `case' lines,
3838 then a `default', then the value with the most uses. */
3839 if (attr->enum_name)
3840 printf ("enum %s\n", attr->enum_name);
3841 else if (!attr->is_numeric)
3842 printf ("enum attr_%s\n", attr->name);
3843 else
3844 printf ("int\n");
3846 /* If the attribute name starts with a star, the remainder is the name of
3847 the subroutine to use, instead of `get_attr_...'. */
3848 if (attr->name[0] == '*')
3849 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3850 else if (attr->is_const == 0)
3851 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3852 else
3854 printf ("get_attr_%s (void)\n", attr->name);
3855 printf ("{\n");
3857 for (av = attr->first_value; av; av = av->next)
3858 if (av->num_insns == 1)
3859 write_attr_set (attr, 2, av->value, "return", ";",
3860 true_rtx, av->first_insn->def->insn_code,
3861 av->first_insn->def->insn_index, 0);
3862 else if (av->num_insns != 0)
3863 write_attr_set (attr, 2, av->value, "return", ";",
3864 true_rtx, -2, 0, 0);
3866 printf ("}\n\n");
3867 return;
3870 printf ("{\n");
3872 /* Find attributes that are worth caching in the conditions. */
3873 cached_attr_count = 0;
3874 attrs_seen_more_than_once = 0;
3875 for (av = attr->first_value; av; av = av->next)
3877 attrs_seen_once = 0;
3878 find_attrs_to_cache (av->value, true);
3880 /* Remove those that aren't worth caching from the array. */
3881 for (i = 0, j = 0; i < cached_attr_count; i++)
3882 if ((attrs_seen_more_than_once & (1U << i)) != 0)
3884 const char *name = cached_attrs[i];
3885 struct attr_desc *cached_attr;
3886 if (i != j)
3887 cached_attrs[j] = name;
3888 cached_attr = find_attr (&name, 0);
3889 gcc_assert (cached_attr && cached_attr->is_const == 0);
3890 if (cached_attr->enum_name)
3891 printf (" enum %s", cached_attr->enum_name);
3892 else if (!cached_attr->is_numeric)
3893 printf (" enum attr_%s", cached_attr->name);
3894 else
3895 printf (" int");
3896 printf (" cached_%s ATTRIBUTE_UNUSED;\n", name);
3897 j++;
3899 cached_attr_count = j;
3900 if (cached_attr_count)
3901 printf ("\n");
3903 printf (" switch (recog_memoized (insn))\n");
3904 printf (" {\n");
3906 for (av = attr->first_value; av; av = av->next)
3907 if (av != common_av)
3908 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3910 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3911 printf (" }\n}\n\n");
3912 cached_attr_count = 0;
3915 /* Given an AND tree of known true terms (because we are inside an `if' with
3916 that as the condition or are in an `else' clause) and an expression,
3917 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3918 the bulk of the work. */
3920 static rtx
3921 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
3923 rtx term;
3925 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3927 if (GET_CODE (known_true) == AND)
3929 exp = eliminate_known_true (XEXP (known_true, 0), exp,
3930 insn_code, insn_index);
3931 exp = eliminate_known_true (XEXP (known_true, 1), exp,
3932 insn_code, insn_index);
3934 else
3936 term = known_true;
3937 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3940 return exp;
3943 /* Write out a series of tests and assignment statements to perform tests and
3944 sets of an attribute value. We are passed an indentation amount and prefix
3945 and suffix strings to write around each attribute value (e.g., "return"
3946 and ";"). */
3948 static void
3949 write_attr_set (struct attr_desc *attr, int indent, rtx value,
3950 const char *prefix, const char *suffix, rtx known_true,
3951 int insn_code, int insn_index, unsigned int attrs_cached)
3953 if (GET_CODE (value) == COND)
3955 /* Assume the default value will be the default of the COND unless we
3956 find an always true expression. */
3957 rtx default_val = XEXP (value, 1);
3958 rtx our_known_true = known_true;
3959 rtx newexp;
3960 int first_if = 1;
3961 int i;
3963 if (cached_attr_count)
3965 attrs_seen_once = 0;
3966 attrs_seen_more_than_once = 0;
3967 for (i = 0; i < XVECLEN (value, 0); i += 2)
3968 find_attrs_to_cache (XVECEXP (value, 0, i), false);
3969 attrs_to_cache |= attrs_seen_more_than_once;
3972 for (i = 0; i < XVECLEN (value, 0); i += 2)
3974 rtx testexp;
3975 rtx inner_true;
3977 testexp = eliminate_known_true (our_known_true,
3978 XVECEXP (value, 0, i),
3979 insn_code, insn_index);
3980 newexp = attr_rtx (NOT, testexp);
3981 newexp = insert_right_side (AND, our_known_true, newexp,
3982 insn_code, insn_index);
3984 /* If the test expression is always true or if the next `known_true'
3985 expression is always false, this is the last case, so break
3986 out and let this value be the `else' case. */
3987 if (testexp == true_rtx || newexp == false_rtx)
3989 default_val = XVECEXP (value, 0, i + 1);
3990 break;
3993 /* Compute the expression to pass to our recursive call as being
3994 known true. */
3995 inner_true = insert_right_side (AND, our_known_true,
3996 testexp, insn_code, insn_index);
3998 /* If this is always false, skip it. */
3999 if (inner_true == false_rtx)
4000 continue;
4002 attrs_cached_inside = attrs_cached;
4003 attrs_cached_after = attrs_cached;
4004 write_indent (indent);
4005 printf ("%sif ", first_if ? "" : "else ");
4006 first_if = 0;
4007 write_test_expr (testexp, attrs_cached,
4008 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4009 attrs_cached = attrs_cached_after;
4010 printf ("\n");
4011 write_indent (indent + 2);
4012 printf ("{\n");
4014 write_attr_set (attr, indent + 4,
4015 XVECEXP (value, 0, i + 1), prefix, suffix,
4016 inner_true, insn_code, insn_index,
4017 attrs_cached_inside);
4018 write_indent (indent + 2);
4019 printf ("}\n");
4020 our_known_true = newexp;
4023 if (! first_if)
4025 write_indent (indent);
4026 printf ("else\n");
4027 write_indent (indent + 2);
4028 printf ("{\n");
4031 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
4032 prefix, suffix, our_known_true, insn_code, insn_index,
4033 attrs_cached);
4035 if (! first_if)
4037 write_indent (indent + 2);
4038 printf ("}\n");
4041 else
4043 write_indent (indent);
4044 printf ("%s ", prefix);
4045 write_attr_value (attr, value);
4046 printf ("%s\n", suffix);
4050 /* Write a series of case statements for every instruction in list IE.
4051 INDENT is the amount of indentation to write before each case. */
4053 static void
4054 write_insn_cases (struct insn_ent *ie, int indent)
4056 for (; ie != 0; ie = ie->next)
4057 if (ie->def->insn_code != -1)
4059 write_indent (indent);
4060 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4061 printf ("case %d: /* define_peephole, line %d */\n",
4062 ie->def->insn_code, ie->def->lineno);
4063 else
4064 printf ("case %d: /* %s */\n",
4065 ie->def->insn_code, XSTR (ie->def->def, 0));
4069 /* Write out the computation for one attribute value. */
4071 static void
4072 write_attr_case (struct attr_desc *attr, struct attr_value *av,
4073 int write_case_lines, const char *prefix, const char *suffix,
4074 int indent, rtx known_true)
4076 if (av->num_insns == 0)
4077 return;
4079 if (av->has_asm_insn)
4081 write_indent (indent);
4082 printf ("case -1:\n");
4083 write_indent (indent + 2);
4084 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4085 write_indent (indent + 2);
4086 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
4087 write_indent (indent + 2);
4088 printf (" fatal_insn_not_found (insn);\n");
4091 if (write_case_lines)
4092 write_insn_cases (av->first_insn, indent);
4093 else
4095 write_indent (indent);
4096 printf ("default:\n");
4099 /* See what we have to do to output this value. */
4100 must_extract = must_constrain = address_used = 0;
4101 walk_attr_value (av->value);
4103 if (must_constrain)
4105 write_indent (indent + 2);
4106 printf ("extract_constrain_insn_cached (insn);\n");
4108 else if (must_extract)
4110 write_indent (indent + 2);
4111 printf ("extract_insn_cached (insn);\n");
4114 attrs_to_cache = 0;
4115 if (av->num_insns == 1)
4116 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
4117 known_true, av->first_insn->def->insn_code,
4118 av->first_insn->def->insn_index, 0);
4119 else
4120 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
4121 known_true, -2, 0, 0);
4123 if (strncmp (prefix, "return", 6))
4125 write_indent (indent + 2);
4126 printf ("break;\n");
4128 printf ("\n");
4131 /* Utilities to write in various forms. */
4133 static void
4134 write_attr_valueq (struct attr_desc *attr, const char *s)
4136 if (attr->is_numeric)
4138 int num = atoi (s);
4140 printf ("%d", num);
4142 if (num > 9 || num < 0)
4143 printf (" /* %#x */", num);
4145 else
4147 write_upcase (attr->enum_name ? attr->enum_name : attr->name);
4148 printf ("_");
4149 write_upcase (s);
4153 static void
4154 write_attr_value (struct attr_desc *attr, rtx value)
4156 int op;
4158 switch (GET_CODE (value))
4160 case CONST_STRING:
4161 write_attr_valueq (attr, XSTR (value, 0));
4162 break;
4164 case CONST_INT:
4165 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4166 break;
4168 case SYMBOL_REF:
4169 print_c_condition (XSTR (value, 0));
4170 break;
4172 case ATTR:
4174 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4175 if (attr->enum_name)
4176 printf ("(enum %s)", attr->enum_name);
4177 else if (!attr->is_numeric)
4178 printf ("(enum attr_%s)", attr->name);
4179 else if (!attr2->is_numeric)
4180 printf ("(int)");
4182 printf ("get_attr_%s (%s)", attr2->name,
4183 (attr2->is_const ? "" : "insn"));
4185 break;
4187 case PLUS:
4188 op = '+';
4189 goto do_operator;
4190 case MINUS:
4191 op = '-';
4192 goto do_operator;
4193 case MULT:
4194 op = '*';
4195 goto do_operator;
4196 case DIV:
4197 op = '/';
4198 goto do_operator;
4199 case MOD:
4200 op = '%';
4201 goto do_operator;
4203 do_operator:
4204 write_attr_value (attr, XEXP (value, 0));
4205 putchar (' ');
4206 putchar (op);
4207 putchar (' ');
4208 write_attr_value (attr, XEXP (value, 1));
4209 break;
4211 default:
4212 gcc_unreachable ();
4216 static void
4217 write_upcase (const char *str)
4219 while (*str)
4221 /* The argument of TOUPPER should not have side effects. */
4222 putchar (TOUPPER(*str));
4223 str++;
4227 static void
4228 write_indent (int indent)
4230 for (; indent > 8; indent -= 8)
4231 printf ("\t");
4233 for (; indent; indent--)
4234 printf (" ");
4237 /* Write a subroutine that is given an insn that requires a delay slot, a
4238 delay slot ordinal, and a candidate insn. It returns nonzero if the
4239 candidate can be placed in the specified delay slot of the insn.
4241 We can write as many as three subroutines. `eligible_for_delay'
4242 handles normal delay slots, `eligible_for_annul_true' indicates that
4243 the specified insn can be annulled if the branch is true, and likewise
4244 for `eligible_for_annul_false'.
4246 KIND is a string distinguishing these three cases ("delay", "annul_true",
4247 or "annul_false"). */
4249 static void
4250 write_eligible_delay (const char *kind)
4252 struct delay_desc *delay;
4253 int max_slots;
4254 char str[50];
4255 const char *pstr;
4256 struct attr_desc *attr;
4257 struct attr_value *av, *common_av;
4258 int i;
4260 /* Compute the maximum number of delay slots required. We use the delay
4261 ordinal times this number plus one, plus the slot number as an index into
4262 the appropriate predicate to test. */
4264 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4265 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4266 max_slots = XVECLEN (delay->def, 1) / 3;
4268 /* Write function prelude. */
4270 printf ("int\n");
4271 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4272 kind);
4273 printf ("{\n");
4274 printf (" rtx insn;\n");
4275 printf ("\n");
4276 printf (" gcc_assert (slot < %d);\n", max_slots);
4277 printf ("\n");
4278 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4279 converts a compound instruction into a loop. */
4280 printf (" if (!INSN_P (candidate_insn))\n");
4281 printf (" return 0;\n");
4282 printf ("\n");
4284 /* If more than one delay type, find out which type the delay insn is. */
4286 if (num_delays > 1)
4288 attr = find_attr (&delay_type_str, 0);
4289 gcc_assert (attr);
4290 common_av = find_most_used (attr);
4292 printf (" insn = delay_insn;\n");
4293 printf (" switch (recog_memoized (insn))\n");
4294 printf (" {\n");
4296 sprintf (str, " * %d;\n break;", max_slots);
4297 for (av = attr->first_value; av; av = av->next)
4298 if (av != common_av)
4299 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4301 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4302 printf (" }\n\n");
4304 /* Ensure matched. Otherwise, shouldn't have been called. */
4305 printf (" gcc_assert (slot >= %d);\n\n", max_slots);
4308 /* If just one type of delay slot, write simple switch. */
4309 if (num_delays == 1 && max_slots == 1)
4311 printf (" insn = candidate_insn;\n");
4312 printf (" switch (recog_memoized (insn))\n");
4313 printf (" {\n");
4315 attr = find_attr (&delay_1_0_str, 0);
4316 gcc_assert (attr);
4317 common_av = find_most_used (attr);
4319 for (av = attr->first_value; av; av = av->next)
4320 if (av != common_av)
4321 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4323 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4324 printf (" }\n");
4327 else
4329 /* Write a nested CASE. The first indicates which condition we need to
4330 test, and the inner CASE tests the condition. */
4331 printf (" insn = candidate_insn;\n");
4332 printf (" switch (slot)\n");
4333 printf (" {\n");
4335 for (delay = delays; delay; delay = delay->next)
4336 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4338 printf (" case %d:\n",
4339 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4340 printf (" switch (recog_memoized (insn))\n");
4341 printf ("\t{\n");
4343 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4344 pstr = str;
4345 attr = find_attr (&pstr, 0);
4346 gcc_assert (attr);
4347 common_av = find_most_used (attr);
4349 for (av = attr->first_value; av; av = av->next)
4350 if (av != common_av)
4351 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4353 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4354 printf (" }\n");
4357 printf (" default:\n");
4358 printf (" gcc_unreachable ();\n");
4359 printf (" }\n");
4362 printf ("}\n\n");
4365 /* This page contains miscellaneous utility routines. */
4367 /* Given a pointer to a (char *), return a malloc'ed string containing the
4368 next comma-separated element. Advance the pointer to after the string
4369 scanned, or the end-of-string. Return NULL if at end of string. */
4371 static char *
4372 next_comma_elt (const char **pstr)
4374 const char *start;
4376 start = scan_comma_elt (pstr);
4378 if (start == NULL)
4379 return NULL;
4381 return attr_string (start, *pstr - start);
4384 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4385 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4386 replaced by a pointer to a canonical copy of the string. */
4388 static struct attr_desc *
4389 find_attr (const char **name_p, int create)
4391 struct attr_desc *attr;
4392 int index;
4393 const char *name = *name_p;
4395 /* Before we resort to using `strcmp', see if the string address matches
4396 anywhere. In most cases, it should have been canonicalized to do so. */
4397 if (name == alternative_name)
4398 return NULL;
4400 index = name[0] & (MAX_ATTRS_INDEX - 1);
4401 for (attr = attrs[index]; attr; attr = attr->next)
4402 if (name == attr->name)
4403 return attr;
4405 /* Otherwise, do it the slow way. */
4406 for (attr = attrs[index]; attr; attr = attr->next)
4407 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4409 *name_p = attr->name;
4410 return attr;
4413 if (! create)
4414 return NULL;
4416 attr = oballoc (struct attr_desc);
4417 attr->name = DEF_ATTR_STRING (name);
4418 attr->enum_name = 0;
4419 attr->first_value = attr->default_val = NULL;
4420 attr->is_numeric = attr->is_const = attr->is_special = 0;
4421 attr->next = attrs[index];
4422 attrs[index] = attr;
4424 *name_p = attr->name;
4426 return attr;
4429 /* Create internal attribute with the given default value. */
4431 static void
4432 make_internal_attr (const char *name, rtx value, int special)
4434 struct attr_desc *attr;
4436 attr = find_attr (&name, 1);
4437 gcc_assert (!attr->default_val);
4439 attr->is_numeric = 1;
4440 attr->is_const = 0;
4441 attr->is_special = (special & ATTR_SPECIAL) != 0;
4442 attr->default_val = get_attr_value (value, attr, -2);
4445 /* Find the most used value of an attribute. */
4447 static struct attr_value *
4448 find_most_used (struct attr_desc *attr)
4450 struct attr_value *av;
4451 struct attr_value *most_used;
4452 int nuses;
4454 most_used = NULL;
4455 nuses = -1;
4457 for (av = attr->first_value; av; av = av->next)
4458 if (av->num_insns > nuses)
4459 nuses = av->num_insns, most_used = av;
4461 return most_used;
4464 /* Return (attr_value "n") */
4466 static rtx
4467 make_numeric_value (int n)
4469 static rtx int_values[20];
4470 rtx exp;
4471 char *p;
4473 gcc_assert (n >= 0);
4475 if (n < 20 && int_values[n])
4476 return int_values[n];
4478 p = attr_printf (MAX_DIGITS, "%d", n);
4479 exp = attr_rtx (CONST_STRING, p);
4481 if (n < 20)
4482 int_values[n] = exp;
4484 return exp;
4487 static rtx
4488 copy_rtx_unchanging (rtx orig)
4490 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4491 return orig;
4493 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4494 return orig;
4497 /* Determine if an insn has a constant number of delay slots, i.e., the
4498 number of delay slots is not a function of the length of the insn. */
4500 static void
4501 write_const_num_delay_slots (void)
4503 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4504 struct attr_value *av;
4506 if (attr)
4508 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4509 printf ("{\n");
4510 printf (" switch (recog_memoized (insn))\n");
4511 printf (" {\n");
4513 for (av = attr->first_value; av; av = av->next)
4515 length_used = 0;
4516 walk_attr_value (av->value);
4517 if (length_used)
4518 write_insn_cases (av->first_insn, 4);
4521 printf (" default:\n");
4522 printf (" return 1;\n");
4523 printf (" }\n}\n\n");
4527 /* Synthetic attributes used by insn-automata.c and the scheduler.
4528 These are primarily concerned with (define_insn_reservation)
4529 patterns. */
4531 struct insn_reserv
4533 struct insn_reserv *next;
4535 const char *name;
4536 int default_latency;
4537 rtx condexp;
4539 /* Sequence number of this insn. */
4540 int insn_num;
4542 /* Whether a (define_bypass) construct names this insn in its
4543 output list. */
4544 bool bypassed;
4547 static struct insn_reserv *all_insn_reservs = 0;
4548 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4549 static size_t n_insn_reservs;
4551 /* Store information from a DEFINE_INSN_RESERVATION for future
4552 attribute generation. */
4553 static void
4554 gen_insn_reserv (rtx def)
4556 struct insn_reserv *decl = oballoc (struct insn_reserv);
4558 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4559 decl->default_latency = XINT (def, 1);
4560 decl->condexp = check_attr_test (XEXP (def, 2), 0, 0);
4561 decl->insn_num = n_insn_reservs;
4562 decl->bypassed = false;
4563 decl->next = 0;
4565 *last_insn_reserv_p = decl;
4566 last_insn_reserv_p = &decl->next;
4567 n_insn_reservs++;
4570 /* Store information from a DEFINE_BYPASS for future attribute
4571 generation. The only thing we care about is the list of output
4572 insns, which will later be used to tag reservation structures with
4573 a 'bypassed' bit. */
4575 struct bypass_list
4577 struct bypass_list *next;
4578 const char *pattern;
4581 static struct bypass_list *all_bypasses;
4582 static size_t n_bypasses;
4584 static void
4585 gen_bypass_1 (const char *s, size_t len)
4587 struct bypass_list *b;
4589 if (len == 0)
4590 return;
4592 s = attr_string (s, len);
4593 for (b = all_bypasses; b; b = b->next)
4594 if (s == b->pattern)
4595 return; /* already got that one */
4597 b = oballoc (struct bypass_list);
4598 b->pattern = s;
4599 b->next = all_bypasses;
4600 all_bypasses = b;
4601 n_bypasses++;
4604 static void
4605 gen_bypass (rtx def)
4607 const char *p, *base;
4609 for (p = base = XSTR (def, 1); *p; p++)
4610 if (*p == ',')
4612 gen_bypass_1 (base, p - base);
4614 p++;
4615 while (ISSPACE (*p));
4616 base = p;
4618 gen_bypass_1 (base, p - base);
4621 /* Find and mark all of the bypassed insns. */
4622 static void
4623 process_bypasses (void)
4625 struct bypass_list *b;
4626 struct insn_reserv *r;
4628 /* The reservation list is likely to be much longer than the bypass
4629 list. */
4630 for (r = all_insn_reservs; r; r = r->next)
4631 for (b = all_bypasses; b; b = b->next)
4632 if (fnmatch (b->pattern, r->name, 0) == 0)
4633 r->bypassed = true;
4636 /* Check that attribute NAME is used in define_insn_reservation condition
4637 EXP. Return true if it is. */
4638 static bool
4639 check_tune_attr (const char *name, rtx exp)
4641 switch (GET_CODE (exp))
4643 case AND:
4644 if (check_tune_attr (name, XEXP (exp, 0)))
4645 return true;
4646 return check_tune_attr (name, XEXP (exp, 1));
4648 case IOR:
4649 return (check_tune_attr (name, XEXP (exp, 0))
4650 && check_tune_attr (name, XEXP (exp, 1)));
4652 case EQ_ATTR:
4653 return XSTR (exp, 0) == name;
4655 default:
4656 return false;
4660 /* Try to find a const attribute (usually cpu or tune) that is used
4661 in all define_insn_reservation conditions. */
4662 static struct attr_desc *
4663 find_tune_attr (rtx exp)
4665 struct attr_desc *attr;
4667 switch (GET_CODE (exp))
4669 case AND:
4670 case IOR:
4671 attr = find_tune_attr (XEXP (exp, 0));
4672 if (attr)
4673 return attr;
4674 return find_tune_attr (XEXP (exp, 1));
4676 case EQ_ATTR:
4677 if (XSTR (exp, 0) == alternative_name)
4678 return NULL;
4680 attr = find_attr (&XSTR (exp, 0), 0);
4681 gcc_assert (attr);
4683 if (attr->is_const && !attr->is_special)
4685 struct insn_reserv *decl;
4687 for (decl = all_insn_reservs; decl; decl = decl->next)
4688 if (! check_tune_attr (attr->name, decl->condexp))
4689 return NULL;
4690 return attr;
4692 return NULL;
4694 default:
4695 return NULL;
4699 /* Create all of the attributes that describe automaton properties. */
4700 static void
4701 make_automaton_attrs (void)
4703 int i;
4704 struct insn_reserv *decl;
4705 rtx code_exp, lats_exp, byps_exp;
4706 struct attr_desc *tune_attr;
4708 if (n_insn_reservs == 0)
4709 return;
4711 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4712 if (tune_attr != NULL)
4714 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4715 struct attr_value *val;
4716 bool first = true;
4718 gcc_assert (tune_attr->is_const
4719 && !tune_attr->is_special
4720 && !tune_attr->is_numeric);
4721 for (val = tune_attr->first_value; val; val = val->next)
4723 if (val == tune_attr->default_val)
4724 continue;
4725 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4726 printf ("static int internal_dfa_insn_code_%s (rtx);\n"
4727 "static int insn_default_latency_%s (rtx);\n",
4728 XSTR (val->value, 0), XSTR (val->value, 0));
4731 printf ("\n");
4732 printf ("int (*internal_dfa_insn_code) (rtx);\n");
4733 printf ("int (*insn_default_latency) (rtx);\n");
4734 printf ("\n");
4735 printf ("void\n");
4736 printf ("init_sched_attrs (void)\n");
4737 printf ("{\n");
4739 for (val = tune_attr->first_value; val; val = val->next)
4741 int j;
4742 char *name;
4743 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
4745 if (val == tune_attr->default_val)
4746 continue;
4747 for (decl = all_insn_reservs, i = 0;
4748 decl;
4749 decl = decl->next)
4751 rtx ctest = test;
4752 rtx condexp
4753 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
4754 if (condexp == false_rtx)
4755 continue;
4756 if (condexp == true_rtx)
4757 break;
4758 condexps[i] = condexp;
4759 condexps[i + 1] = make_numeric_value (decl->insn_num);
4760 condexps[i + 2] = make_numeric_value (decl->default_latency);
4761 i += 3;
4764 code_exp = rtx_alloc (COND);
4765 lats_exp = rtx_alloc (COND);
4767 j = i / 3 * 2;
4768 XVEC (code_exp, 0) = rtvec_alloc (j);
4769 XVEC (lats_exp, 0) = rtvec_alloc (j);
4771 if (decl)
4773 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
4774 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
4776 else
4778 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
4779 XEXP (lats_exp, 1) = make_numeric_value (0);
4782 while (i > 0)
4784 i -= 3;
4785 j -= 2;
4786 XVECEXP (code_exp, 0, j) = condexps[i];
4787 XVECEXP (lats_exp, 0, j) = condexps[i];
4789 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
4790 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
4793 name = XNEWVEC (char,
4794 sizeof ("*internal_dfa_insn_code_")
4795 + strlen (XSTR (val->value, 0)));
4796 strcpy (name, "*internal_dfa_insn_code_");
4797 strcat (name, XSTR (val->value, 0));
4798 make_internal_attr (name, code_exp, ATTR_NONE);
4799 strcpy (name, "*insn_default_latency_");
4800 strcat (name, XSTR (val->value, 0));
4801 make_internal_attr (name, lats_exp, ATTR_NONE);
4802 XDELETEVEC (name);
4804 if (first)
4806 printf (" if (");
4807 first = false;
4809 else
4810 printf (" else if (");
4811 write_test_expr (test, 0, 0);
4812 printf (")\n");
4813 printf (" {\n");
4814 printf (" internal_dfa_insn_code\n");
4815 printf (" = internal_dfa_insn_code_%s;\n",
4816 XSTR (val->value, 0));
4817 printf (" insn_default_latency\n");
4818 printf (" = insn_default_latency_%s;\n",
4819 XSTR (val->value, 0));
4820 printf (" }\n");
4823 printf (" else\n");
4824 printf (" gcc_unreachable ();\n");
4825 printf ("}\n");
4826 printf ("\n");
4828 XDELETEVEC (condexps);
4830 else
4832 code_exp = rtx_alloc (COND);
4833 lats_exp = rtx_alloc (COND);
4835 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
4836 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
4838 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
4839 XEXP (lats_exp, 1) = make_numeric_value (0);
4841 for (decl = all_insn_reservs, i = 0;
4842 decl;
4843 decl = decl->next, i += 2)
4845 XVECEXP (code_exp, 0, i) = decl->condexp;
4846 XVECEXP (lats_exp, 0, i) = decl->condexp;
4848 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
4849 XVECEXP (lats_exp, 0, i+1)
4850 = make_numeric_value (decl->default_latency);
4852 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
4853 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
4856 if (n_bypasses == 0)
4857 byps_exp = make_numeric_value (0);
4858 else
4860 process_bypasses ();
4862 byps_exp = rtx_alloc (COND);
4863 XVEC (byps_exp, 0) = rtvec_alloc (n_bypasses * 2);
4864 XEXP (byps_exp, 1) = make_numeric_value (0);
4865 for (decl = all_insn_reservs, i = 0;
4866 decl;
4867 decl = decl->next)
4868 if (decl->bypassed)
4870 XVECEXP (byps_exp, 0, i) = decl->condexp;
4871 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
4872 i += 2;
4876 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
4880 main (int argc, char **argv)
4882 rtx desc;
4883 struct attr_desc *attr;
4884 struct insn_def *id;
4885 rtx tem;
4886 int i;
4888 progname = "genattrtab";
4890 if (!init_rtx_reader_args (argc, argv))
4891 return (FATAL_EXIT_CODE);
4893 obstack_init (hash_obstack);
4894 obstack_init (temp_obstack);
4896 /* Set up true and false rtx's */
4897 true_rtx = rtx_alloc (CONST_INT);
4898 XWINT (true_rtx, 0) = 1;
4899 false_rtx = rtx_alloc (CONST_INT);
4900 XWINT (false_rtx, 0) = 0;
4901 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4902 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
4904 alternative_name = DEF_ATTR_STRING ("alternative");
4905 length_str = DEF_ATTR_STRING ("length");
4906 delay_type_str = DEF_ATTR_STRING ("*delay_type");
4907 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4908 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
4910 printf ("/* Generated automatically by the program `genattrtab'\n\
4911 from the machine description file `md'. */\n\n");
4913 /* Read the machine description. */
4915 while (1)
4917 int lineno;
4919 desc = read_md_rtx (&lineno, &insn_code_number);
4920 if (desc == NULL)
4921 break;
4923 switch (GET_CODE (desc))
4925 case DEFINE_INSN:
4926 case DEFINE_PEEPHOLE:
4927 case DEFINE_ASM_ATTRIBUTES:
4928 gen_insn (desc, lineno);
4929 break;
4931 case DEFINE_ATTR:
4932 case DEFINE_ENUM_ATTR:
4933 gen_attr (desc, lineno);
4934 break;
4936 case DEFINE_DELAY:
4937 gen_delay (desc, lineno);
4938 break;
4940 case DEFINE_INSN_RESERVATION:
4941 gen_insn_reserv (desc);
4942 break;
4944 case DEFINE_BYPASS:
4945 gen_bypass (desc);
4946 break;
4948 default:
4949 break;
4951 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
4952 insn_index_number++;
4955 if (have_error)
4956 return FATAL_EXIT_CODE;
4958 insn_code_number++;
4960 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4961 if (! got_define_asm_attributes)
4963 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4964 XVEC (tem, 0) = rtvec_alloc (0);
4965 gen_insn (tem, 0);
4968 /* Expand DEFINE_DELAY information into new attribute. */
4969 if (num_delays)
4970 expand_delays ();
4972 printf ("#include \"config.h\"\n");
4973 printf ("#include \"system.h\"\n");
4974 printf ("#include \"coretypes.h\"\n");
4975 printf ("#include \"tm.h\"\n");
4976 printf ("#include \"rtl.h\"\n");
4977 printf ("#include \"insn-attr.h\"\n");
4978 printf ("#include \"tm_p.h\"\n");
4979 printf ("#include \"insn-config.h\"\n");
4980 printf ("#include \"recog.h\"\n");
4981 printf ("#include \"regs.h\"\n");
4982 printf ("#include \"output.h\"\n");
4983 printf ("#include \"diagnostic-core.h\"\n");
4984 printf ("#include \"flags.h\"\n");
4985 printf ("#include \"function.h\"\n");
4986 printf ("\n");
4987 printf ("#define operands recog_data.operand\n\n");
4989 /* Make `insn_alternatives'. */
4990 insn_alternatives = oballocvec (int, insn_code_number);
4991 for (id = defs; id; id = id->next)
4992 if (id->insn_code >= 0)
4993 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4995 /* Make `insn_n_alternatives'. */
4996 insn_n_alternatives = oballocvec (int, insn_code_number);
4997 for (id = defs; id; id = id->next)
4998 if (id->insn_code >= 0)
4999 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5001 /* Construct extra attributes for automata. */
5002 make_automaton_attrs ();
5004 /* Prepare to write out attribute subroutines by checking everything stored
5005 away and building the attribute cases. */
5007 check_defs ();
5009 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5010 for (attr = attrs[i]; attr; attr = attr->next)
5011 attr->default_val->value
5012 = check_attr_value (attr->default_val->value, attr);
5014 if (have_error)
5015 return FATAL_EXIT_CODE;
5017 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5018 for (attr = attrs[i]; attr; attr = attr->next)
5019 fill_attr (attr);
5021 /* Construct extra attributes for `length'. */
5022 make_length_attrs ();
5024 /* Perform any possible optimizations to speed up compilation. */
5025 optimize_attrs ();
5027 /* Now write out all the `gen_attr_...' routines. Do these before the
5028 special routines so that they get defined before they are used. */
5030 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5031 for (attr = attrs[i]; attr; attr = attr->next)
5033 if (! attr->is_special && ! attr->is_const)
5034 write_attr_get (attr);
5037 /* Write out delay eligibility information, if DEFINE_DELAY present.
5038 (The function to compute the number of delay slots will be written
5039 below.) */
5040 if (num_delays)
5042 write_eligible_delay ("delay");
5043 if (have_annul_true)
5044 write_eligible_delay ("annul_true");
5045 if (have_annul_false)
5046 write_eligible_delay ("annul_false");
5049 /* Write out constant delay slot info. */
5050 write_const_num_delay_slots ();
5052 write_length_unit_log ();
5054 fflush (stdout);
5055 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);