[PATCH] Fix undefined behaviour in arc port
[official-gcc.git] / gcc / genattrtab.c
blob932b18b12374aa876b9de29ed3a8f70a5cec4c0b
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991-2015 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This program handles insn attributes and the DEFINE_DELAY and
22 DEFINE_INSN_RESERVATION definitions.
24 It produces a series of functions named `get_attr_...', one for each insn
25 attribute. Each of these is given the rtx for an insn and returns a member
26 of the enum for the attribute.
28 These subroutines have the form of a `switch' on the INSN_CODE (via
29 `recog_memoized'). Each case either returns a constant attribute value
30 or a value that depends on tests on other attributes, the form of
31 operands, or some random C expression (encoded with a SYMBOL_REF
32 expression).
34 If the attribute `alternative', or a random C expression is present,
35 `constrain_operands' is called. If either of these cases of a reference to
36 an operand is found, `extract_insn' is called.
38 The special attribute `length' is also recognized. For this operand,
39 expressions involving the address of an operand or the current insn,
40 (address (pc)), are valid. In this case, an initial pass is made to
41 set all lengths that do not depend on address. Those that do are set to
42 the maximum length. Then each insn that depends on an address is checked
43 and possibly has its length changed. The process repeats until no further
44 changed are made. The resulting lengths are saved for use by
45 `get_attr_length'.
47 A special form of DEFINE_ATTR, where the expression for default value is a
48 CONST expression, indicates an attribute that is constant for a given run
49 of the compiler. The subroutine generated for these attributes has no
50 parameters as it does not depend on any particular insn. Constant
51 attributes are typically used to specify which variety of processor is
52 used.
54 Internal attributes are defined to handle DEFINE_DELAY and
55 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
57 This program works by keeping a list of possible values for each attribute.
58 These include the basic attribute choices, default values for attribute, and
59 all derived quantities.
61 As the description file is read, the definition for each insn is saved in a
62 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
63 is created for each insn and chained to the corresponding attribute value,
64 either that specified, or the default.
66 An optimization phase is then run. This simplifies expressions for each
67 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
68 indicates when the attribute has the specified value for the insn. This
69 avoids recursive calls during compilation.
71 The strategy used when processing DEFINE_DELAY definitions is to create
72 arbitrarily complex expressions and have the optimization simplify them.
74 Once optimization is complete, any required routines and definitions
75 will be written.
77 An optimization that is not yet implemented is to hoist the constant
78 expressions entirely out of the routines and definitions that are written.
79 A way to do this is to iterate over all possible combinations of values
80 for constant attributes and generate a set of functions for that given
81 combination. An initialization function would be written that evaluates
82 the attributes and installs the corresponding set of routines and
83 definitions (each would be accessed through a pointer).
85 We use the flags in an RTX as follows:
86 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
87 independent of the insn code.
88 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
89 for the insn code currently being processed (see optimize_attrs).
90 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
91 (see attr_rtx). */
93 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), unchanging))
94 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), in_struct))
95 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG ((RTX), return_val))
97 #if 0
98 #define strcmp_check(S1, S2) ((S1) == (S2) \
99 ? 0 \
100 : (gcc_assert (strcmp ((S1), (S2))), 1))
101 #else
102 #define strcmp_check(S1, S2) ((S1) != (S2))
103 #endif
105 #include "bconfig.h"
106 #include "system.h"
107 #include "coretypes.h"
108 #include "tm.h"
109 #include "rtl.h"
110 #include "obstack.h"
111 #include "errors.h"
112 #include "read-md.h"
113 #include "gensupport.h"
114 #include "fnmatch.h"
116 #define DEBUG 0
118 /* Flags for make_internal_attr's `special' parameter. */
119 #define ATTR_NONE 0
120 #define ATTR_SPECIAL (1 << 0)
122 static struct obstack obstack1, obstack2;
123 static struct obstack *hash_obstack = &obstack1;
124 static struct obstack *temp_obstack = &obstack2;
126 /* enough space to reserve for printing out ints */
127 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
129 /* Define structures used to record attributes and values. */
131 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
132 encountered, we store all the relevant information into a
133 `struct insn_def'. This is done to allow attribute definitions to occur
134 anywhere in the file. */
136 struct insn_def
138 struct insn_def *next; /* Next insn in chain. */
139 rtx def; /* The DEFINE_... */
140 int insn_code; /* Instruction number. */
141 int insn_index; /* Expression number in file, for errors. */
142 file_location loc; /* Where in the .md files it occurs. */
143 int num_alternatives; /* Number of alternatives. */
144 int vec_idx; /* Index of attribute vector in `def'. */
147 /* Once everything has been read in, we store in each attribute value a list
148 of insn codes that have that value. Here is the structure used for the
149 list. */
151 struct insn_ent
153 struct insn_ent *next; /* Next in chain. */
154 struct insn_def *def; /* Instruction definition. */
157 /* Each value of an attribute (either constant or computed) is assigned a
158 structure which is used as the listhead of the insns that have that
159 value. */
161 struct attr_value
163 rtx value; /* Value of attribute. */
164 struct attr_value *next; /* Next attribute value in chain. */
165 struct insn_ent *first_insn; /* First insn with this value. */
166 int num_insns; /* Number of insns with this value. */
167 int has_asm_insn; /* True if this value used for `asm' insns */
170 /* Structure for each attribute. */
172 struct attr_desc
174 char *name; /* Name of attribute. */
175 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */
176 struct attr_desc *next; /* Next attribute. */
177 struct attr_value *first_value; /* First value of this attribute. */
178 struct attr_value *default_val; /* Default value for this attribute. */
179 file_location loc; /* Where in the .md files it occurs. */
180 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
181 unsigned is_const : 1; /* Attribute value constant for each run. */
182 unsigned is_special : 1; /* Don't call `write_attr_set'. */
185 /* Structure for each DEFINE_DELAY. */
187 struct delay_desc
189 rtx def; /* DEFINE_DELAY expression. */
190 struct delay_desc *next; /* Next DEFINE_DELAY. */
191 file_location loc; /* Where in the .md files it occurs. */
192 int num; /* Number of DEFINE_DELAY, starting at 1. */
195 struct attr_value_list
197 struct attr_value *av;
198 struct insn_ent *ie;
199 struct attr_desc *attr;
200 struct attr_value_list *next;
203 /* Listheads of above structures. */
205 /* This one is indexed by the first character of the attribute name. */
206 #define MAX_ATTRS_INDEX 256
207 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
208 static struct insn_def *defs;
209 static struct delay_desc *delays;
210 struct attr_value_list **insn_code_values;
212 /* Other variables. */
214 static int insn_index_number;
215 static int got_define_asm_attributes;
216 static int must_extract;
217 static int must_constrain;
218 static int address_used;
219 static int length_used;
220 static int num_delays;
221 static int have_annul_true, have_annul_false;
222 static int num_insn_ents;
224 /* Stores, for each insn code, the number of constraint alternatives. */
226 static int *insn_n_alternatives;
228 /* Stores, for each insn code, a bitmap that has bits on for each possible
229 alternative. */
231 static uint64_t *insn_alternatives;
233 /* Used to simplify expressions. */
235 static rtx true_rtx, false_rtx;
237 /* Used to reduce calls to `strcmp' */
239 static const char *alternative_name;
240 static const char *length_str;
241 static const char *delay_type_str;
242 static const char *delay_1_0_str;
243 static const char *num_delay_slots_str;
245 /* Simplify an expression. Only call the routine if there is something to
246 simplify. */
247 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
248 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
249 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
251 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
253 /* Forward declarations of functions used before their definitions, only. */
254 static char *attr_string (const char *, int);
255 static char *attr_printf (unsigned int, const char *, ...)
256 ATTRIBUTE_PRINTF_2;
257 static rtx make_numeric_value (int);
258 static struct attr_desc *find_attr (const char **, int);
259 static rtx mk_attr_alt (uint64_t);
260 static char *next_comma_elt (const char **);
261 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
262 static rtx copy_boolean (rtx);
263 static int compares_alternatives_p (rtx);
264 static void make_internal_attr (const char *, rtx, int);
265 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
266 static void walk_attr_value (rtx);
267 static int max_attr_value (rtx, int*);
268 static int min_attr_value (rtx, int*);
269 static int or_attr_value (rtx, int*);
270 static rtx simplify_test_exp (rtx, int, int);
271 static rtx simplify_test_exp_in_temp (rtx, int, int);
272 static rtx copy_rtx_unchanging (rtx);
273 static bool attr_alt_subset_p (rtx, rtx);
274 static bool attr_alt_subset_of_compl_p (rtx, rtx);
275 static void clear_struct_flag (rtx);
276 static void write_attr_valueq (FILE *, struct attr_desc *, const char *);
277 static struct attr_value *find_most_used (struct attr_desc *);
278 static void write_attr_set (FILE *, struct attr_desc *, int, rtx,
279 const char *, const char *, rtx,
280 int, int, unsigned int);
281 static void write_attr_case (FILE *, struct attr_desc *,
282 struct attr_value *,
283 int, const char *, const char *, int, rtx);
284 static void write_attr_value (FILE *, struct attr_desc *, rtx);
285 static void write_upcase (FILE *, const char *);
286 static void write_indent (FILE *, int);
287 static rtx identity_fn (rtx);
288 static rtx zero_fn (rtx);
289 static rtx one_fn (rtx);
290 static rtx max_fn (rtx);
291 static rtx min_fn (rtx);
293 #define oballoc(T) XOBNEW (hash_obstack, T)
294 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
296 /* This gen* file is unique, in that it writes out multiple files.
298 Before GCC 4.8, insn-attrtab.c was written out containing many large
299 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
300 a parallel build, and even made it impossible to build GCC on machines
301 with relatively small RAM space (PR other/29442). Therefore, the
302 atrribute functions/tables are now written out to three separate
303 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
304 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
305 rest goes to ATTR_FILE_NAME. */
307 static const char *attr_file_name = NULL;
308 static const char *dfa_file_name = NULL;
309 static const char *latency_file_name = NULL;
311 static FILE *attr_file, *dfa_file, *latency_file;
313 /* Hash table for sharing RTL and strings. */
315 /* Each hash table slot is a bucket containing a chain of these structures.
316 Strings are given negative hash codes; RTL expressions are given positive
317 hash codes. */
319 struct attr_hash
321 struct attr_hash *next; /* Next structure in the bucket. */
322 unsigned int hashcode; /* Hash code of this rtx or string. */
323 union
325 char *str; /* The string (negative hash codes) */
326 rtx rtl; /* or the RTL recorded here. */
327 } u;
330 /* Now here is the hash table. When recording an RTL, it is added to
331 the slot whose index is the hash code mod the table size. Note
332 that the hash table is used for several kinds of RTL (see attr_rtx)
333 and for strings. While all these live in the same table, they are
334 completely independent, and the hash code is computed differently
335 for each. */
337 #define RTL_HASH_SIZE 4093
338 static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
340 /* Here is how primitive or already-shared RTL's hash
341 codes are made. */
342 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
344 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
346 static void
347 attr_hash_add_rtx (unsigned int hashcode, rtx rtl)
349 struct attr_hash *h;
351 h = XOBNEW (hash_obstack, struct attr_hash);
352 h->hashcode = hashcode;
353 h->u.rtl = rtl;
354 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
355 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
358 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
360 static void
361 attr_hash_add_string (unsigned int hashcode, char *str)
363 struct attr_hash *h;
365 h = XOBNEW (hash_obstack, struct attr_hash);
366 h->hashcode = -hashcode;
367 h->u.str = str;
368 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
369 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
372 /* Generate an RTL expression, but avoid duplicates.
373 Set the ATTR_PERMANENT_P flag for these permanent objects.
375 In some cases we cannot uniquify; then we return an ordinary
376 impermanent rtx with ATTR_PERMANENT_P clear.
378 Args are as follows:
380 rtx attr_rtx (code, [element1, ..., elementn]) */
382 static rtx
383 attr_rtx_1 (enum rtx_code code, va_list p)
385 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
386 unsigned int hashcode;
387 struct attr_hash *h;
388 struct obstack *old_obstack = rtl_obstack;
390 /* For each of several cases, search the hash table for an existing entry.
391 Use that entry if one is found; otherwise create a new RTL and add it
392 to the table. */
394 if (GET_RTX_CLASS (code) == RTX_UNARY)
396 rtx arg0 = va_arg (p, rtx);
398 /* A permanent object cannot point to impermanent ones. */
399 if (! ATTR_PERMANENT_P (arg0))
401 rt_val = rtx_alloc (code);
402 XEXP (rt_val, 0) = arg0;
403 return rt_val;
406 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
407 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
408 if (h->hashcode == hashcode
409 && GET_CODE (h->u.rtl) == code
410 && XEXP (h->u.rtl, 0) == arg0)
411 return h->u.rtl;
413 if (h == 0)
415 rtl_obstack = hash_obstack;
416 rt_val = rtx_alloc (code);
417 XEXP (rt_val, 0) = arg0;
420 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
421 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
422 || GET_RTX_CLASS (code) == RTX_COMPARE
423 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
425 rtx arg0 = va_arg (p, rtx);
426 rtx arg1 = va_arg (p, rtx);
428 /* A permanent object cannot point to impermanent ones. */
429 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
431 rt_val = rtx_alloc (code);
432 XEXP (rt_val, 0) = arg0;
433 XEXP (rt_val, 1) = arg1;
434 return rt_val;
437 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
438 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
439 if (h->hashcode == hashcode
440 && GET_CODE (h->u.rtl) == code
441 && XEXP (h->u.rtl, 0) == arg0
442 && XEXP (h->u.rtl, 1) == arg1)
443 return h->u.rtl;
445 if (h == 0)
447 rtl_obstack = hash_obstack;
448 rt_val = rtx_alloc (code);
449 XEXP (rt_val, 0) = arg0;
450 XEXP (rt_val, 1) = arg1;
453 else if (code == SYMBOL_REF
454 || (GET_RTX_LENGTH (code) == 1
455 && GET_RTX_FORMAT (code)[0] == 's'))
457 char *arg0 = va_arg (p, char *);
459 arg0 = DEF_ATTR_STRING (arg0);
461 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
462 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
463 if (h->hashcode == hashcode
464 && GET_CODE (h->u.rtl) == code
465 && XSTR (h->u.rtl, 0) == arg0)
466 return h->u.rtl;
468 if (h == 0)
470 rtl_obstack = hash_obstack;
471 rt_val = rtx_alloc (code);
472 XSTR (rt_val, 0) = arg0;
473 if (code == SYMBOL_REF)
474 X0EXP (rt_val, 1) = NULL_RTX;
477 else if (GET_RTX_LENGTH (code) == 2
478 && GET_RTX_FORMAT (code)[0] == 's'
479 && GET_RTX_FORMAT (code)[1] == 's')
481 char *arg0 = va_arg (p, char *);
482 char *arg1 = va_arg (p, char *);
484 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
485 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
486 if (h->hashcode == hashcode
487 && GET_CODE (h->u.rtl) == code
488 && XSTR (h->u.rtl, 0) == arg0
489 && XSTR (h->u.rtl, 1) == arg1)
490 return h->u.rtl;
492 if (h == 0)
494 rtl_obstack = hash_obstack;
495 rt_val = rtx_alloc (code);
496 XSTR (rt_val, 0) = arg0;
497 XSTR (rt_val, 1) = arg1;
500 else if (code == CONST_INT)
502 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
503 if (arg0 == 0)
504 return false_rtx;
505 else if (arg0 == 1)
506 return true_rtx;
507 else
508 goto nohash;
510 else
512 int i; /* Array indices... */
513 const char *fmt; /* Current rtx's format... */
514 nohash:
515 rt_val = rtx_alloc (code); /* Allocate the storage space. */
517 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
518 for (i = 0; i < GET_RTX_LENGTH (code); i++)
520 switch (*fmt++)
522 case '0': /* Unused field. */
523 break;
525 case 'i': /* An integer? */
526 XINT (rt_val, i) = va_arg (p, int);
527 break;
529 case 'w': /* A wide integer? */
530 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
531 break;
533 case 's': /* A string? */
534 XSTR (rt_val, i) = va_arg (p, char *);
535 break;
537 case 'e': /* An expression? */
538 case 'u': /* An insn? Same except when printing. */
539 XEXP (rt_val, i) = va_arg (p, rtx);
540 break;
542 case 'E': /* An RTX vector? */
543 XVEC (rt_val, i) = va_arg (p, rtvec);
544 break;
546 default:
547 gcc_unreachable ();
550 return rt_val;
553 rtl_obstack = old_obstack;
554 attr_hash_add_rtx (hashcode, rt_val);
555 ATTR_PERMANENT_P (rt_val) = 1;
556 return rt_val;
559 static rtx
560 attr_rtx (enum rtx_code code, ...)
562 rtx result;
563 va_list p;
565 va_start (p, code);
566 result = attr_rtx_1 (code, p);
567 va_end (p);
568 return result;
571 /* Create a new string printed with the printf line arguments into a space
572 of at most LEN bytes:
574 rtx attr_printf (len, format, [arg1, ..., argn]) */
576 static char *
577 attr_printf (unsigned int len, const char *fmt, ...)
579 char str[256];
580 va_list p;
582 va_start (p, fmt);
584 gcc_assert (len < sizeof str); /* Leave room for \0. */
586 vsprintf (str, fmt, p);
587 va_end (p);
589 return DEF_ATTR_STRING (str);
592 static rtx
593 attr_eq (const char *name, const char *value)
595 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
598 static const char *
599 attr_numeral (int n)
601 return XSTR (make_numeric_value (n), 0);
604 /* Return a permanent (possibly shared) copy of a string STR (not assumed
605 to be null terminated) with LEN bytes. */
607 static char *
608 attr_string (const char *str, int len)
610 struct attr_hash *h;
611 unsigned int hashcode;
612 int i;
613 char *new_str;
615 /* Compute the hash code. */
616 hashcode = (len + 1) * 613U + (unsigned) str[0];
617 for (i = 1; i < len; i += 2)
618 hashcode = ((hashcode * 613) + (unsigned) str[i]);
619 if ((int) hashcode < 0)
620 hashcode = -hashcode;
622 /* Search the table for the string. */
623 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
624 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
625 && !strncmp (h->u.str, str, len))
626 return h->u.str; /* <-- return if found. */
628 /* Not found; create a permanent copy and add it to the hash table. */
629 new_str = XOBNEWVAR (hash_obstack, char, len + 1);
630 memcpy (new_str, str, len);
631 new_str[len] = '\0';
632 attr_hash_add_string (hashcode, new_str);
633 copy_md_ptr_loc (new_str, str);
635 return new_str; /* Return the new string. */
638 /* Check two rtx's for equality of contents,
639 taking advantage of the fact that if both are hashed
640 then they can't be equal unless they are the same object. */
642 static int
643 attr_equal_p (rtx x, rtx y)
645 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
646 && rtx_equal_p (x, y)));
649 /* Copy an attribute value expression,
650 descending to all depths, but not copying any
651 permanent hashed subexpressions. */
653 static rtx
654 attr_copy_rtx (rtx orig)
656 rtx copy;
657 int i, j;
658 RTX_CODE code;
659 const char *format_ptr;
661 /* No need to copy a permanent object. */
662 if (ATTR_PERMANENT_P (orig))
663 return orig;
665 code = GET_CODE (orig);
667 switch (code)
669 case REG:
670 CASE_CONST_ANY:
671 case SYMBOL_REF:
672 case MATCH_TEST:
673 case CODE_LABEL:
674 case PC:
675 case CC0:
676 return orig;
678 default:
679 break;
682 copy = rtx_alloc (code);
683 PUT_MODE (copy, GET_MODE (orig));
684 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
685 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
686 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
688 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
690 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
692 switch (*format_ptr++)
694 case 'e':
695 XEXP (copy, i) = XEXP (orig, i);
696 if (XEXP (orig, i) != NULL)
697 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
698 break;
700 case 'E':
701 case 'V':
702 XVEC (copy, i) = XVEC (orig, i);
703 if (XVEC (orig, i) != NULL)
705 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
706 for (j = 0; j < XVECLEN (copy, i); j++)
707 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
709 break;
711 case 'n':
712 case 'i':
713 XINT (copy, i) = XINT (orig, i);
714 break;
716 case 'w':
717 XWINT (copy, i) = XWINT (orig, i);
718 break;
720 case 's':
721 case 'S':
722 XSTR (copy, i) = XSTR (orig, i);
723 break;
725 default:
726 gcc_unreachable ();
729 return copy;
732 /* Given a test expression for an attribute, ensure it is validly formed.
733 IS_CONST indicates whether the expression is constant for each compiler
734 run (a constant expression may not test any particular insn).
736 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
737 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
738 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
740 Update the string address in EQ_ATTR expression to be the same used
741 in the attribute (or `alternative_name') to speed up subsequent
742 `find_attr' calls and eliminate most `strcmp' calls.
744 Return the new expression, if any. */
746 static rtx
747 check_attr_test (rtx exp, int is_const, file_location loc)
749 struct attr_desc *attr;
750 struct attr_value *av;
751 const char *name_ptr, *p;
752 rtx orexp, newexp;
754 switch (GET_CODE (exp))
756 case EQ_ATTR:
757 /* Handle negation test. */
758 if (XSTR (exp, 1)[0] == '!')
759 return check_attr_test (attr_rtx (NOT,
760 attr_eq (XSTR (exp, 0),
761 &XSTR (exp, 1)[1])),
762 is_const, loc);
764 else if (n_comma_elts (XSTR (exp, 1)) == 1)
766 attr = find_attr (&XSTR (exp, 0), 0);
767 if (attr == NULL)
769 if (! strcmp (XSTR (exp, 0), "alternative"))
770 return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1)));
771 else
772 fatal_at (loc, "unknown attribute `%s' in EQ_ATTR",
773 XSTR (exp, 0));
776 if (is_const && ! attr->is_const)
777 fatal_at (loc, "constant expression uses insn attribute `%s'"
778 " in EQ_ATTR", XSTR (exp, 0));
780 /* Copy this just to make it permanent,
781 so expressions using it can be permanent too. */
782 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
784 /* It shouldn't be possible to simplify the value given to a
785 constant attribute, so don't expand this until it's time to
786 write the test expression. */
787 if (attr->is_const)
788 ATTR_IND_SIMPLIFIED_P (exp) = 1;
790 if (attr->is_numeric)
792 for (p = XSTR (exp, 1); *p; p++)
793 if (! ISDIGIT (*p))
794 fatal_at (loc, "attribute `%s' takes only numeric values",
795 XSTR (exp, 0));
797 else
799 for (av = attr->first_value; av; av = av->next)
800 if (GET_CODE (av->value) == CONST_STRING
801 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
802 break;
804 if (av == NULL)
805 fatal_at (loc, "unknown value `%s' for `%s' attribute",
806 XSTR (exp, 1), XSTR (exp, 0));
809 else
811 if (! strcmp (XSTR (exp, 0), "alternative"))
813 int set = 0;
815 name_ptr = XSTR (exp, 1);
816 while ((p = next_comma_elt (&name_ptr)) != NULL)
817 set |= ((uint64_t) 1) << atoi (p);
819 return mk_attr_alt (set);
821 else
823 /* Make an IOR tree of the possible values. */
824 orexp = false_rtx;
825 name_ptr = XSTR (exp, 1);
826 while ((p = next_comma_elt (&name_ptr)) != NULL)
828 newexp = attr_eq (XSTR (exp, 0), p);
829 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
832 return check_attr_test (orexp, is_const, loc);
835 break;
837 case ATTR_FLAG:
838 break;
840 case CONST_INT:
841 /* Either TRUE or FALSE. */
842 if (XWINT (exp, 0))
843 return true_rtx;
844 else
845 return false_rtx;
847 case IOR:
848 case AND:
849 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, loc);
850 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, loc);
851 break;
853 case NOT:
854 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, loc);
855 break;
857 case MATCH_TEST:
858 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
859 ATTR_IND_SIMPLIFIED_P (exp) = 1;
860 break;
862 case MATCH_OPERAND:
863 if (is_const)
864 fatal_at (loc, "RTL operator \"%s\" not valid in constant attribute"
865 " test", GET_RTX_NAME (GET_CODE (exp)));
866 /* These cases can't be simplified. */
867 ATTR_IND_SIMPLIFIED_P (exp) = 1;
868 break;
870 case LE: case LT: case GT: case GE:
871 case LEU: case LTU: case GTU: case GEU:
872 case NE: case EQ:
873 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
874 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
875 exp = attr_rtx (GET_CODE (exp),
876 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
877 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
878 /* These cases can't be simplified. */
879 ATTR_IND_SIMPLIFIED_P (exp) = 1;
880 break;
882 case SYMBOL_REF:
883 if (is_const)
885 /* These cases are valid for constant attributes, but can't be
886 simplified. */
887 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
888 ATTR_IND_SIMPLIFIED_P (exp) = 1;
889 break;
891 default:
892 fatal_at (loc, "RTL operator \"%s\" not valid in attribute test",
893 GET_RTX_NAME (GET_CODE (exp)));
896 return exp;
899 /* Given an expression, ensure that it is validly formed and that all named
900 attribute values are valid for the given attribute. Issue a fatal error
901 if not.
903 Return a perhaps modified replacement expression for the value. */
905 static rtx
906 check_attr_value (rtx exp, struct attr_desc *attr)
908 struct attr_value *av;
909 const char *p;
910 int i;
912 switch (GET_CODE (exp))
914 case CONST_INT:
915 if (!attr->is_numeric)
917 error_at (attr->loc,
918 "CONST_INT not valid for non-numeric attribute %s",
919 attr->name);
920 break;
923 if (INTVAL (exp) < 0)
925 error_at (attr->loc,
926 "negative numeric value specified for attribute %s",
927 attr->name);
928 break;
930 break;
932 case CONST_STRING:
933 if (! strcmp (XSTR (exp, 0), "*"))
934 break;
936 if (attr->is_numeric)
938 p = XSTR (exp, 0);
939 for (; *p; p++)
940 if (! ISDIGIT (*p))
942 error_at (attr->loc,
943 "non-numeric value for numeric attribute %s",
944 attr->name);
945 break;
947 break;
950 for (av = attr->first_value; av; av = av->next)
951 if (GET_CODE (av->value) == CONST_STRING
952 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
953 break;
955 if (av == NULL)
956 error_at (attr->loc, "unknown value `%s' for `%s' attribute",
957 XSTR (exp, 0), attr->name);
958 break;
960 case IF_THEN_ELSE:
961 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), attr->is_const,
962 attr->loc);
963 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
964 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
965 break;
967 case PLUS:
968 case MINUS:
969 case MULT:
970 case DIV:
971 case MOD:
972 if (!attr->is_numeric)
974 error_at (attr->loc, "invalid operation `%s' for non-numeric"
975 " attribute value", GET_RTX_NAME (GET_CODE (exp)));
976 break;
978 /* Fall through. */
980 case IOR:
981 case AND:
982 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
983 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
984 break;
986 case FFS:
987 case CLZ:
988 case CTZ:
989 case POPCOUNT:
990 case PARITY:
991 case BSWAP:
992 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
993 break;
995 case COND:
996 if (XVECLEN (exp, 0) % 2 != 0)
998 error_at (attr->loc, "first operand of COND must have even length");
999 break;
1002 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1004 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1005 attr->is_const, attr->loc);
1006 XVECEXP (exp, 0, i + 1)
1007 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1010 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1011 break;
1013 case ATTR:
1015 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1016 if (attr2 == NULL)
1017 error_at (attr->loc, "unknown attribute `%s' in ATTR",
1018 XSTR (exp, 0));
1019 else if (attr->is_const && ! attr2->is_const)
1020 error_at (attr->loc,
1021 "non-constant attribute `%s' referenced from `%s'",
1022 XSTR (exp, 0), attr->name);
1023 else if (attr->is_numeric != attr2->is_numeric)
1024 error_at (attr->loc,
1025 "numeric attribute mismatch calling `%s' from `%s'",
1026 XSTR (exp, 0), attr->name);
1028 break;
1030 case SYMBOL_REF:
1031 /* A constant SYMBOL_REF is valid as a constant attribute test and
1032 is expanded later by make_canonical into a COND. In a non-constant
1033 attribute test, it is left be. */
1034 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1036 default:
1037 error_at (attr->loc, "invalid operation `%s' for attribute value",
1038 GET_RTX_NAME (GET_CODE (exp)));
1039 break;
1042 return exp;
1045 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1046 It becomes a COND with each test being (eq_attr "alternative" "n") */
1048 static rtx
1049 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1051 int num_alt = id->num_alternatives;
1052 rtx condexp;
1053 int i;
1055 if (XVECLEN (exp, 1) != num_alt)
1057 error_at (id->loc, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1058 " was %d expected %d", XVECLEN (exp, 1), num_alt);
1059 return NULL_RTX;
1062 /* Make a COND with all tests but the last. Select the last value via the
1063 default. */
1064 condexp = rtx_alloc (COND);
1065 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1067 for (i = 0; i < num_alt - 1; i++)
1069 const char *p;
1070 p = attr_numeral (i);
1072 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1073 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1076 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1078 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1081 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1082 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1084 static rtx
1085 convert_set_attr (rtx exp, struct insn_def *id)
1087 rtx newexp;
1088 const char *name_ptr;
1089 char *p;
1090 int n;
1092 /* See how many alternative specified. */
1093 n = n_comma_elts (XSTR (exp, 1));
1094 if (n == 1)
1095 return attr_rtx (SET,
1096 attr_rtx (ATTR, XSTR (exp, 0)),
1097 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1099 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1100 XSTR (newexp, 0) = XSTR (exp, 0);
1101 XVEC (newexp, 1) = rtvec_alloc (n);
1103 /* Process each comma-separated name. */
1104 name_ptr = XSTR (exp, 1);
1105 n = 0;
1106 while ((p = next_comma_elt (&name_ptr)) != NULL)
1107 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1109 return convert_set_attr_alternative (newexp, id);
1112 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1113 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1114 expressions. */
1116 static void
1117 check_defs (void)
1119 struct insn_def *id;
1120 struct attr_desc *attr;
1121 int i;
1122 rtx value;
1124 for (id = defs; id; id = id->next)
1126 if (XVEC (id->def, id->vec_idx) == NULL)
1127 continue;
1129 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1131 value = XVECEXP (id->def, id->vec_idx, i);
1132 switch (GET_CODE (value))
1134 case SET:
1135 if (GET_CODE (XEXP (value, 0)) != ATTR)
1137 error_at (id->loc, "bad attribute set");
1138 value = NULL_RTX;
1140 break;
1142 case SET_ATTR_ALTERNATIVE:
1143 value = convert_set_attr_alternative (value, id);
1144 break;
1146 case SET_ATTR:
1147 value = convert_set_attr (value, id);
1148 break;
1150 default:
1151 error_at (id->loc, "invalid attribute code %s",
1152 GET_RTX_NAME (GET_CODE (value)));
1153 value = NULL_RTX;
1155 if (value == NULL_RTX)
1156 continue;
1158 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1160 error_at (id->loc, "unknown attribute %s",
1161 XSTR (XEXP (value, 0), 0));
1162 continue;
1165 XVECEXP (id->def, id->vec_idx, i) = value;
1166 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1171 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1172 expressions by converting them into a COND. This removes cases from this
1173 program. Also, replace an attribute value of "*" with the default attribute
1174 value. LOC is the location to use for error reporting. */
1176 static rtx
1177 make_canonical (file_location loc, struct attr_desc *attr, rtx exp)
1179 int i;
1180 rtx newexp;
1182 switch (GET_CODE (exp))
1184 case CONST_INT:
1185 exp = make_numeric_value (INTVAL (exp));
1186 break;
1188 case CONST_STRING:
1189 if (! strcmp (XSTR (exp, 0), "*"))
1191 if (attr->default_val == 0)
1192 fatal_at (loc, "(attr_value \"*\") used in invalid context");
1193 exp = attr->default_val->value;
1195 else
1196 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1198 break;
1200 case SYMBOL_REF:
1201 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1202 break;
1203 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1204 This makes the COND something that won't be considered an arbitrary
1205 expression by walk_attr_value. */
1206 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1207 exp = check_attr_value (exp, attr);
1208 break;
1210 case IF_THEN_ELSE:
1211 newexp = rtx_alloc (COND);
1212 XVEC (newexp, 0) = rtvec_alloc (2);
1213 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1214 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1216 XEXP (newexp, 1) = XEXP (exp, 2);
1218 exp = newexp;
1219 /* Fall through to COND case since this is now a COND. */
1221 case COND:
1223 int allsame = 1;
1224 rtx defval;
1226 /* First, check for degenerate COND. */
1227 if (XVECLEN (exp, 0) == 0)
1228 return make_canonical (loc, attr, XEXP (exp, 1));
1229 defval = XEXP (exp, 1) = make_canonical (loc, attr, XEXP (exp, 1));
1231 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1233 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1234 XVECEXP (exp, 0, i + 1)
1235 = make_canonical (loc, attr, XVECEXP (exp, 0, i + 1));
1236 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1237 allsame = 0;
1239 if (allsame)
1240 return defval;
1242 break;
1244 default:
1245 break;
1248 return exp;
1251 static rtx
1252 copy_boolean (rtx exp)
1254 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1255 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1256 copy_boolean (XEXP (exp, 1)));
1257 if (GET_CODE (exp) == MATCH_OPERAND)
1259 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1260 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1262 else if (GET_CODE (exp) == EQ_ATTR)
1264 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1265 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1268 return exp;
1271 /* Given a value and an attribute description, return a `struct attr_value *'
1272 that represents that value. This is either an existing structure, if the
1273 value has been previously encountered, or a newly-created structure.
1275 `insn_code' is the code of an insn whose attribute has the specified
1276 value (-2 if not processing an insn). We ensure that all insns for
1277 a given value have the same number of alternatives if the value checks
1278 alternatives. LOC is the location to use for error reporting. */
1280 static struct attr_value *
1281 get_attr_value (file_location loc, rtx value, struct attr_desc *attr,
1282 int insn_code)
1284 struct attr_value *av;
1285 uint64_t num_alt = 0;
1287 value = make_canonical (loc, attr, value);
1288 if (compares_alternatives_p (value))
1290 if (insn_code < 0 || insn_alternatives == NULL)
1291 fatal_at (loc, "(eq_attr \"alternatives\" ...) used in non-insn"
1292 " context");
1293 else
1294 num_alt = insn_alternatives[insn_code];
1297 for (av = attr->first_value; av; av = av->next)
1298 if (rtx_equal_p (value, av->value)
1299 && (num_alt == 0 || av->first_insn == NULL
1300 || insn_alternatives[av->first_insn->def->insn_code]))
1301 return av;
1303 av = oballoc (struct attr_value);
1304 av->value = value;
1305 av->next = attr->first_value;
1306 attr->first_value = av;
1307 av->first_insn = NULL;
1308 av->num_insns = 0;
1309 av->has_asm_insn = 0;
1311 return av;
1314 /* After all DEFINE_DELAYs have been read in, create internal attributes
1315 to generate the required routines.
1317 First, we compute the number of delay slots for each insn (as a COND of
1318 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1319 delay type is specified, we compute a similar function giving the
1320 DEFINE_DELAY ordinal for each insn.
1322 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1323 tells whether a given insn can be in that delay slot.
1325 Normal attribute filling and optimization expands these to contain the
1326 information needed to handle delay slots. */
1328 static void
1329 expand_delays (void)
1331 struct delay_desc *delay;
1332 rtx condexp;
1333 rtx newexp;
1334 int i;
1335 char *p;
1337 /* First, generate data for `num_delay_slots' function. */
1339 condexp = rtx_alloc (COND);
1340 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1341 XEXP (condexp, 1) = make_numeric_value (0);
1343 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1345 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1346 XVECEXP (condexp, 0, i + 1)
1347 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1350 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1352 /* If more than one delay type, do the same for computing the delay type. */
1353 if (num_delays > 1)
1355 condexp = rtx_alloc (COND);
1356 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1357 XEXP (condexp, 1) = make_numeric_value (0);
1359 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1361 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1362 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1365 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1368 /* For each delay possibility and delay slot, compute an eligibility
1369 attribute for non-annulled insns and for each type of annulled (annul
1370 if true and annul if false). */
1371 for (delay = delays; delay; delay = delay->next)
1373 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1375 condexp = XVECEXP (delay->def, 1, i);
1376 if (condexp == 0)
1377 condexp = false_rtx;
1378 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1379 make_numeric_value (1), make_numeric_value (0));
1381 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1382 "*delay_%d_%d", delay->num, i / 3);
1383 make_internal_attr (p, newexp, ATTR_SPECIAL);
1385 if (have_annul_true)
1387 condexp = XVECEXP (delay->def, 1, i + 1);
1388 if (condexp == 0) condexp = false_rtx;
1389 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1390 make_numeric_value (1),
1391 make_numeric_value (0));
1392 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1393 "*annul_true_%d_%d", delay->num, i / 3);
1394 make_internal_attr (p, newexp, ATTR_SPECIAL);
1397 if (have_annul_false)
1399 condexp = XVECEXP (delay->def, 1, i + 2);
1400 if (condexp == 0) condexp = false_rtx;
1401 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1402 make_numeric_value (1),
1403 make_numeric_value (0));
1404 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1405 "*annul_false_%d_%d", delay->num, i / 3);
1406 make_internal_attr (p, newexp, ATTR_SPECIAL);
1412 /* Once all attributes and insns have been read and checked, we construct for
1413 each attribute value a list of all the insns that have that value for
1414 the attribute. */
1416 static void
1417 fill_attr (struct attr_desc *attr)
1419 struct attr_value *av;
1420 struct insn_ent *ie;
1421 struct insn_def *id;
1422 int i;
1423 rtx value;
1425 /* Don't fill constant attributes. The value is independent of
1426 any particular insn. */
1427 if (attr->is_const)
1428 return;
1430 for (id = defs; id; id = id->next)
1432 /* If no value is specified for this insn for this attribute, use the
1433 default. */
1434 value = NULL;
1435 if (XVEC (id->def, id->vec_idx))
1436 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1437 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1438 attr->name))
1439 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1441 if (value == NULL)
1442 av = attr->default_val;
1443 else
1444 av = get_attr_value (id->loc, value, attr, id->insn_code);
1446 ie = oballoc (struct insn_ent);
1447 ie->def = id;
1448 insert_insn_ent (av, ie);
1452 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1453 test that checks relative positions of insns (uses MATCH_DUP or PC).
1454 If so, replace it with what is obtained by passing the expression to
1455 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1456 recursively on each value (including the default value). Otherwise,
1457 return the value returned by NO_ADDRESS_FN applied to EXP. */
1459 static rtx
1460 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1461 rtx (*address_fn) (rtx))
1463 int i;
1464 rtx newexp;
1466 if (GET_CODE (exp) == COND)
1468 /* See if any tests use addresses. */
1469 address_used = 0;
1470 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1471 walk_attr_value (XVECEXP (exp, 0, i));
1473 if (address_used)
1474 return (*address_fn) (exp);
1476 /* Make a new copy of this COND, replacing each element. */
1477 newexp = rtx_alloc (COND);
1478 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1479 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1481 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1482 XVECEXP (newexp, 0, i + 1)
1483 = substitute_address (XVECEXP (exp, 0, i + 1),
1484 no_address_fn, address_fn);
1487 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1488 no_address_fn, address_fn);
1490 return newexp;
1493 else if (GET_CODE (exp) == IF_THEN_ELSE)
1495 address_used = 0;
1496 walk_attr_value (XEXP (exp, 0));
1497 if (address_used)
1498 return (*address_fn) (exp);
1500 return attr_rtx (IF_THEN_ELSE,
1501 substitute_address (XEXP (exp, 0),
1502 no_address_fn, address_fn),
1503 substitute_address (XEXP (exp, 1),
1504 no_address_fn, address_fn),
1505 substitute_address (XEXP (exp, 2),
1506 no_address_fn, address_fn));
1509 return (*no_address_fn) (exp);
1512 /* Make new attributes from the `length' attribute. The following are made,
1513 each corresponding to a function called from `shorten_branches' or
1514 `get_attr_length':
1516 *insn_default_length This is the length of the insn to be returned
1517 by `get_attr_length' before `shorten_branches'
1518 has been called. In each case where the length
1519 depends on relative addresses, the largest
1520 possible is used. This routine is also used
1521 to compute the initial size of the insn.
1523 *insn_variable_length_p This returns 1 if the insn's length depends
1524 on relative addresses, zero otherwise.
1526 *insn_current_length This is only called when it is known that the
1527 insn has a variable length and returns the
1528 current length, based on relative addresses.
1531 static void
1532 make_length_attrs (void)
1534 static const char *new_names[] =
1536 "*insn_default_length",
1537 "*insn_min_length",
1538 "*insn_variable_length_p",
1539 "*insn_current_length"
1541 static rtx (*const no_address_fn[]) (rtx)
1542 = {identity_fn,identity_fn, zero_fn, zero_fn};
1543 static rtx (*const address_fn[]) (rtx)
1544 = {max_fn, min_fn, one_fn, identity_fn};
1545 size_t i;
1546 struct attr_desc *length_attr, *new_attr;
1547 struct attr_value *av, *new_av;
1548 struct insn_ent *ie, *new_ie;
1550 /* See if length attribute is defined. If so, it must be numeric. Make
1551 it special so we don't output anything for it. */
1552 length_attr = find_attr (&length_str, 0);
1553 if (length_attr == 0)
1554 return;
1556 if (! length_attr->is_numeric)
1557 fatal_at (length_attr->loc, "length attribute must be numeric");
1559 length_attr->is_const = 0;
1560 length_attr->is_special = 1;
1562 /* Make each new attribute, in turn. */
1563 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1565 make_internal_attr (new_names[i],
1566 substitute_address (length_attr->default_val->value,
1567 no_address_fn[i], address_fn[i]),
1568 ATTR_NONE);
1569 new_attr = find_attr (&new_names[i], 0);
1570 for (av = length_attr->first_value; av; av = av->next)
1571 for (ie = av->first_insn; ie; ie = ie->next)
1573 new_av = get_attr_value (ie->def->loc,
1574 substitute_address (av->value,
1575 no_address_fn[i],
1576 address_fn[i]),
1577 new_attr, ie->def->insn_code);
1578 new_ie = oballoc (struct insn_ent);
1579 new_ie->def = ie->def;
1580 insert_insn_ent (new_av, new_ie);
1585 /* Utility functions called from above routine. */
1587 static rtx
1588 identity_fn (rtx exp)
1590 return exp;
1593 static rtx
1594 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1596 return make_numeric_value (0);
1599 static rtx
1600 one_fn (rtx exp ATTRIBUTE_UNUSED)
1602 return make_numeric_value (1);
1605 static rtx
1606 max_fn (rtx exp)
1608 int unknown;
1609 return make_numeric_value (max_attr_value (exp, &unknown));
1612 static rtx
1613 min_fn (rtx exp)
1615 int unknown;
1616 return make_numeric_value (min_attr_value (exp, &unknown));
1619 static void
1620 write_length_unit_log (FILE *outf)
1622 struct attr_desc *length_attr = find_attr (&length_str, 0);
1623 struct attr_value *av;
1624 struct insn_ent *ie;
1625 unsigned int length_unit_log, length_or;
1626 int unknown = 0;
1628 if (length_attr)
1630 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1631 for (av = length_attr->first_value; av; av = av->next)
1632 for (ie = av->first_insn; ie; ie = ie->next)
1633 length_or |= or_attr_value (av->value, &unknown);
1636 if (length_attr == NULL || unknown)
1637 length_unit_log = 0;
1638 else
1640 length_or = ~length_or;
1641 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1642 length_unit_log++;
1644 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1647 /* Compute approximate cost of the expression. Used to decide whether
1648 expression is cheap enough for inline. */
1649 static int
1650 attr_rtx_cost (rtx x)
1652 int cost = 1;
1653 enum rtx_code code;
1654 if (!x)
1655 return 0;
1656 code = GET_CODE (x);
1657 switch (code)
1659 case MATCH_OPERAND:
1660 if (XSTR (x, 1)[0])
1661 return 10;
1662 else
1663 return 1;
1665 case EQ_ATTR_ALT:
1666 return 1;
1668 case EQ_ATTR:
1669 /* Alternatives don't result into function call. */
1670 if (!strcmp_check (XSTR (x, 0), alternative_name))
1671 return 1;
1672 else
1673 return 5;
1674 default:
1676 int i, j;
1677 const char *fmt = GET_RTX_FORMAT (code);
1678 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1680 switch (fmt[i])
1682 case 'V':
1683 case 'E':
1684 for (j = 0; j < XVECLEN (x, i); j++)
1685 cost += attr_rtx_cost (XVECEXP (x, i, j));
1686 break;
1687 case 'e':
1688 cost += attr_rtx_cost (XEXP (x, i));
1689 break;
1693 break;
1695 return cost;
1698 /* Take a COND expression and see if any of the conditions in it can be
1699 simplified. If any are known true or known false for the particular insn
1700 code, the COND can be further simplified.
1702 Also call ourselves on any COND operations that are values of this COND.
1704 We do not modify EXP; rather, we make and return a new rtx. */
1706 static rtx
1707 simplify_cond (rtx exp, int insn_code, int insn_index)
1709 int i, j;
1710 /* We store the desired contents here,
1711 then build a new expression if they don't match EXP. */
1712 rtx defval = XEXP (exp, 1);
1713 rtx new_defval = XEXP (exp, 1);
1714 int len = XVECLEN (exp, 0);
1715 rtx *tests = XNEWVEC (rtx, len);
1716 int allsame = 1;
1717 rtx ret;
1719 /* This lets us free all storage allocated below, if appropriate. */
1720 obstack_finish (rtl_obstack);
1722 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1724 /* See if default value needs simplification. */
1725 if (GET_CODE (defval) == COND)
1726 new_defval = simplify_cond (defval, insn_code, insn_index);
1728 /* Simplify the subexpressions, and see what tests we can get rid of. */
1730 for (i = 0; i < len; i += 2)
1732 rtx newtest, newval;
1734 /* Simplify this test. */
1735 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1736 tests[i] = newtest;
1738 newval = tests[i + 1];
1739 /* See if this value may need simplification. */
1740 if (GET_CODE (newval) == COND)
1741 newval = simplify_cond (newval, insn_code, insn_index);
1743 /* Look for ways to delete or combine this test. */
1744 if (newtest == true_rtx)
1746 /* If test is true, make this value the default
1747 and discard this + any following tests. */
1748 len = i;
1749 defval = tests[i + 1];
1750 new_defval = newval;
1753 else if (newtest == false_rtx)
1755 /* If test is false, discard it and its value. */
1756 for (j = i; j < len - 2; j++)
1757 tests[j] = tests[j + 2];
1758 i -= 2;
1759 len -= 2;
1762 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1764 /* If this value and the value for the prev test are the same,
1765 merge the tests. */
1767 tests[i - 2]
1768 = insert_right_side (IOR, tests[i - 2], newtest,
1769 insn_code, insn_index);
1771 /* Delete this test/value. */
1772 for (j = i; j < len - 2; j++)
1773 tests[j] = tests[j + 2];
1774 len -= 2;
1775 i -= 2;
1778 else
1779 tests[i + 1] = newval;
1782 /* If the last test in a COND has the same value
1783 as the default value, that test isn't needed. */
1785 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1786 len -= 2;
1788 /* See if we changed anything. */
1789 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1790 allsame = 0;
1791 else
1792 for (i = 0; i < len; i++)
1793 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1795 allsame = 0;
1796 break;
1799 if (len == 0)
1801 if (GET_CODE (defval) == COND)
1802 ret = simplify_cond (defval, insn_code, insn_index);
1803 else
1804 ret = defval;
1806 else if (allsame)
1807 ret = exp;
1808 else
1810 rtx newexp = rtx_alloc (COND);
1812 XVEC (newexp, 0) = rtvec_alloc (len);
1813 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1814 XEXP (newexp, 1) = new_defval;
1815 ret = newexp;
1817 free (tests);
1818 return ret;
1821 /* Remove an insn entry from an attribute value. */
1823 static void
1824 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1826 struct insn_ent *previe;
1828 if (av->first_insn == ie)
1829 av->first_insn = ie->next;
1830 else
1832 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1834 previe->next = ie->next;
1837 av->num_insns--;
1838 if (ie->def->insn_code == -1)
1839 av->has_asm_insn = 0;
1841 num_insn_ents--;
1844 /* Insert an insn entry in an attribute value list. */
1846 static void
1847 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1849 ie->next = av->first_insn;
1850 av->first_insn = ie;
1851 av->num_insns++;
1852 if (ie->def->insn_code == -1)
1853 av->has_asm_insn = 1;
1855 num_insn_ents++;
1858 /* This is a utility routine to take an expression that is a tree of either
1859 AND or IOR expressions and insert a new term. The new term will be
1860 inserted at the right side of the first node whose code does not match
1861 the root. A new node will be created with the root's code. Its left
1862 side will be the old right side and its right side will be the new
1863 term.
1865 If the `term' is itself a tree, all its leaves will be inserted. */
1867 static rtx
1868 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1870 rtx newexp;
1872 /* Avoid consing in some special cases. */
1873 if (code == AND && term == true_rtx)
1874 return exp;
1875 if (code == AND && term == false_rtx)
1876 return false_rtx;
1877 if (code == AND && exp == true_rtx)
1878 return term;
1879 if (code == AND && exp == false_rtx)
1880 return false_rtx;
1881 if (code == IOR && term == true_rtx)
1882 return true_rtx;
1883 if (code == IOR && term == false_rtx)
1884 return exp;
1885 if (code == IOR && exp == true_rtx)
1886 return true_rtx;
1887 if (code == IOR && exp == false_rtx)
1888 return term;
1889 if (attr_equal_p (exp, term))
1890 return exp;
1892 if (GET_CODE (term) == code)
1894 exp = insert_right_side (code, exp, XEXP (term, 0),
1895 insn_code, insn_index);
1896 exp = insert_right_side (code, exp, XEXP (term, 1),
1897 insn_code, insn_index);
1899 return exp;
1902 if (GET_CODE (exp) == code)
1904 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1905 term, insn_code, insn_index);
1906 if (new_rtx != XEXP (exp, 1))
1907 /* Make a copy of this expression and call recursively. */
1908 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1909 else
1910 newexp = exp;
1912 else
1914 /* Insert the new term. */
1915 newexp = attr_rtx (code, exp, term);
1918 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1921 /* If we have an expression which AND's a bunch of
1922 (not (eq_attrq "alternative" "n"))
1923 terms, we may have covered all or all but one of the possible alternatives.
1924 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1926 This routine is passed an expression and either AND or IOR. It returns a
1927 bitmask indicating which alternatives are mentioned within EXP. */
1929 static uint64_t
1930 compute_alternative_mask (rtx exp, enum rtx_code code)
1932 const char *string;
1933 if (GET_CODE (exp) == code)
1934 return compute_alternative_mask (XEXP (exp, 0), code)
1935 | compute_alternative_mask (XEXP (exp, 1), code);
1937 else if (code == AND && GET_CODE (exp) == NOT
1938 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1939 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1940 string = XSTR (XEXP (exp, 0), 1);
1942 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1943 && XSTR (exp, 0) == alternative_name)
1944 string = XSTR (exp, 1);
1946 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1948 if (code == AND && XINT (exp, 1))
1949 return XINT (exp, 0);
1951 if (code == IOR && !XINT (exp, 1))
1952 return XINT (exp, 0);
1954 return 0;
1956 else
1957 return 0;
1959 if (string[1] == 0)
1960 return ((uint64_t) 1) << (string[0] - '0');
1961 return ((uint64_t) 1) << atoi (string);
1964 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1965 attribute with the value represented by that bit. */
1967 static rtx
1968 make_alternative_compare (uint64_t mask)
1970 return mk_attr_alt (mask);
1973 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1974 of "attr" for this insn code. From that value, we can compute a test
1975 showing when the EQ_ATTR will be true. This routine performs that
1976 computation. If a test condition involves an address, we leave the EQ_ATTR
1977 intact because addresses are only valid for the `length' attribute.
1979 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1980 it refers. VALUE is the value of that attribute for the insn
1981 corresponding to INSN_CODE and INSN_INDEX. */
1983 static rtx
1984 evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
1985 int insn_code, int insn_index)
1987 rtx orexp, andexp;
1988 rtx right;
1989 rtx newexp;
1990 int i;
1992 while (GET_CODE (value) == ATTR)
1994 struct attr_value *av = NULL;
1996 attr = find_attr (&XSTR (value, 0), 0);
1998 if (insn_code_values)
2000 struct attr_value_list *iv;
2001 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2002 if (iv->attr == attr)
2004 av = iv->av;
2005 break;
2008 else
2010 struct insn_ent *ie;
2011 for (av = attr->first_value; av; av = av->next)
2012 for (ie = av->first_insn; ie; ie = ie->next)
2013 if (ie->def->insn_code == insn_code)
2014 goto got_av;
2016 if (av)
2018 got_av:
2019 value = av->value;
2023 switch (GET_CODE (value))
2025 case CONST_STRING:
2026 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
2027 newexp = true_rtx;
2028 else
2029 newexp = false_rtx;
2030 break;
2032 case SYMBOL_REF:
2034 const char *prefix;
2035 char *string, *p;
2037 gcc_assert (GET_CODE (exp) == EQ_ATTR);
2038 prefix = attr->enum_name ? attr->enum_name : attr->name;
2039 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
2040 for (p = string; *p; p++)
2041 *p = TOUPPER (*p);
2043 newexp = attr_rtx (EQ, value,
2044 attr_rtx (SYMBOL_REF,
2045 DEF_ATTR_STRING (string)));
2046 break;
2049 case COND:
2050 /* We construct an IOR of all the cases for which the
2051 requested attribute value is present. Since we start with
2052 FALSE, if it is not present, FALSE will be returned.
2054 Each case is the AND of the NOT's of the previous conditions with the
2055 current condition; in the default case the current condition is TRUE.
2057 For each possible COND value, call ourselves recursively.
2059 The extra TRUE and FALSE expressions will be eliminated by another
2060 call to the simplification routine. */
2062 orexp = false_rtx;
2063 andexp = true_rtx;
2065 for (i = 0; i < XVECLEN (value, 0); i += 2)
2067 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2068 insn_code, insn_index);
2070 right = insert_right_side (AND, andexp, this_cond,
2071 insn_code, insn_index);
2072 right = insert_right_side (AND, right,
2073 evaluate_eq_attr (exp, attr,
2074 XVECEXP (value, 0,
2075 i + 1),
2076 insn_code, insn_index),
2077 insn_code, insn_index);
2078 orexp = insert_right_side (IOR, orexp, right,
2079 insn_code, insn_index);
2081 /* Add this condition into the AND expression. */
2082 newexp = attr_rtx (NOT, this_cond);
2083 andexp = insert_right_side (AND, andexp, newexp,
2084 insn_code, insn_index);
2087 /* Handle the default case. */
2088 right = insert_right_side (AND, andexp,
2089 evaluate_eq_attr (exp, attr, XEXP (value, 1),
2090 insn_code, insn_index),
2091 insn_code, insn_index);
2092 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2093 break;
2095 default:
2096 gcc_unreachable ();
2099 /* If uses an address, must return original expression. But set the
2100 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2102 address_used = 0;
2103 walk_attr_value (newexp);
2105 if (address_used)
2107 if (! ATTR_IND_SIMPLIFIED_P (exp))
2108 return copy_rtx_unchanging (exp);
2109 return exp;
2111 else
2112 return newexp;
2115 /* This routine is called when an AND of a term with a tree of AND's is
2116 encountered. If the term or its complement is present in the tree, it
2117 can be replaced with TRUE or FALSE, respectively.
2119 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2120 be true and hence are complementary.
2122 There is one special case: If we see
2123 (and (not (eq_attr "att" "v1"))
2124 (eq_attr "att" "v2"))
2125 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2126 replace the term, not anything in the AND tree. So we pass a pointer to
2127 the term. */
2129 static rtx
2130 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2132 rtx left, right;
2133 rtx newexp;
2134 rtx temp;
2135 int left_eliminates_term, right_eliminates_term;
2137 if (GET_CODE (exp) == AND)
2139 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2140 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2141 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2143 newexp = attr_rtx (AND, left, right);
2145 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2149 else if (GET_CODE (exp) == IOR)
2151 /* For the IOR case, we do the same as above, except that we can
2152 only eliminate `term' if both sides of the IOR would do so. */
2153 temp = *pterm;
2154 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2155 left_eliminates_term = (temp == true_rtx);
2157 temp = *pterm;
2158 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2159 right_eliminates_term = (temp == true_rtx);
2161 if (left_eliminates_term && right_eliminates_term)
2162 *pterm = true_rtx;
2164 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2166 newexp = attr_rtx (IOR, left, right);
2168 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2172 /* Check for simplifications. Do some extra checking here since this
2173 routine is called so many times. */
2175 if (exp == *pterm)
2176 return true_rtx;
2178 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2179 return false_rtx;
2181 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2182 return false_rtx;
2184 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2186 if (attr_alt_subset_p (*pterm, exp))
2187 return true_rtx;
2189 if (attr_alt_subset_of_compl_p (*pterm, exp))
2190 return false_rtx;
2192 if (attr_alt_subset_p (exp, *pterm))
2193 *pterm = true_rtx;
2195 return exp;
2198 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2200 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2201 return exp;
2203 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2204 return true_rtx;
2205 else
2206 return false_rtx;
2209 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2210 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2212 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2213 return exp;
2215 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2216 return false_rtx;
2217 else
2218 return true_rtx;
2221 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2222 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2224 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2225 return exp;
2227 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2228 return false_rtx;
2229 else
2230 *pterm = true_rtx;
2233 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2235 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2236 return true_rtx;
2239 else if (GET_CODE (exp) == NOT)
2241 if (attr_equal_p (XEXP (exp, 0), *pterm))
2242 return false_rtx;
2245 else if (GET_CODE (*pterm) == NOT)
2247 if (attr_equal_p (XEXP (*pterm, 0), exp))
2248 return false_rtx;
2251 else if (attr_equal_p (exp, *pterm))
2252 return true_rtx;
2254 return exp;
2257 /* Similar to `simplify_and_tree', but for IOR trees. */
2259 static rtx
2260 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2262 rtx left, right;
2263 rtx newexp;
2264 rtx temp;
2265 int left_eliminates_term, right_eliminates_term;
2267 if (GET_CODE (exp) == IOR)
2269 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2270 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2271 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2273 newexp = attr_rtx (GET_CODE (exp), left, right);
2275 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2279 else if (GET_CODE (exp) == AND)
2281 /* For the AND case, we do the same as above, except that we can
2282 only eliminate `term' if both sides of the AND would do so. */
2283 temp = *pterm;
2284 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2285 left_eliminates_term = (temp == false_rtx);
2287 temp = *pterm;
2288 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2289 right_eliminates_term = (temp == false_rtx);
2291 if (left_eliminates_term && right_eliminates_term)
2292 *pterm = false_rtx;
2294 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2296 newexp = attr_rtx (GET_CODE (exp), left, right);
2298 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2302 if (attr_equal_p (exp, *pterm))
2303 return false_rtx;
2305 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2306 return true_rtx;
2308 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2309 return true_rtx;
2311 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2312 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2313 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2314 *pterm = false_rtx;
2316 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2317 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2318 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2319 return false_rtx;
2321 return exp;
2324 /* Simplify test expression and use temporary obstack in order to avoid
2325 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2326 and avoid unnecessary copying if possible. */
2328 static rtx
2329 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2331 rtx x;
2332 struct obstack *old;
2333 if (ATTR_IND_SIMPLIFIED_P (exp))
2334 return exp;
2335 old = rtl_obstack;
2336 rtl_obstack = temp_obstack;
2337 x = simplify_test_exp (exp, insn_code, insn_index);
2338 rtl_obstack = old;
2339 if (x == exp || rtl_obstack == temp_obstack)
2340 return x;
2341 return attr_copy_rtx (x);
2344 /* Returns true if S1 is a subset of S2. */
2346 static bool
2347 attr_alt_subset_p (rtx s1, rtx s2)
2349 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2351 case (0 << 1) | 0:
2352 return !(XINT (s1, 0) &~ XINT (s2, 0));
2354 case (0 << 1) | 1:
2355 return !(XINT (s1, 0) & XINT (s2, 0));
2357 case (1 << 1) | 0:
2358 return false;
2360 case (1 << 1) | 1:
2361 return !(XINT (s2, 0) &~ XINT (s1, 0));
2363 default:
2364 gcc_unreachable ();
2368 /* Returns true if S1 is a subset of complement of S2. */
2370 static bool
2371 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2373 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2375 case (0 << 1) | 0:
2376 return !(XINT (s1, 0) & XINT (s2, 0));
2378 case (0 << 1) | 1:
2379 return !(XINT (s1, 0) & ~XINT (s2, 0));
2381 case (1 << 1) | 0:
2382 return !(XINT (s2, 0) &~ XINT (s1, 0));
2384 case (1 << 1) | 1:
2385 return false;
2387 default:
2388 gcc_unreachable ();
2392 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2394 static rtx
2395 attr_alt_intersection (rtx s1, rtx s2)
2397 rtx result = rtx_alloc (EQ_ATTR_ALT);
2399 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2401 case (0 << 1) | 0:
2402 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2403 break;
2404 case (0 << 1) | 1:
2405 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2406 break;
2407 case (1 << 1) | 0:
2408 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2409 break;
2410 case (1 << 1) | 1:
2411 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2412 break;
2413 default:
2414 gcc_unreachable ();
2416 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2418 return result;
2421 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2423 static rtx
2424 attr_alt_union (rtx s1, rtx s2)
2426 rtx result = rtx_alloc (EQ_ATTR_ALT);
2428 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2430 case (0 << 1) | 0:
2431 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2432 break;
2433 case (0 << 1) | 1:
2434 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2435 break;
2436 case (1 << 1) | 0:
2437 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2438 break;
2439 case (1 << 1) | 1:
2440 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2441 break;
2442 default:
2443 gcc_unreachable ();
2446 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2447 return result;
2450 /* Return EQ_ATTR_ALT expression representing complement of S. */
2452 static rtx
2453 attr_alt_complement (rtx s)
2455 rtx result = rtx_alloc (EQ_ATTR_ALT);
2457 XINT (result, 0) = XINT (s, 0);
2458 XINT (result, 1) = 1 - XINT (s, 1);
2460 return result;
2463 /* Return EQ_ATTR_ALT expression representing set containing elements set
2464 in E. */
2466 static rtx
2467 mk_attr_alt (uint64_t e)
2469 rtx result = rtx_alloc (EQ_ATTR_ALT);
2471 XINT (result, 0) = e;
2472 XINT (result, 1) = 0;
2474 return result;
2477 /* Given an expression, see if it can be simplified for a particular insn
2478 code based on the values of other attributes being tested. This can
2479 eliminate nested get_attr_... calls.
2481 Note that if an endless recursion is specified in the patterns, the
2482 optimization will loop. However, it will do so in precisely the cases where
2483 an infinite recursion loop could occur during compilation. It's better that
2484 it occurs here! */
2486 static rtx
2487 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2489 rtx left, right;
2490 struct attr_desc *attr;
2491 struct attr_value *av;
2492 struct insn_ent *ie;
2493 struct attr_value_list *iv;
2494 uint64_t i;
2495 rtx newexp = exp;
2496 bool left_alt, right_alt;
2498 /* Don't re-simplify something we already simplified. */
2499 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2500 return exp;
2502 switch (GET_CODE (exp))
2504 case AND:
2505 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2506 if (left == false_rtx)
2507 return false_rtx;
2508 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2509 if (right == false_rtx)
2510 return false_rtx;
2512 if (GET_CODE (left) == EQ_ATTR_ALT
2513 && GET_CODE (right) == EQ_ATTR_ALT)
2515 exp = attr_alt_intersection (left, right);
2516 return simplify_test_exp (exp, insn_code, insn_index);
2519 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2520 present on both sides, apply the distributive law since this will
2521 yield simplifications. */
2522 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2523 && compute_alternative_mask (left, IOR)
2524 && compute_alternative_mask (right, IOR))
2526 if (GET_CODE (left) == IOR)
2527 std::swap (left, right);
2529 newexp = attr_rtx (IOR,
2530 attr_rtx (AND, left, XEXP (right, 0)),
2531 attr_rtx (AND, left, XEXP (right, 1)));
2533 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2536 /* Try with the term on both sides. */
2537 right = simplify_and_tree (right, &left, insn_code, insn_index);
2538 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2539 left = simplify_and_tree (left, &right, insn_code, insn_index);
2541 if (left == false_rtx || right == false_rtx)
2542 return false_rtx;
2543 else if (left == true_rtx)
2545 return right;
2547 else if (right == true_rtx)
2549 return left;
2551 /* See if all or all but one of the insn's alternatives are specified
2552 in this tree. Optimize if so. */
2554 if (GET_CODE (left) == NOT)
2555 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2556 && XSTR (XEXP (left, 0), 0) == alternative_name);
2557 else
2558 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2559 && XINT (left, 1));
2561 if (GET_CODE (right) == NOT)
2562 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2563 && XSTR (XEXP (right, 0), 0) == alternative_name);
2564 else
2565 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2566 && XINT (right, 1));
2568 if (insn_code >= 0
2569 && (GET_CODE (left) == AND
2570 || left_alt
2571 || GET_CODE (right) == AND
2572 || right_alt))
2574 i = compute_alternative_mask (exp, AND);
2575 if (i & ~insn_alternatives[insn_code])
2576 fatal ("invalid alternative specified for pattern number %d",
2577 insn_index);
2579 /* If all alternatives are excluded, this is false. */
2580 i ^= insn_alternatives[insn_code];
2581 if (i == 0)
2582 return false_rtx;
2583 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2585 /* If just one excluded, AND a comparison with that one to the
2586 front of the tree. The others will be eliminated by
2587 optimization. We do not want to do this if the insn has one
2588 alternative and we have tested none of them! */
2589 left = make_alternative_compare (i);
2590 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2591 newexp = attr_rtx (AND, left, right);
2593 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2597 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2599 newexp = attr_rtx (AND, left, right);
2600 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2602 break;
2604 case IOR:
2605 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2606 if (left == true_rtx)
2607 return true_rtx;
2608 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2609 if (right == true_rtx)
2610 return true_rtx;
2612 if (GET_CODE (left) == EQ_ATTR_ALT
2613 && GET_CODE (right) == EQ_ATTR_ALT)
2615 exp = attr_alt_union (left, right);
2616 return simplify_test_exp (exp, insn_code, insn_index);
2619 right = simplify_or_tree (right, &left, insn_code, insn_index);
2620 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2621 left = simplify_or_tree (left, &right, insn_code, insn_index);
2623 if (right == true_rtx || left == true_rtx)
2624 return true_rtx;
2625 else if (left == false_rtx)
2627 return right;
2629 else if (right == false_rtx)
2631 return left;
2634 /* Test for simple cases where the distributive law is useful. I.e.,
2635 convert (ior (and (x) (y))
2636 (and (x) (z)))
2637 to (and (x)
2638 (ior (y) (z)))
2641 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2642 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2644 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2646 left = XEXP (left, 0);
2647 right = newexp;
2648 newexp = attr_rtx (AND, left, right);
2649 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2652 /* Similarly,
2653 convert (ior (and (y) (x))
2654 (and (z) (x)))
2655 to (and (ior (y) (z))
2656 (x))
2657 Note that we want the common term to stay at the end.
2660 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2661 && attr_equal_p (XEXP (left, 1), XEXP (right, 1)))
2663 newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0));
2665 left = newexp;
2666 right = XEXP (right, 1);
2667 newexp = attr_rtx (AND, left, right);
2668 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2671 /* See if all or all but one of the insn's alternatives are specified
2672 in this tree. Optimize if so. */
2674 else if (insn_code >= 0
2675 && (GET_CODE (left) == IOR
2676 || (GET_CODE (left) == EQ_ATTR_ALT
2677 && !XINT (left, 1))
2678 || (GET_CODE (left) == EQ_ATTR
2679 && XSTR (left, 0) == alternative_name)
2680 || GET_CODE (right) == IOR
2681 || (GET_CODE (right) == EQ_ATTR_ALT
2682 && !XINT (right, 1))
2683 || (GET_CODE (right) == EQ_ATTR
2684 && XSTR (right, 0) == alternative_name)))
2686 i = compute_alternative_mask (exp, IOR);
2687 if (i & ~insn_alternatives[insn_code])
2688 fatal ("invalid alternative specified for pattern number %d",
2689 insn_index);
2691 /* If all alternatives are included, this is true. */
2692 i ^= insn_alternatives[insn_code];
2693 if (i == 0)
2694 return true_rtx;
2695 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2697 /* If just one excluded, IOR a comparison with that one to the
2698 front of the tree. The others will be eliminated by
2699 optimization. We do not want to do this if the insn has one
2700 alternative and we have tested none of them! */
2701 left = make_alternative_compare (i);
2702 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2703 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2705 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2709 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2711 newexp = attr_rtx (IOR, left, right);
2712 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2714 break;
2716 case NOT:
2717 if (GET_CODE (XEXP (exp, 0)) == NOT)
2719 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2720 insn_code, insn_index);
2721 return left;
2724 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2725 if (GET_CODE (left) == NOT)
2726 return XEXP (left, 0);
2728 if (left == false_rtx)
2729 return true_rtx;
2730 if (left == true_rtx)
2731 return false_rtx;
2733 if (GET_CODE (left) == EQ_ATTR_ALT)
2735 exp = attr_alt_complement (left);
2736 return simplify_test_exp (exp, insn_code, insn_index);
2739 /* Try to apply De`Morgan's laws. */
2740 if (GET_CODE (left) == IOR)
2742 newexp = attr_rtx (AND,
2743 attr_rtx (NOT, XEXP (left, 0)),
2744 attr_rtx (NOT, XEXP (left, 1)));
2746 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2748 else if (GET_CODE (left) == AND)
2750 newexp = attr_rtx (IOR,
2751 attr_rtx (NOT, XEXP (left, 0)),
2752 attr_rtx (NOT, XEXP (left, 1)));
2754 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2756 else if (left != XEXP (exp, 0))
2758 newexp = attr_rtx (NOT, left);
2760 break;
2762 case EQ_ATTR_ALT:
2763 if (!XINT (exp, 0))
2764 return XINT (exp, 1) ? true_rtx : false_rtx;
2765 break;
2767 case EQ_ATTR:
2768 if (XSTR (exp, 0) == alternative_name)
2770 newexp = mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1)));
2771 break;
2774 /* Look at the value for this insn code in the specified attribute.
2775 We normally can replace this comparison with the condition that
2776 would give this insn the values being tested for. */
2777 if (insn_code >= 0
2778 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2780 rtx x;
2782 av = NULL;
2783 if (insn_code_values)
2785 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2786 if (iv->attr == attr)
2788 av = iv->av;
2789 break;
2792 else
2794 for (av = attr->first_value; av; av = av->next)
2795 for (ie = av->first_insn; ie; ie = ie->next)
2796 if (ie->def->insn_code == insn_code)
2797 goto got_av;
2800 if (av)
2802 got_av:
2803 x = evaluate_eq_attr (exp, attr, av->value,
2804 insn_code, insn_index);
2805 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2806 if (attr_rtx_cost (x) < 7)
2807 return x;
2810 break;
2812 default:
2813 break;
2816 /* We have already simplified this expression. Simplifying it again
2817 won't buy anything unless we weren't given a valid insn code
2818 to process (i.e., we are canonicalizing something.). */
2819 if (insn_code != -2
2820 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2821 return copy_rtx_unchanging (newexp);
2823 return newexp;
2826 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2827 otherwise return 0. */
2829 static int
2830 tests_attr_p (rtx p, struct attr_desc *attr)
2832 const char *fmt;
2833 int i, ie, j, je;
2835 if (GET_CODE (p) == EQ_ATTR)
2837 if (XSTR (p, 0) != attr->name)
2838 return 0;
2839 return 1;
2842 fmt = GET_RTX_FORMAT (GET_CODE (p));
2843 ie = GET_RTX_LENGTH (GET_CODE (p));
2844 for (i = 0; i < ie; i++)
2846 switch (*fmt++)
2848 case 'e':
2849 if (tests_attr_p (XEXP (p, i), attr))
2850 return 1;
2851 break;
2853 case 'E':
2854 je = XVECLEN (p, i);
2855 for (j = 0; j < je; ++j)
2856 if (tests_attr_p (XVECEXP (p, i, j), attr))
2857 return 1;
2858 break;
2862 return 0;
2865 /* Calculate a topological sorting of all attributes so that
2866 all attributes only depend on attributes in front of it.
2867 Place the result in *RET (which is a pointer to an array of
2868 attr_desc pointers), and return the size of that array. */
2870 static int
2871 get_attr_order (struct attr_desc ***ret)
2873 int i, j;
2874 int num = 0;
2875 struct attr_desc *attr;
2876 struct attr_desc **all, **sorted;
2877 char *handled;
2878 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2879 for (attr = attrs[i]; attr; attr = attr->next)
2880 num++;
2881 all = XNEWVEC (struct attr_desc *, num);
2882 sorted = XNEWVEC (struct attr_desc *, num);
2883 handled = XCNEWVEC (char, num);
2884 num = 0;
2885 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2886 for (attr = attrs[i]; attr; attr = attr->next)
2887 all[num++] = attr;
2889 j = 0;
2890 for (i = 0; i < num; i++)
2891 if (all[i]->is_const)
2892 handled[i] = 1, sorted[j++] = all[i];
2894 /* We have only few attributes hence we can live with the inner
2895 loop being O(n^2), unlike the normal fast variants of topological
2896 sorting. */
2897 while (j < num)
2899 for (i = 0; i < num; i++)
2900 if (!handled[i])
2902 /* Let's see if I depends on anything interesting. */
2903 int k;
2904 for (k = 0; k < num; k++)
2905 if (!handled[k])
2907 struct attr_value *av;
2908 for (av = all[i]->first_value; av; av = av->next)
2909 if (av->num_insns != 0)
2910 if (tests_attr_p (av->value, all[k]))
2911 break;
2913 if (av)
2914 /* Something in I depends on K. */
2915 break;
2917 if (k == num)
2919 /* Nothing in I depended on anything intersting, so
2920 it's done. */
2921 handled[i] = 1;
2922 sorted[j++] = all[i];
2927 if (DEBUG)
2928 for (j = 0; j < num; j++)
2930 struct attr_desc *attr2;
2931 struct attr_value *av;
2933 attr = sorted[j];
2934 fprintf (stderr, "%s depends on: ", attr->name);
2935 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
2936 for (attr2 = attrs[i]; attr2; attr2 = attr2->next)
2937 if (!attr2->is_const)
2938 for (av = attr->first_value; av; av = av->next)
2939 if (av->num_insns != 0)
2940 if (tests_attr_p (av->value, attr2))
2942 fprintf (stderr, "%s, ", attr2->name);
2943 break;
2945 fprintf (stderr, "\n");
2948 free (all);
2949 *ret = sorted;
2950 return num;
2953 /* Optimize the attribute lists by seeing if we can determine conditional
2954 values from the known values of other attributes. This will save subroutine
2955 calls during the compilation. NUM_INSN_CODES is the number of unique
2956 instruction codes. */
2958 static void
2959 optimize_attrs (int num_insn_codes)
2961 struct attr_desc *attr;
2962 struct attr_value *av;
2963 struct insn_ent *ie;
2964 rtx newexp;
2965 int i;
2966 struct attr_value_list *ivbuf;
2967 struct attr_value_list *iv;
2968 struct attr_desc **topsort;
2969 int topnum;
2971 /* For each insn code, make a list of all the insn_ent's for it,
2972 for all values for all attributes. */
2974 if (num_insn_ents == 0)
2975 return;
2977 /* Make 2 extra elements, for "code" values -2 and -1. */
2978 insn_code_values = XCNEWVEC (struct attr_value_list *, num_insn_codes + 2);
2980 /* Offset the table address so we can index by -2 or -1. */
2981 insn_code_values += 2;
2983 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2985 /* Create the chain of insn*attr values such that we see dependend
2986 attributes after their dependencies. As we use a stack via the
2987 next pointers start from the end of the topological order. */
2988 topnum = get_attr_order (&topsort);
2989 for (i = topnum - 1; i >= 0; i--)
2990 for (av = topsort[i]->first_value; av; av = av->next)
2991 for (ie = av->first_insn; ie; ie = ie->next)
2993 iv->attr = topsort[i];
2994 iv->av = av;
2995 iv->ie = ie;
2996 iv->next = insn_code_values[ie->def->insn_code];
2997 insn_code_values[ie->def->insn_code] = iv;
2998 iv++;
3000 free (topsort);
3002 /* Sanity check on num_insn_ents. */
3003 gcc_assert (iv == ivbuf + num_insn_ents);
3005 /* Process one insn code at a time. */
3006 for (i = -2; i < num_insn_codes; i++)
3008 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3009 We use it to mean "already simplified for this insn". */
3010 for (iv = insn_code_values[i]; iv; iv = iv->next)
3011 clear_struct_flag (iv->av->value);
3013 for (iv = insn_code_values[i]; iv; iv = iv->next)
3015 struct obstack *old = rtl_obstack;
3017 attr = iv->attr;
3018 av = iv->av;
3019 ie = iv->ie;
3020 if (GET_CODE (av->value) != COND)
3021 continue;
3023 rtl_obstack = temp_obstack;
3024 newexp = av->value;
3025 while (GET_CODE (newexp) == COND)
3027 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
3028 ie->def->insn_index);
3029 if (newexp2 == newexp)
3030 break;
3031 newexp = newexp2;
3034 rtl_obstack = old;
3035 /* If we created a new value for this instruction, and it's
3036 cheaper than the old value, and overall cheap, use that
3037 one as specific value for the current instruction.
3038 The last test is to avoid exploding the get_attr_ function
3039 sizes for no much gain. */
3040 if (newexp != av->value
3041 && attr_rtx_cost (newexp) < attr_rtx_cost (av->value)
3042 && attr_rtx_cost (newexp) < 26
3045 newexp = attr_copy_rtx (newexp);
3046 remove_insn_ent (av, ie);
3047 av = get_attr_value (ie->def->loc, newexp, attr,
3048 ie->def->insn_code);
3049 iv->av = av;
3050 insert_insn_ent (av, ie);
3055 free (ivbuf);
3056 free (insn_code_values - 2);
3057 insn_code_values = NULL;
3060 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3062 static void
3063 clear_struct_flag (rtx x)
3065 int i;
3066 int j;
3067 enum rtx_code code;
3068 const char *fmt;
3070 ATTR_CURR_SIMPLIFIED_P (x) = 0;
3071 if (ATTR_IND_SIMPLIFIED_P (x))
3072 return;
3074 code = GET_CODE (x);
3076 switch (code)
3078 case REG:
3079 CASE_CONST_ANY:
3080 case MATCH_TEST:
3081 case SYMBOL_REF:
3082 case CODE_LABEL:
3083 case PC:
3084 case CC0:
3085 case EQ_ATTR:
3086 case ATTR_FLAG:
3087 return;
3089 default:
3090 break;
3093 /* Compare the elements. If any pair of corresponding elements
3094 fail to match, return 0 for the whole things. */
3096 fmt = GET_RTX_FORMAT (code);
3097 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3099 switch (fmt[i])
3101 case 'V':
3102 case 'E':
3103 for (j = 0; j < XVECLEN (x, i); j++)
3104 clear_struct_flag (XVECEXP (x, i, j));
3105 break;
3107 case 'e':
3108 clear_struct_flag (XEXP (x, i));
3109 break;
3114 /* Add attribute value NAME to the beginning of ATTR's list. */
3116 static void
3117 add_attr_value (struct attr_desc *attr, const char *name)
3119 struct attr_value *av;
3121 av = oballoc (struct attr_value);
3122 av->value = attr_rtx (CONST_STRING, name);
3123 av->next = attr->first_value;
3124 attr->first_value = av;
3125 av->first_insn = NULL;
3126 av->num_insns = 0;
3127 av->has_asm_insn = 0;
3130 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3132 static void
3133 gen_attr (md_rtx_info *info)
3135 struct enum_type *et;
3136 struct enum_value *ev;
3137 struct attr_desc *attr;
3138 const char *name_ptr;
3139 char *p;
3140 rtx def = info->def;
3142 /* Make a new attribute structure. Check for duplicate by looking at
3143 attr->default_val, since it is initialized by this routine. */
3144 attr = find_attr (&XSTR (def, 0), 1);
3145 if (attr->default_val)
3147 error_at (info->loc, "duplicate definition for attribute %s",
3148 attr->name);
3149 message_at (attr->loc, "previous definition");
3150 return;
3152 attr->loc = info->loc;
3154 if (GET_CODE (def) == DEFINE_ENUM_ATTR)
3156 attr->enum_name = XSTR (def, 1);
3157 et = lookup_enum_type (XSTR (def, 1));
3158 if (!et || !et->md_p)
3159 error_at (info->loc, "No define_enum called `%s' defined",
3160 attr->name);
3161 if (et)
3162 for (ev = et->values; ev; ev = ev->next)
3163 add_attr_value (attr, ev->name);
3165 else if (*XSTR (def, 1) == '\0')
3166 attr->is_numeric = 1;
3167 else
3169 name_ptr = XSTR (def, 1);
3170 while ((p = next_comma_elt (&name_ptr)) != NULL)
3171 add_attr_value (attr, p);
3174 if (GET_CODE (XEXP (def, 2)) == CONST)
3176 attr->is_const = 1;
3177 if (attr->is_numeric)
3178 error_at (info->loc,
3179 "constant attributes may not take numeric values");
3181 /* Get rid of the CONST node. It is allowed only at top-level. */
3182 XEXP (def, 2) = XEXP (XEXP (def, 2), 0);
3185 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3186 error_at (info->loc, "`length' attribute must take numeric values");
3188 /* Set up the default value. */
3189 XEXP (def, 2) = check_attr_value (XEXP (def, 2), attr);
3190 attr->default_val = get_attr_value (info->loc, XEXP (def, 2), attr, -2);
3193 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3194 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3195 number of alternatives as this should be checked elsewhere. */
3197 static int
3198 count_alternatives (rtx exp)
3200 int i, j, n;
3201 const char *fmt;
3203 if (GET_CODE (exp) == MATCH_OPERAND)
3204 return n_comma_elts (XSTR (exp, 2));
3206 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3207 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3208 switch (*fmt++)
3210 case 'e':
3211 case 'u':
3212 n = count_alternatives (XEXP (exp, i));
3213 if (n)
3214 return n;
3215 break;
3217 case 'E':
3218 case 'V':
3219 if (XVEC (exp, i) != NULL)
3220 for (j = 0; j < XVECLEN (exp, i); j++)
3222 n = count_alternatives (XVECEXP (exp, i, j));
3223 if (n)
3224 return n;
3228 return 0;
3231 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3232 `alternative' attribute. */
3234 static int
3235 compares_alternatives_p (rtx exp)
3237 int i, j;
3238 const char *fmt;
3240 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3241 return 1;
3243 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3244 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3245 switch (*fmt++)
3247 case 'e':
3248 case 'u':
3249 if (compares_alternatives_p (XEXP (exp, i)))
3250 return 1;
3251 break;
3253 case 'E':
3254 for (j = 0; j < XVECLEN (exp, i); j++)
3255 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3256 return 1;
3257 break;
3260 return 0;
3263 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3265 static void
3266 gen_insn (md_rtx_info *info)
3268 struct insn_def *id;
3269 rtx def = info->def;
3271 id = oballoc (struct insn_def);
3272 id->next = defs;
3273 defs = id;
3274 id->def = def;
3275 id->loc = info->loc;
3277 switch (GET_CODE (def))
3279 case DEFINE_INSN:
3280 id->insn_code = info->index;
3281 id->insn_index = insn_index_number;
3282 id->num_alternatives = count_alternatives (def);
3283 if (id->num_alternatives == 0)
3284 id->num_alternatives = 1;
3285 id->vec_idx = 4;
3286 break;
3288 case DEFINE_PEEPHOLE:
3289 id->insn_code = info->index;
3290 id->insn_index = insn_index_number;
3291 id->num_alternatives = count_alternatives (def);
3292 if (id->num_alternatives == 0)
3293 id->num_alternatives = 1;
3294 id->vec_idx = 3;
3295 break;
3297 case DEFINE_ASM_ATTRIBUTES:
3298 id->insn_code = -1;
3299 id->insn_index = -1;
3300 id->num_alternatives = 1;
3301 id->vec_idx = 0;
3302 got_define_asm_attributes = 1;
3303 break;
3305 default:
3306 gcc_unreachable ();
3310 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3311 true or annul false is specified, and make a `struct delay_desc'. */
3313 static void
3314 gen_delay (md_rtx_info *info)
3316 struct delay_desc *delay;
3317 int i;
3319 rtx def = info->def;
3320 if (XVECLEN (def, 1) % 3 != 0)
3322 error_at (info->loc, "number of elements in DEFINE_DELAY must"
3323 " be multiple of three");
3324 return;
3327 for (i = 0; i < XVECLEN (def, 1); i += 3)
3329 if (XVECEXP (def, 1, i + 1))
3330 have_annul_true = 1;
3331 if (XVECEXP (def, 1, i + 2))
3332 have_annul_false = 1;
3335 delay = oballoc (struct delay_desc);
3336 delay->def = def;
3337 delay->num = ++num_delays;
3338 delay->next = delays;
3339 delay->loc = info->loc;
3340 delays = delay;
3343 /* Names of attributes that could be possibly cached. */
3344 static const char *cached_attrs[32];
3345 /* Number of such attributes. */
3346 static int cached_attr_count;
3347 /* Bitmasks of possibly cached attributes. */
3348 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3349 static unsigned int attrs_to_cache;
3350 static unsigned int attrs_cached_inside, attrs_cached_after;
3352 /* Finds non-const attributes that could be possibly cached.
3353 When create is TRUE, fills in cached_attrs array.
3354 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3355 bitmasks. */
3357 static void
3358 find_attrs_to_cache (rtx exp, bool create)
3360 int i;
3361 const char *name;
3362 struct attr_desc *attr;
3364 if (exp == NULL)
3365 return;
3367 switch (GET_CODE (exp))
3369 case NOT:
3370 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3371 find_attrs_to_cache (XEXP (exp, 0), create);
3372 return;
3374 case EQ_ATTR:
3375 name = XSTR (exp, 0);
3376 if (name == alternative_name)
3377 return;
3378 for (i = 0; i < cached_attr_count; i++)
3379 if (name == cached_attrs[i])
3381 if ((attrs_seen_once & (1U << i)) != 0)
3382 attrs_seen_more_than_once |= (1U << i);
3383 else
3384 attrs_seen_once |= (1U << i);
3385 return;
3387 if (!create)
3388 return;
3389 attr = find_attr (&name, 0);
3390 gcc_assert (attr);
3391 if (attr->is_const)
3392 return;
3393 if (cached_attr_count == 32)
3394 return;
3395 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3396 attrs_seen_once |= (1U << cached_attr_count);
3397 cached_attr_count++;
3398 return;
3400 case AND:
3401 case IOR:
3402 find_attrs_to_cache (XEXP (exp, 0), create);
3403 find_attrs_to_cache (XEXP (exp, 1), create);
3404 return;
3406 case COND:
3407 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3408 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3409 return;
3411 default:
3412 return;
3416 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3417 We use AND and IOR both for logical and bit-wise operations, so
3418 interpret them as logical unless they are inside a comparison expression. */
3420 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3421 #define FLG_BITWISE 1
3422 /* Set if cached attribute will be known initialized in else block after
3423 this condition. This is true for LHS of toplevel && and || and
3424 even for RHS of ||, but not for RHS of &&. */
3425 #define FLG_AFTER 2
3426 /* Set if cached attribute will be known initialized in then block after
3427 this condition. This is true for LHS of toplevel && and || and
3428 even for RHS of &&, but not for RHS of ||. */
3429 #define FLG_INSIDE 4
3430 /* Cleared when an operand of &&. */
3431 #define FLG_OUTSIDE_AND 8
3433 static unsigned int
3434 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags)
3436 int comparison_operator = 0;
3437 RTX_CODE code;
3438 struct attr_desc *attr;
3440 /* In order not to worry about operator precedence, surround our part of
3441 the expression with parentheses. */
3443 fprintf (outf, "(");
3444 code = GET_CODE (exp);
3445 switch (code)
3447 /* Binary operators. */
3448 case GEU: case GTU:
3449 case LEU: case LTU:
3450 fprintf (outf, "(unsigned) ");
3451 /* Fall through. */
3453 case EQ: case NE:
3454 case GE: case GT:
3455 case LE: case LT:
3456 comparison_operator = FLG_BITWISE;
3458 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3459 case AND: case IOR: case XOR:
3460 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3461 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3463 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3464 write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3465 flags | comparison_operator);
3467 else
3469 if (code == AND)
3470 flags &= ~FLG_OUTSIDE_AND;
3471 if (GET_CODE (XEXP (exp, 0)) == code
3472 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3473 || (GET_CODE (XEXP (exp, 0)) == NOT
3474 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3475 attrs_cached
3476 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3477 else
3478 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3480 switch (code)
3482 case EQ:
3483 fprintf (outf, " == ");
3484 break;
3485 case NE:
3486 fprintf (outf, " != ");
3487 break;
3488 case GE:
3489 fprintf (outf, " >= ");
3490 break;
3491 case GT:
3492 fprintf (outf, " > ");
3493 break;
3494 case GEU:
3495 fprintf (outf, " >= (unsigned) ");
3496 break;
3497 case GTU:
3498 fprintf (outf, " > (unsigned) ");
3499 break;
3500 case LE:
3501 fprintf (outf, " <= ");
3502 break;
3503 case LT:
3504 fprintf (outf, " < ");
3505 break;
3506 case LEU:
3507 fprintf (outf, " <= (unsigned) ");
3508 break;
3509 case LTU:
3510 fprintf (outf, " < (unsigned) ");
3511 break;
3512 case PLUS:
3513 fprintf (outf, " + ");
3514 break;
3515 case MINUS:
3516 fprintf (outf, " - ");
3517 break;
3518 case MULT:
3519 fprintf (outf, " * ");
3520 break;
3521 case DIV:
3522 fprintf (outf, " / ");
3523 break;
3524 case MOD:
3525 fprintf (outf, " %% ");
3526 break;
3527 case AND:
3528 if (flags & FLG_BITWISE)
3529 fprintf (outf, " & ");
3530 else
3531 fprintf (outf, " && ");
3532 break;
3533 case IOR:
3534 if (flags & FLG_BITWISE)
3535 fprintf (outf, " | ");
3536 else
3537 fprintf (outf, " || ");
3538 break;
3539 case XOR:
3540 fprintf (outf, " ^ ");
3541 break;
3542 case ASHIFT:
3543 fprintf (outf, " << ");
3544 break;
3545 case LSHIFTRT:
3546 case ASHIFTRT:
3547 fprintf (outf, " >> ");
3548 break;
3549 default:
3550 gcc_unreachable ();
3553 if (code == AND)
3555 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3556 cached_x is only known to be initialized in then block. */
3557 flags &= ~FLG_AFTER;
3559 else if (code == IOR)
3561 if (flags & FLG_OUTSIDE_AND)
3562 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3563 cached_x is only known to be initialized in else block
3564 and else if conditions. */
3565 flags &= ~FLG_INSIDE;
3566 else
3567 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3568 && something_else)
3569 cached_x is not know to be initialized anywhere. */
3570 flags &= ~(FLG_AFTER | FLG_INSIDE);
3572 if ((code == AND || code == IOR)
3573 && (GET_CODE (XEXP (exp, 1)) == code
3574 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3575 || (GET_CODE (XEXP (exp, 1)) == NOT
3576 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3577 attrs_cached
3578 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags);
3579 else
3580 write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3581 flags | comparison_operator);
3582 break;
3584 case NOT:
3585 /* Special-case (not (eq_attrq "alternative" "x")) */
3586 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3588 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3590 fprintf (outf, "which_alternative != %s",
3591 XSTR (XEXP (exp, 0), 1));
3592 break;
3595 fprintf (outf, "! ");
3596 attrs_cached =
3597 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3598 break;
3601 /* Otherwise, fall through to normal unary operator. */
3603 /* Unary operators. */
3604 case ABS: case NEG:
3605 switch (code)
3607 case NOT:
3608 if (flags & FLG_BITWISE)
3609 fprintf (outf, "~ ");
3610 else
3611 fprintf (outf, "! ");
3612 break;
3613 case ABS:
3614 fprintf (outf, "abs ");
3615 break;
3616 case NEG:
3617 fprintf (outf, "-");
3618 break;
3619 default:
3620 gcc_unreachable ();
3623 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3624 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3625 break;
3627 case EQ_ATTR_ALT:
3629 int set = XINT (exp, 0), bit = 0;
3631 if (flags & FLG_BITWISE)
3632 fatal ("EQ_ATTR_ALT not valid inside comparison");
3634 if (!set)
3635 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3637 if (!(set & (set - 1)))
3639 if (!(set & 0xffff))
3641 bit += 16;
3642 set >>= 16;
3644 if (!(set & 0xff))
3646 bit += 8;
3647 set >>= 8;
3649 if (!(set & 0xf))
3651 bit += 4;
3652 set >>= 4;
3654 if (!(set & 0x3))
3656 bit += 2;
3657 set >>= 2;
3659 if (!(set & 1))
3660 bit++;
3662 fprintf (outf, "which_alternative %s= %d",
3663 XINT (exp, 1) ? "!" : "=", bit);
3665 else
3667 fprintf (outf, "%s((1 << which_alternative) & %#x)",
3668 XINT (exp, 1) ? "!" : "", set);
3671 break;
3673 /* Comparison test of an attribute with a value. Most of these will
3674 have been removed by optimization. Handle "alternative"
3675 specially and give error if EQ_ATTR present inside a comparison. */
3676 case EQ_ATTR:
3677 if (flags & FLG_BITWISE)
3678 fatal ("EQ_ATTR not valid inside comparison");
3680 if (XSTR (exp, 0) == alternative_name)
3682 fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3683 break;
3686 attr = find_attr (&XSTR (exp, 0), 0);
3687 gcc_assert (attr);
3689 /* Now is the time to expand the value of a constant attribute. */
3690 if (attr->is_const)
3692 write_test_expr (outf,
3693 evaluate_eq_attr (exp, attr,
3694 attr->default_val->value,
3695 -2, -2),
3696 attrs_cached, 0);
3698 else
3700 int i;
3701 for (i = 0; i < cached_attr_count; i++)
3702 if (attr->name == cached_attrs[i])
3703 break;
3704 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3705 fprintf (outf, "cached_%s", attr->name);
3706 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3708 fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3709 attr->name, attr->name);
3710 if (flags & FLG_AFTER)
3711 attrs_cached_after |= (1U << i);
3712 if (flags & FLG_INSIDE)
3713 attrs_cached_inside |= (1U << i);
3714 attrs_cached |= (1U << i);
3716 else
3717 fprintf (outf, "get_attr_%s (insn)", attr->name);
3718 fprintf (outf, " == ");
3719 write_attr_valueq (outf, attr, XSTR (exp, 1));
3721 break;
3723 /* Comparison test of flags for define_delays. */
3724 case ATTR_FLAG:
3725 if (flags & FLG_BITWISE)
3726 fatal ("ATTR_FLAG not valid inside comparison");
3727 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3728 break;
3730 /* See if an operand matches a predicate. */
3731 case MATCH_OPERAND:
3732 /* If only a mode is given, just ensure the mode matches the operand.
3733 If neither a mode nor predicate is given, error. */
3734 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3736 if (GET_MODE (exp) == VOIDmode)
3737 fatal ("null MATCH_OPERAND specified as test");
3738 else
3739 fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3740 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3742 else
3743 fprintf (outf, "%s (operands[%d], %smode)",
3744 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3745 break;
3747 /* Constant integer. */
3748 case CONST_INT:
3749 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3750 break;
3752 case MATCH_TEST:
3753 fprint_c_condition (outf, XSTR (exp, 0));
3754 if (flags & FLG_BITWISE)
3755 fprintf (outf, " != 0");
3756 break;
3758 /* A random C expression. */
3759 case SYMBOL_REF:
3760 fprint_c_condition (outf, XSTR (exp, 0));
3761 break;
3763 /* The address of the branch target. */
3764 case MATCH_DUP:
3765 fprintf (outf,
3766 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3767 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3768 break;
3770 case PC:
3771 /* The address of the current insn. We implement this actually as the
3772 address of the current insn for backward branches, but the last
3773 address of the next insn for forward branches, and both with
3774 adjustments that account for the worst-case possible stretching of
3775 intervening alignments between this insn and its destination. */
3776 fprintf (outf, "insn_current_reference_address (insn)");
3777 break;
3779 case CONST_STRING:
3780 fprintf (outf, "%s", XSTR (exp, 0));
3781 break;
3783 case IF_THEN_ELSE:
3784 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3785 fprintf (outf, " ? ");
3786 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3787 fprintf (outf, " : ");
3788 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3789 break;
3791 default:
3792 fatal ("bad RTX code `%s' in attribute calculation\n",
3793 GET_RTX_NAME (code));
3796 fprintf (outf, ")");
3797 return attrs_cached;
3800 /* Given an attribute value, return the maximum CONST_STRING argument
3801 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3803 static int
3804 max_attr_value (rtx exp, int *unknownp)
3806 int current_max;
3807 int i, n;
3809 switch (GET_CODE (exp))
3811 case CONST_STRING:
3812 current_max = atoi (XSTR (exp, 0));
3813 break;
3815 case COND:
3816 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3817 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3819 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3820 if (n > current_max)
3821 current_max = n;
3823 break;
3825 case IF_THEN_ELSE:
3826 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3827 n = max_attr_value (XEXP (exp, 2), unknownp);
3828 if (n > current_max)
3829 current_max = n;
3830 break;
3832 default:
3833 *unknownp = 1;
3834 current_max = INT_MAX;
3835 break;
3838 return current_max;
3841 /* Given an attribute value, return the minimum CONST_STRING argument
3842 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3844 static int
3845 min_attr_value (rtx exp, int *unknownp)
3847 int current_min;
3848 int i, n;
3850 switch (GET_CODE (exp))
3852 case CONST_STRING:
3853 current_min = atoi (XSTR (exp, 0));
3854 break;
3856 case COND:
3857 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3858 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3860 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3861 if (n < current_min)
3862 current_min = n;
3864 break;
3866 case IF_THEN_ELSE:
3867 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3868 n = min_attr_value (XEXP (exp, 2), unknownp);
3869 if (n < current_min)
3870 current_min = n;
3871 break;
3873 default:
3874 *unknownp = 1;
3875 current_min = INT_MAX;
3876 break;
3879 return current_min;
3882 /* Given an attribute value, return the result of ORing together all
3883 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3884 if the numeric value is not known. */
3886 static int
3887 or_attr_value (rtx exp, int *unknownp)
3889 int current_or;
3890 int i;
3892 switch (GET_CODE (exp))
3894 case CONST_STRING:
3895 current_or = atoi (XSTR (exp, 0));
3896 break;
3898 case COND:
3899 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3900 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3901 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3902 break;
3904 case IF_THEN_ELSE:
3905 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3906 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3907 break;
3909 default:
3910 *unknownp = 1;
3911 current_or = -1;
3912 break;
3915 return current_or;
3918 /* Scan an attribute value, possibly a conditional, and record what actions
3919 will be required to do any conditional tests in it.
3921 Specifically, set
3922 `must_extract' if we need to extract the insn operands
3923 `must_constrain' if we must compute `which_alternative'
3924 `address_used' if an address expression was used
3925 `length_used' if an (eq_attr "length" ...) was used
3928 static void
3929 walk_attr_value (rtx exp)
3931 int i, j;
3932 const char *fmt;
3933 RTX_CODE code;
3935 if (exp == NULL)
3936 return;
3938 code = GET_CODE (exp);
3939 switch (code)
3941 case SYMBOL_REF:
3942 if (! ATTR_IND_SIMPLIFIED_P (exp))
3943 /* Since this is an arbitrary expression, it can look at anything.
3944 However, constant expressions do not depend on any particular
3945 insn. */
3946 must_extract = must_constrain = 1;
3947 return;
3949 case MATCH_OPERAND:
3950 must_extract = 1;
3951 return;
3953 case MATCH_TEST:
3954 case EQ_ATTR_ALT:
3955 must_extract = must_constrain = 1;
3956 break;
3958 case EQ_ATTR:
3959 if (XSTR (exp, 0) == alternative_name)
3960 must_extract = must_constrain = 1;
3961 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3962 length_used = 1;
3963 return;
3965 case MATCH_DUP:
3966 must_extract = 1;
3967 address_used = 1;
3968 return;
3970 case PC:
3971 address_used = 1;
3972 return;
3974 case ATTR_FLAG:
3975 return;
3977 default:
3978 break;
3981 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3982 switch (*fmt++)
3984 case 'e':
3985 case 'u':
3986 walk_attr_value (XEXP (exp, i));
3987 break;
3989 case 'E':
3990 if (XVEC (exp, i) != NULL)
3991 for (j = 0; j < XVECLEN (exp, i); j++)
3992 walk_attr_value (XVECEXP (exp, i, j));
3993 break;
3997 /* Write out a function to obtain the attribute for a given INSN. */
3999 static void
4000 write_attr_get (FILE *outf, struct attr_desc *attr)
4002 struct attr_value *av, *common_av;
4003 int i, j;
4005 /* Find the most used attribute value. Handle that as the `default' of the
4006 switch we will generate. */
4007 common_av = find_most_used (attr);
4009 /* Write out start of function, then all values with explicit `case' lines,
4010 then a `default', then the value with the most uses. */
4011 if (attr->enum_name)
4012 fprintf (outf, "enum %s\n", attr->enum_name);
4013 else if (!attr->is_numeric)
4014 fprintf (outf, "enum attr_%s\n", attr->name);
4015 else
4016 fprintf (outf, "int\n");
4018 /* If the attribute name starts with a star, the remainder is the name of
4019 the subroutine to use, instead of `get_attr_...'. */
4020 if (attr->name[0] == '*')
4021 fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4022 else if (attr->is_const == 0)
4023 fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
4024 else
4026 fprintf (outf, "get_attr_%s (void)\n", attr->name);
4027 fprintf (outf, "{\n");
4029 for (av = attr->first_value; av; av = av->next)
4030 if (av->num_insns == 1)
4031 write_attr_set (outf, attr, 2, av->value, "return", ";",
4032 true_rtx, av->first_insn->def->insn_code,
4033 av->first_insn->def->insn_index, 0);
4034 else if (av->num_insns != 0)
4035 write_attr_set (outf, attr, 2, av->value, "return", ";",
4036 true_rtx, -2, 0, 0);
4038 fprintf (outf, "}\n\n");
4039 return;
4042 fprintf (outf, "{\n");
4044 /* Find attributes that are worth caching in the conditions. */
4045 cached_attr_count = 0;
4046 attrs_seen_more_than_once = 0;
4047 for (av = attr->first_value; av; av = av->next)
4049 attrs_seen_once = 0;
4050 find_attrs_to_cache (av->value, true);
4052 /* Remove those that aren't worth caching from the array. */
4053 for (i = 0, j = 0; i < cached_attr_count; i++)
4054 if ((attrs_seen_more_than_once & (1U << i)) != 0)
4056 const char *name = cached_attrs[i];
4057 struct attr_desc *cached_attr;
4058 if (i != j)
4059 cached_attrs[j] = name;
4060 cached_attr = find_attr (&name, 0);
4061 gcc_assert (cached_attr && cached_attr->is_const == 0);
4062 if (cached_attr->enum_name)
4063 fprintf (outf, " enum %s", cached_attr->enum_name);
4064 else if (!cached_attr->is_numeric)
4065 fprintf (outf, " enum attr_%s", cached_attr->name);
4066 else
4067 fprintf (outf, " int");
4068 fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
4069 j++;
4071 cached_attr_count = j;
4072 if (cached_attr_count)
4073 fprintf (outf, "\n");
4075 fprintf (outf, " switch (recog_memoized (insn))\n");
4076 fprintf (outf, " {\n");
4078 for (av = attr->first_value; av; av = av->next)
4079 if (av != common_av)
4080 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4082 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4083 fprintf (outf, " }\n}\n\n");
4084 cached_attr_count = 0;
4087 /* Given an AND tree of known true terms (because we are inside an `if' with
4088 that as the condition or are in an `else' clause) and an expression,
4089 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4090 the bulk of the work. */
4092 static rtx
4093 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4095 rtx term;
4097 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4099 if (GET_CODE (known_true) == AND)
4101 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4102 insn_code, insn_index);
4103 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4104 insn_code, insn_index);
4106 else
4108 term = known_true;
4109 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4112 return exp;
4115 /* Write out a series of tests and assignment statements to perform tests and
4116 sets of an attribute value. We are passed an indentation amount and prefix
4117 and suffix strings to write around each attribute value (e.g., "return"
4118 and ";"). */
4120 static void
4121 write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
4122 const char *prefix, const char *suffix, rtx known_true,
4123 int insn_code, int insn_index, unsigned int attrs_cached)
4125 if (GET_CODE (value) == COND)
4127 /* Assume the default value will be the default of the COND unless we
4128 find an always true expression. */
4129 rtx default_val = XEXP (value, 1);
4130 rtx our_known_true = known_true;
4131 rtx newexp;
4132 int first_if = 1;
4133 int i;
4135 if (cached_attr_count)
4137 attrs_seen_once = 0;
4138 attrs_seen_more_than_once = 0;
4139 for (i = 0; i < XVECLEN (value, 0); i += 2)
4140 find_attrs_to_cache (XVECEXP (value, 0, i), false);
4141 attrs_to_cache |= attrs_seen_more_than_once;
4144 for (i = 0; i < XVECLEN (value, 0); i += 2)
4146 rtx testexp;
4147 rtx inner_true;
4149 /* Reset our_known_true after some time to not accumulate
4150 too much cruft (slowing down genattrtab). */
4151 if ((i & 31) == 0)
4152 our_known_true = known_true;
4153 testexp = eliminate_known_true (our_known_true,
4154 XVECEXP (value, 0, i),
4155 insn_code, insn_index);
4156 newexp = attr_rtx (NOT, testexp);
4157 newexp = insert_right_side (AND, our_known_true, newexp,
4158 insn_code, insn_index);
4160 /* If the test expression is always true or if the next `known_true'
4161 expression is always false, this is the last case, so break
4162 out and let this value be the `else' case. */
4163 if (testexp == true_rtx || newexp == false_rtx)
4165 default_val = XVECEXP (value, 0, i + 1);
4166 break;
4169 /* Compute the expression to pass to our recursive call as being
4170 known true. */
4171 inner_true = insert_right_side (AND, our_known_true,
4172 testexp, insn_code, insn_index);
4174 /* If this is always false, skip it. */
4175 if (inner_true == false_rtx)
4176 continue;
4178 attrs_cached_inside = attrs_cached;
4179 attrs_cached_after = attrs_cached;
4180 write_indent (outf, indent);
4181 fprintf (outf, "%sif ", first_if ? "" : "else ");
4182 first_if = 0;
4183 write_test_expr (outf, testexp, attrs_cached,
4184 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4185 attrs_cached = attrs_cached_after;
4186 fprintf (outf, "\n");
4187 write_indent (outf, indent + 2);
4188 fprintf (outf, "{\n");
4190 write_attr_set (outf, attr, indent + 4,
4191 XVECEXP (value, 0, i + 1), prefix, suffix,
4192 inner_true, insn_code, insn_index,
4193 attrs_cached_inside);
4194 write_indent (outf, indent + 2);
4195 fprintf (outf, "}\n");
4196 our_known_true = newexp;
4199 if (! first_if)
4201 write_indent (outf, indent);
4202 fprintf (outf, "else\n");
4203 write_indent (outf, indent + 2);
4204 fprintf (outf, "{\n");
4207 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4208 prefix, suffix, our_known_true, insn_code, insn_index,
4209 attrs_cached);
4211 if (! first_if)
4213 write_indent (outf, indent + 2);
4214 fprintf (outf, "}\n");
4217 else
4219 write_indent (outf, indent);
4220 fprintf (outf, "%s ", prefix);
4221 write_attr_value (outf, attr, value);
4222 fprintf (outf, "%s\n", suffix);
4226 /* Write a series of case statements for every instruction in list IE.
4227 INDENT is the amount of indentation to write before each case. */
4229 static void
4230 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4232 for (; ie != 0; ie = ie->next)
4233 if (ie->def->insn_code != -1)
4235 write_indent (outf, indent);
4236 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4237 fprintf (outf, "case %d: /* define_peephole, %s:%d */\n",
4238 ie->def->insn_code, ie->def->loc.filename,
4239 ie->def->loc.lineno);
4240 else
4241 fprintf (outf, "case %d: /* %s */\n",
4242 ie->def->insn_code, XSTR (ie->def->def, 0));
4246 /* Write out the computation for one attribute value. */
4248 static void
4249 write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
4250 int write_case_lines, const char *prefix, const char *suffix,
4251 int indent, rtx known_true)
4253 if (av->num_insns == 0)
4254 return;
4256 if (av->has_asm_insn)
4258 write_indent (outf, indent);
4259 fprintf (outf, "case -1:\n");
4260 write_indent (outf, indent + 2);
4261 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4262 write_indent (outf, indent + 2);
4263 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
4264 write_indent (outf, indent + 2);
4265 fprintf (outf, " fatal_insn_not_found (insn);\n");
4268 if (write_case_lines)
4269 write_insn_cases (outf, av->first_insn, indent);
4270 else
4272 write_indent (outf, indent);
4273 fprintf (outf, "default:\n");
4276 /* See what we have to do to output this value. */
4277 must_extract = must_constrain = address_used = 0;
4278 walk_attr_value (av->value);
4280 if (must_constrain)
4282 write_indent (outf, indent + 2);
4283 fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4285 else if (must_extract)
4287 write_indent (outf, indent + 2);
4288 fprintf (outf, "extract_insn_cached (insn);\n");
4291 attrs_to_cache = 0;
4292 if (av->num_insns == 1)
4293 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4294 known_true, av->first_insn->def->insn_code,
4295 av->first_insn->def->insn_index, 0);
4296 else
4297 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4298 known_true, -2, 0, 0);
4300 if (strncmp (prefix, "return", 6))
4302 write_indent (outf, indent + 2);
4303 fprintf (outf, "break;\n");
4305 fprintf (outf, "\n");
4308 /* Utilities to write in various forms. */
4310 static void
4311 write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
4313 if (attr->is_numeric)
4315 int num = atoi (s);
4317 fprintf (outf, "%d", num);
4319 if (num > 9 || num < 0)
4320 fprintf (outf, " /* %#x */", num);
4322 else
4324 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4325 fprintf (outf, "_");
4326 write_upcase (outf, s);
4330 static void
4331 write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
4333 int op;
4335 switch (GET_CODE (value))
4337 case CONST_STRING:
4338 write_attr_valueq (outf, attr, XSTR (value, 0));
4339 break;
4341 case CONST_INT:
4342 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4343 break;
4345 case SYMBOL_REF:
4346 fprint_c_condition (outf, XSTR (value, 0));
4347 break;
4349 case ATTR:
4351 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4352 if (attr->enum_name)
4353 fprintf (outf, "(enum %s)", attr->enum_name);
4354 else if (!attr->is_numeric)
4355 fprintf (outf, "(enum attr_%s)", attr->name);
4356 else if (!attr2->is_numeric)
4357 fprintf (outf, "(int)");
4359 fprintf (outf, "get_attr_%s (%s)", attr2->name,
4360 (attr2->is_const ? "" : "insn"));
4362 break;
4364 case PLUS:
4365 op = '+';
4366 goto do_operator;
4367 case MINUS:
4368 op = '-';
4369 goto do_operator;
4370 case MULT:
4371 op = '*';
4372 goto do_operator;
4373 case DIV:
4374 op = '/';
4375 goto do_operator;
4376 case MOD:
4377 op = '%';
4378 goto do_operator;
4380 do_operator:
4381 write_attr_value (outf, attr, XEXP (value, 0));
4382 fputc (' ', outf);
4383 fputc (op, outf);
4384 fputc (' ', outf);
4385 write_attr_value (outf, attr, XEXP (value, 1));
4386 break;
4388 default:
4389 gcc_unreachable ();
4393 static void
4394 write_upcase (FILE *outf, const char *str)
4396 while (*str)
4398 /* The argument of TOUPPER should not have side effects. */
4399 fputc (TOUPPER (*str), outf);
4400 str++;
4404 static void
4405 write_indent (FILE *outf, int indent)
4407 for (; indent > 8; indent -= 8)
4408 fprintf (outf, "\t");
4410 for (; indent; indent--)
4411 fprintf (outf, " ");
4414 /* Write a subroutine that is given an insn that requires a delay slot, a
4415 delay slot ordinal, and a candidate insn. It returns nonzero if the
4416 candidate can be placed in the specified delay slot of the insn.
4418 We can write as many as three subroutines. `eligible_for_delay'
4419 handles normal delay slots, `eligible_for_annul_true' indicates that
4420 the specified insn can be annulled if the branch is true, and likewise
4421 for `eligible_for_annul_false'.
4423 KIND is a string distinguishing these three cases ("delay", "annul_true",
4424 or "annul_false"). */
4426 static void
4427 write_eligible_delay (FILE *outf, const char *kind)
4429 struct delay_desc *delay;
4430 int max_slots;
4431 char str[50];
4432 const char *pstr;
4433 struct attr_desc *attr;
4434 struct attr_value *av, *common_av;
4435 int i;
4437 /* Compute the maximum number of delay slots required. We use the delay
4438 ordinal times this number plus one, plus the slot number as an index into
4439 the appropriate predicate to test. */
4441 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4442 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4443 max_slots = XVECLEN (delay->def, 1) / 3;
4445 /* Write function prelude. */
4447 fprintf (outf, "int\n");
4448 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4449 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4450 kind);
4451 fprintf (outf, "{\n");
4452 fprintf (outf, " rtx_insn *insn;\n");
4453 fprintf (outf, "\n");
4454 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
4455 fprintf (outf, "\n");
4456 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4457 converts a compound instruction into a loop. */
4458 fprintf (outf, " if (!INSN_P (candidate_insn))\n");
4459 fprintf (outf, " return 0;\n");
4460 fprintf (outf, "\n");
4462 /* If more than one delay type, find out which type the delay insn is. */
4464 if (num_delays > 1)
4466 attr = find_attr (&delay_type_str, 0);
4467 gcc_assert (attr);
4468 common_av = find_most_used (attr);
4470 fprintf (outf, " insn = delay_insn;\n");
4471 fprintf (outf, " switch (recog_memoized (insn))\n");
4472 fprintf (outf, " {\n");
4474 sprintf (str, " * %d;\n break;", max_slots);
4475 for (av = attr->first_value; av; av = av->next)
4476 if (av != common_av)
4477 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4479 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4480 fprintf (outf, " }\n\n");
4482 /* Ensure matched. Otherwise, shouldn't have been called. */
4483 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
4486 /* If just one type of delay slot, write simple switch. */
4487 if (num_delays == 1 && max_slots == 1)
4489 fprintf (outf, " insn = candidate_insn;\n");
4490 fprintf (outf, " switch (recog_memoized (insn))\n");
4491 fprintf (outf, " {\n");
4493 attr = find_attr (&delay_1_0_str, 0);
4494 gcc_assert (attr);
4495 common_av = find_most_used (attr);
4497 for (av = attr->first_value; av; av = av->next)
4498 if (av != common_av)
4499 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4501 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4502 fprintf (outf, " }\n");
4505 else
4507 /* Write a nested CASE. The first indicates which condition we need to
4508 test, and the inner CASE tests the condition. */
4509 fprintf (outf, " insn = candidate_insn;\n");
4510 fprintf (outf, " switch (slot)\n");
4511 fprintf (outf, " {\n");
4513 for (delay = delays; delay; delay = delay->next)
4514 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4516 fprintf (outf, " case %d:\n",
4517 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4518 fprintf (outf, " switch (recog_memoized (insn))\n");
4519 fprintf (outf, "\t{\n");
4521 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4522 pstr = str;
4523 attr = find_attr (&pstr, 0);
4524 gcc_assert (attr);
4525 common_av = find_most_used (attr);
4527 for (av = attr->first_value; av; av = av->next)
4528 if (av != common_av)
4529 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4531 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4532 fprintf (outf, " }\n");
4535 fprintf (outf, " default:\n");
4536 fprintf (outf, " gcc_unreachable ();\n");
4537 fprintf (outf, " }\n");
4540 fprintf (outf, "}\n\n");
4543 /* This page contains miscellaneous utility routines. */
4545 /* Given a pointer to a (char *), return a malloc'ed string containing the
4546 next comma-separated element. Advance the pointer to after the string
4547 scanned, or the end-of-string. Return NULL if at end of string. */
4549 static char *
4550 next_comma_elt (const char **pstr)
4552 const char *start;
4554 start = scan_comma_elt (pstr);
4556 if (start == NULL)
4557 return NULL;
4559 return attr_string (start, *pstr - start);
4562 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4563 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4564 replaced by a pointer to a canonical copy of the string. */
4566 static struct attr_desc *
4567 find_attr (const char **name_p, int create)
4569 struct attr_desc *attr;
4570 int index;
4571 const char *name = *name_p;
4573 /* Before we resort to using `strcmp', see if the string address matches
4574 anywhere. In most cases, it should have been canonicalized to do so. */
4575 if (name == alternative_name)
4576 return NULL;
4578 index = name[0] & (MAX_ATTRS_INDEX - 1);
4579 for (attr = attrs[index]; attr; attr = attr->next)
4580 if (name == attr->name)
4581 return attr;
4583 /* Otherwise, do it the slow way. */
4584 for (attr = attrs[index]; attr; attr = attr->next)
4585 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4587 *name_p = attr->name;
4588 return attr;
4591 if (! create)
4592 return NULL;
4594 attr = oballoc (struct attr_desc);
4595 attr->name = DEF_ATTR_STRING (name);
4596 attr->enum_name = 0;
4597 attr->first_value = attr->default_val = NULL;
4598 attr->is_numeric = attr->is_const = attr->is_special = 0;
4599 attr->next = attrs[index];
4600 attrs[index] = attr;
4602 *name_p = attr->name;
4604 return attr;
4607 /* Create internal attribute with the given default value. */
4609 static void
4610 make_internal_attr (const char *name, rtx value, int special)
4612 struct attr_desc *attr;
4614 attr = find_attr (&name, 1);
4615 gcc_assert (!attr->default_val);
4617 attr->is_numeric = 1;
4618 attr->is_const = 0;
4619 attr->is_special = (special & ATTR_SPECIAL) != 0;
4620 attr->default_val = get_attr_value (file_location ("<internal>", 0),
4621 value, attr, -2);
4624 /* Find the most used value of an attribute. */
4626 static struct attr_value *
4627 find_most_used (struct attr_desc *attr)
4629 struct attr_value *av;
4630 struct attr_value *most_used;
4631 int nuses;
4633 most_used = NULL;
4634 nuses = -1;
4636 for (av = attr->first_value; av; av = av->next)
4637 if (av->num_insns > nuses)
4638 nuses = av->num_insns, most_used = av;
4640 return most_used;
4643 /* Return (attr_value "n") */
4645 static rtx
4646 make_numeric_value (int n)
4648 static rtx int_values[20];
4649 rtx exp;
4650 char *p;
4652 gcc_assert (n >= 0);
4654 if (n < 20 && int_values[n])
4655 return int_values[n];
4657 p = attr_printf (MAX_DIGITS, "%d", n);
4658 exp = attr_rtx (CONST_STRING, p);
4660 if (n < 20)
4661 int_values[n] = exp;
4663 return exp;
4666 static rtx
4667 copy_rtx_unchanging (rtx orig)
4669 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4670 return orig;
4672 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4673 return orig;
4676 /* Determine if an insn has a constant number of delay slots, i.e., the
4677 number of delay slots is not a function of the length of the insn. */
4679 static void
4680 write_const_num_delay_slots (FILE *outf)
4682 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4683 struct attr_value *av;
4685 if (attr)
4687 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4688 fprintf (outf, "{\n");
4689 fprintf (outf, " switch (recog_memoized (insn))\n");
4690 fprintf (outf, " {\n");
4692 for (av = attr->first_value; av; av = av->next)
4694 length_used = 0;
4695 walk_attr_value (av->value);
4696 if (length_used)
4697 write_insn_cases (outf, av->first_insn, 4);
4700 fprintf (outf, " default:\n");
4701 fprintf (outf, " return 1;\n");
4702 fprintf (outf, " }\n}\n\n");
4706 /* Synthetic attributes used by insn-automata.c and the scheduler.
4707 These are primarily concerned with (define_insn_reservation)
4708 patterns. */
4710 struct insn_reserv
4712 struct insn_reserv *next;
4714 const char *name;
4715 int default_latency;
4716 rtx condexp;
4718 /* Sequence number of this insn. */
4719 int insn_num;
4721 /* Whether a (define_bypass) construct names this insn in its
4722 output list. */
4723 bool bypassed;
4726 static struct insn_reserv *all_insn_reservs = 0;
4727 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4728 static size_t n_insn_reservs;
4730 /* Store information from a DEFINE_INSN_RESERVATION for future
4731 attribute generation. */
4732 static void
4733 gen_insn_reserv (md_rtx_info *info)
4735 struct insn_reserv *decl = oballoc (struct insn_reserv);
4736 rtx def = info->def;
4738 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4739 decl->default_latency = XINT (def, 1);
4740 decl->condexp = check_attr_test (XEXP (def, 2), 0, info->loc);
4741 decl->insn_num = n_insn_reservs;
4742 decl->bypassed = false;
4743 decl->next = 0;
4745 *last_insn_reserv_p = decl;
4746 last_insn_reserv_p = &decl->next;
4747 n_insn_reservs++;
4750 /* Store information from a DEFINE_BYPASS for future attribute
4751 generation. The only thing we care about is the list of output
4752 insns, which will later be used to tag reservation structures with
4753 a 'bypassed' bit. */
4755 struct bypass_list
4757 struct bypass_list *next;
4758 const char *pattern;
4761 static struct bypass_list *all_bypasses;
4762 static size_t n_bypasses;
4763 static size_t n_bypassed;
4765 static void
4766 gen_bypass_1 (const char *s, size_t len)
4768 struct bypass_list *b;
4770 if (len == 0)
4771 return;
4773 s = attr_string (s, len);
4774 for (b = all_bypasses; b; b = b->next)
4775 if (s == b->pattern)
4776 return; /* already got that one */
4778 b = oballoc (struct bypass_list);
4779 b->pattern = s;
4780 b->next = all_bypasses;
4781 all_bypasses = b;
4782 n_bypasses++;
4785 static void
4786 gen_bypass (md_rtx_info *info)
4788 const char *p, *base;
4790 rtx def = info->def;
4791 for (p = base = XSTR (def, 1); *p; p++)
4792 if (*p == ',')
4794 gen_bypass_1 (base, p - base);
4796 p++;
4797 while (ISSPACE (*p));
4798 base = p;
4800 gen_bypass_1 (base, p - base);
4803 /* Find and mark all of the bypassed insns. */
4804 static void
4805 process_bypasses (void)
4807 struct bypass_list *b;
4808 struct insn_reserv *r;
4810 n_bypassed = 0;
4812 /* The reservation list is likely to be much longer than the bypass
4813 list. */
4814 for (r = all_insn_reservs; r; r = r->next)
4815 for (b = all_bypasses; b; b = b->next)
4816 if (fnmatch (b->pattern, r->name, 0) == 0)
4818 n_bypassed++;
4819 r->bypassed = true;
4820 break;
4824 /* Check that attribute NAME is used in define_insn_reservation condition
4825 EXP. Return true if it is. */
4826 static bool
4827 check_tune_attr (const char *name, rtx exp)
4829 switch (GET_CODE (exp))
4831 case AND:
4832 if (check_tune_attr (name, XEXP (exp, 0)))
4833 return true;
4834 return check_tune_attr (name, XEXP (exp, 1));
4836 case IOR:
4837 return (check_tune_attr (name, XEXP (exp, 0))
4838 && check_tune_attr (name, XEXP (exp, 1)));
4840 case EQ_ATTR:
4841 return XSTR (exp, 0) == name;
4843 default:
4844 return false;
4848 /* Try to find a const attribute (usually cpu or tune) that is used
4849 in all define_insn_reservation conditions. */
4850 static struct attr_desc *
4851 find_tune_attr (rtx exp)
4853 struct attr_desc *attr;
4855 switch (GET_CODE (exp))
4857 case AND:
4858 case IOR:
4859 attr = find_tune_attr (XEXP (exp, 0));
4860 if (attr)
4861 return attr;
4862 return find_tune_attr (XEXP (exp, 1));
4864 case EQ_ATTR:
4865 if (XSTR (exp, 0) == alternative_name)
4866 return NULL;
4868 attr = find_attr (&XSTR (exp, 0), 0);
4869 gcc_assert (attr);
4871 if (attr->is_const && !attr->is_special)
4873 struct insn_reserv *decl;
4875 for (decl = all_insn_reservs; decl; decl = decl->next)
4876 if (! check_tune_attr (attr->name, decl->condexp))
4877 return NULL;
4878 return attr;
4880 return NULL;
4882 default:
4883 return NULL;
4887 /* Create all of the attributes that describe automaton properties.
4888 Write the DFA and latency function prototypes to the files that
4889 need to have them, and write the init_sched_attrs(). */
4891 static void
4892 make_automaton_attrs (void)
4894 int i;
4895 struct insn_reserv *decl;
4896 rtx code_exp, lats_exp, byps_exp;
4897 struct attr_desc *tune_attr;
4899 if (n_insn_reservs == 0)
4900 return;
4902 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4903 if (tune_attr != NULL)
4905 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4906 struct attr_value *val;
4907 bool first = true;
4909 gcc_assert (tune_attr->is_const
4910 && !tune_attr->is_special
4911 && !tune_attr->is_numeric);
4913 /* Write the prototypes for all DFA functions. */
4914 for (val = tune_attr->first_value; val; val = val->next)
4916 if (val == tune_attr->default_val)
4917 continue;
4918 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4919 fprintf (dfa_file,
4920 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4921 XSTR (val->value, 0));
4923 fprintf (dfa_file, "\n");
4925 /* Write the prototypes for all latency functions. */
4926 for (val = tune_attr->first_value; val; val = val->next)
4928 if (val == tune_attr->default_val)
4929 continue;
4930 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4931 fprintf (latency_file,
4932 "extern int insn_default_latency_%s (rtx_insn *);\n",
4933 XSTR (val->value, 0));
4935 fprintf (latency_file, "\n");
4937 /* Write the prototypes for all automaton functions. */
4938 for (val = tune_attr->first_value; val; val = val->next)
4940 if (val == tune_attr->default_val)
4941 continue;
4942 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4943 fprintf (attr_file,
4944 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4945 "extern int insn_default_latency_%s (rtx_insn *);\n",
4946 XSTR (val->value, 0), XSTR (val->value, 0));
4948 fprintf (attr_file, "\n");
4949 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4950 fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n");
4951 fprintf (attr_file, "\n");
4952 fprintf (attr_file, "void\n");
4953 fprintf (attr_file, "init_sched_attrs (void)\n");
4954 fprintf (attr_file, "{\n");
4956 for (val = tune_attr->first_value; val; val = val->next)
4958 int j;
4959 char *name;
4960 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
4962 if (val == tune_attr->default_val)
4963 continue;
4964 for (decl = all_insn_reservs, i = 0;
4965 decl;
4966 decl = decl->next)
4968 rtx ctest = test;
4969 rtx condexp
4970 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
4971 if (condexp == false_rtx)
4972 continue;
4973 if (condexp == true_rtx)
4974 break;
4975 condexps[i] = condexp;
4976 condexps[i + 1] = make_numeric_value (decl->insn_num);
4977 condexps[i + 2] = make_numeric_value (decl->default_latency);
4978 i += 3;
4981 code_exp = rtx_alloc (COND);
4982 lats_exp = rtx_alloc (COND);
4984 j = i / 3 * 2;
4985 XVEC (code_exp, 0) = rtvec_alloc (j);
4986 XVEC (lats_exp, 0) = rtvec_alloc (j);
4988 if (decl)
4990 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
4991 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
4993 else
4995 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
4996 XEXP (lats_exp, 1) = make_numeric_value (0);
4999 while (i > 0)
5001 i -= 3;
5002 j -= 2;
5003 XVECEXP (code_exp, 0, j) = condexps[i];
5004 XVECEXP (lats_exp, 0, j) = condexps[i];
5006 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
5007 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5010 name = XNEWVEC (char,
5011 sizeof ("*internal_dfa_insn_code_")
5012 + strlen (XSTR (val->value, 0)));
5013 strcpy (name, "*internal_dfa_insn_code_");
5014 strcat (name, XSTR (val->value, 0));
5015 make_internal_attr (name, code_exp, ATTR_NONE);
5016 strcpy (name, "*insn_default_latency_");
5017 strcat (name, XSTR (val->value, 0));
5018 make_internal_attr (name, lats_exp, ATTR_NONE);
5019 XDELETEVEC (name);
5021 if (first)
5023 fprintf (attr_file, " if (");
5024 first = false;
5026 else
5027 fprintf (attr_file, " else if (");
5028 write_test_expr (attr_file, test, 0, 0);
5029 fprintf (attr_file, ")\n");
5030 fprintf (attr_file, " {\n");
5031 fprintf (attr_file, " internal_dfa_insn_code\n");
5032 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
5033 XSTR (val->value, 0));
5034 fprintf (attr_file, " insn_default_latency\n");
5035 fprintf (attr_file, " = insn_default_latency_%s;\n",
5036 XSTR (val->value, 0));
5037 fprintf (attr_file, " }\n");
5040 fprintf (attr_file, " else\n");
5041 fprintf (attr_file, " gcc_unreachable ();\n");
5042 fprintf (attr_file, "}\n");
5043 fprintf (attr_file, "\n");
5045 XDELETEVEC (condexps);
5047 else
5049 code_exp = rtx_alloc (COND);
5050 lats_exp = rtx_alloc (COND);
5052 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5053 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5055 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5056 XEXP (lats_exp, 1) = make_numeric_value (0);
5058 for (decl = all_insn_reservs, i = 0;
5059 decl;
5060 decl = decl->next, i += 2)
5062 XVECEXP (code_exp, 0, i) = decl->condexp;
5063 XVECEXP (lats_exp, 0, i) = decl->condexp;
5065 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5066 XVECEXP (lats_exp, 0, i+1)
5067 = make_numeric_value (decl->default_latency);
5069 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5070 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
5073 if (n_bypasses == 0)
5074 byps_exp = make_numeric_value (0);
5075 else
5077 process_bypasses ();
5079 byps_exp = rtx_alloc (COND);
5080 XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2);
5081 XEXP (byps_exp, 1) = make_numeric_value (0);
5082 for (decl = all_insn_reservs, i = 0;
5083 decl;
5084 decl = decl->next)
5085 if (decl->bypassed)
5087 XVECEXP (byps_exp, 0, i) = decl->condexp;
5088 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5089 i += 2;
5093 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5096 static void
5097 write_header (FILE *outf)
5099 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5100 " from the machine description file `md'. */\n\n");
5102 fprintf (outf, "#include \"config.h\"\n");
5103 fprintf (outf, "#include \"system.h\"\n");
5104 fprintf (outf, "#include \"coretypes.h\"\n");
5105 fprintf (outf, "#include \"backend.h\"\n");
5106 fprintf (outf, "#include \"predict.h\"\n");
5107 fprintf (outf, "#include \"tree.h\"\n");
5108 fprintf (outf, "#include \"rtl.h\"\n");
5109 fprintf (outf, "#include \"alias.h\"\n");
5110 fprintf (outf, "#include \"options.h\"\n");
5111 fprintf (outf, "#include \"varasm.h\"\n");
5112 fprintf (outf, "#include \"stor-layout.h\"\n");
5113 fprintf (outf, "#include \"calls.h\"\n");
5114 fprintf (outf, "#include \"insn-attr.h\"\n");
5115 fprintf (outf, "#include \"tm_p.h\"\n");
5116 fprintf (outf, "#include \"insn-config.h\"\n");
5117 fprintf (outf, "#include \"recog.h\"\n");
5118 fprintf (outf, "#include \"regs.h\"\n");
5119 fprintf (outf, "#include \"real.h\"\n");
5120 fprintf (outf, "#include \"output.h\"\n");
5121 fprintf (outf, "#include \"toplev.h\"\n");
5122 fprintf (outf, "#include \"flags.h\"\n");
5123 fprintf (outf, "#include \"emit-rtl.h\"\n");
5124 fprintf (outf, "\n");
5125 fprintf (outf, "#define operands recog_data.operand\n\n");
5128 static FILE *
5129 open_outfile (const char *file_name)
5131 FILE *outf;
5132 outf = fopen (file_name, "w");
5133 if (! outf)
5134 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5135 write_header (outf);
5136 return outf;
5139 static bool
5140 handle_arg (const char *arg)
5142 switch (arg[1])
5144 case 'A':
5145 attr_file_name = &arg[2];
5146 return true;
5147 case 'D':
5148 dfa_file_name = &arg[2];
5149 return true;
5150 case 'L':
5151 latency_file_name = &arg[2];
5152 return true;
5153 default:
5154 return false;
5159 main (int argc, char **argv)
5161 struct attr_desc *attr;
5162 struct insn_def *id;
5163 int i;
5165 progname = "genattrtab";
5167 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5168 return FATAL_EXIT_CODE;
5170 attr_file = open_outfile (attr_file_name);
5171 dfa_file = open_outfile (dfa_file_name);
5172 latency_file = open_outfile (latency_file_name);
5174 obstack_init (hash_obstack);
5175 obstack_init (temp_obstack);
5177 /* Set up true and false rtx's */
5178 true_rtx = rtx_alloc (CONST_INT);
5179 XWINT (true_rtx, 0) = 1;
5180 false_rtx = rtx_alloc (CONST_INT);
5181 XWINT (false_rtx, 0) = 0;
5182 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5183 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5185 alternative_name = DEF_ATTR_STRING ("alternative");
5186 length_str = DEF_ATTR_STRING ("length");
5187 delay_type_str = DEF_ATTR_STRING ("*delay_type");
5188 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5189 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5191 /* Read the machine description. */
5193 md_rtx_info info;
5194 while (read_md_rtx (&info))
5196 switch (GET_CODE (info.def))
5198 case DEFINE_INSN:
5199 case DEFINE_PEEPHOLE:
5200 case DEFINE_ASM_ATTRIBUTES:
5201 gen_insn (&info);
5202 break;
5204 case DEFINE_ATTR:
5205 case DEFINE_ENUM_ATTR:
5206 gen_attr (&info);
5207 break;
5209 case DEFINE_DELAY:
5210 gen_delay (&info);
5211 break;
5213 case DEFINE_INSN_RESERVATION:
5214 gen_insn_reserv (&info);
5215 break;
5217 case DEFINE_BYPASS:
5218 gen_bypass (&info);
5219 break;
5221 default:
5222 break;
5224 if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
5225 insn_index_number++;
5228 if (have_error)
5229 return FATAL_EXIT_CODE;
5231 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5232 if (! got_define_asm_attributes)
5234 md_rtx_info info;
5235 info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5236 XVEC (info.def, 0) = rtvec_alloc (0);
5237 info.loc = file_location ("<internal>", 0);
5238 info.index = -1;
5239 gen_insn (&info);
5242 /* Expand DEFINE_DELAY information into new attribute. */
5243 if (num_delays)
5244 expand_delays ();
5246 /* Make `insn_alternatives'. */
5247 int num_insn_codes = get_num_insn_codes ();
5248 insn_alternatives = oballocvec (uint64_t, num_insn_codes);
5249 for (id = defs; id; id = id->next)
5250 if (id->insn_code >= 0)
5251 insn_alternatives[id->insn_code]
5252 = (((uint64_t) 1) << id->num_alternatives) - 1;
5254 /* Make `insn_n_alternatives'. */
5255 insn_n_alternatives = oballocvec (int, num_insn_codes);
5256 for (id = defs; id; id = id->next)
5257 if (id->insn_code >= 0)
5258 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5260 /* Construct extra attributes for automata. */
5261 make_automaton_attrs ();
5263 /* Prepare to write out attribute subroutines by checking everything stored
5264 away and building the attribute cases. */
5266 check_defs ();
5268 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5269 for (attr = attrs[i]; attr; attr = attr->next)
5270 attr->default_val->value
5271 = check_attr_value (attr->default_val->value, attr);
5273 if (have_error)
5274 return FATAL_EXIT_CODE;
5276 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5277 for (attr = attrs[i]; attr; attr = attr->next)
5278 fill_attr (attr);
5280 /* Construct extra attributes for `length'. */
5281 make_length_attrs ();
5283 /* Perform any possible optimizations to speed up compilation. */
5284 optimize_attrs (num_insn_codes);
5286 /* Now write out all the `gen_attr_...' routines. Do these before the
5287 special routines so that they get defined before they are used. */
5289 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5290 for (attr = attrs[i]; attr; attr = attr->next)
5292 FILE *outf;
5294 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5295 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5296 outf = dfa_file;
5297 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5298 outf = latency_file;
5299 else
5300 outf = attr_file;
5301 #undef IS_ATTR_GROUP
5303 if (! attr->is_special && ! attr->is_const)
5304 write_attr_get (outf, attr);
5307 /* Write out delay eligibility information, if DEFINE_DELAY present.
5308 (The function to compute the number of delay slots will be written
5309 below.) */
5310 if (num_delays)
5312 write_eligible_delay (attr_file, "delay");
5313 if (have_annul_true)
5314 write_eligible_delay (attr_file, "annul_true");
5315 if (have_annul_false)
5316 write_eligible_delay (attr_file, "annul_false");
5319 /* Write out constant delay slot info. */
5320 write_const_num_delay_slots (attr_file);
5322 write_length_unit_log (attr_file);
5324 if (fclose (attr_file) != 0)
5325 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5326 if (fclose (dfa_file) != 0)
5327 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5328 if (fclose (latency_file) != 0)
5329 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5331 return SUCCESS_EXIT_CODE;