Daily bump.
[official-gcc.git] / gcc / genattrtab.c
blobb64d8b9831b0538256d47474afe0f3d91f471f27
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991-2016 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 EXP for attribute ATTR, ensure it is validly
733 formed. LOC is the location of the .md construct that contains EXP.
735 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
736 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
737 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
739 Update the string address in EQ_ATTR expression to be the same used
740 in the attribute (or `alternative_name') to speed up subsequent
741 `find_attr' calls and eliminate most `strcmp' calls.
743 Return the new expression, if any. */
745 static rtx
746 check_attr_test (file_location loc, rtx exp, attr_desc *attr)
748 struct attr_value *av;
749 const char *name_ptr, *p;
750 rtx orexp, newexp;
752 switch (GET_CODE (exp))
754 case EQ_ATTR:
755 /* Handle negation test. */
756 if (XSTR (exp, 1)[0] == '!')
757 return check_attr_test (loc,
758 attr_rtx (NOT,
759 attr_eq (XSTR (exp, 0),
760 &XSTR (exp, 1)[1])),
761 attr);
763 else if (n_comma_elts (XSTR (exp, 1)) == 1)
765 attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
766 if (attr2 == NULL)
768 if (! strcmp (XSTR (exp, 0), "alternative"))
769 return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1)));
770 else
771 fatal_at (loc, "unknown attribute `%s' in definition of"
772 " attribute `%s'", XSTR (exp, 0), attr->name);
775 if (attr->is_const && ! attr2->is_const)
776 fatal_at (loc, "constant attribute `%s' cannot test non-constant"
777 " attribute `%s'", attr->name, attr2->name);
779 /* Copy this just to make it permanent,
780 so expressions using it can be permanent too. */
781 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
783 /* It shouldn't be possible to simplify the value given to a
784 constant attribute, so don't expand this until it's time to
785 write the test expression. */
786 if (attr2->is_const)
787 ATTR_IND_SIMPLIFIED_P (exp) = 1;
789 if (attr2->is_numeric)
791 for (p = XSTR (exp, 1); *p; p++)
792 if (! ISDIGIT (*p))
793 fatal_at (loc, "attribute `%s' takes only numeric values",
794 attr2->name);
796 else
798 for (av = attr2->first_value; av; av = av->next)
799 if (GET_CODE (av->value) == CONST_STRING
800 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
801 break;
803 if (av == NULL)
804 fatal_at (loc, "unknown value `%s' for attribute `%s'",
805 XSTR (exp, 1), attr2->name);
808 else
810 if (! strcmp (XSTR (exp, 0), "alternative"))
812 int set = 0;
814 name_ptr = XSTR (exp, 1);
815 while ((p = next_comma_elt (&name_ptr)) != NULL)
816 set |= ((uint64_t) 1) << atoi (p);
818 return mk_attr_alt (set);
820 else
822 /* Make an IOR tree of the possible values. */
823 orexp = false_rtx;
824 name_ptr = XSTR (exp, 1);
825 while ((p = next_comma_elt (&name_ptr)) != NULL)
827 newexp = attr_eq (XSTR (exp, 0), p);
828 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
831 return check_attr_test (loc, orexp, attr);
834 break;
836 case ATTR_FLAG:
837 break;
839 case CONST_INT:
840 /* Either TRUE or FALSE. */
841 if (XWINT (exp, 0))
842 return true_rtx;
843 else
844 return false_rtx;
846 case IOR:
847 case AND:
848 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
849 XEXP (exp, 1) = check_attr_test (loc, XEXP (exp, 1), attr);
850 break;
852 case NOT:
853 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
854 break;
856 case MATCH_TEST:
857 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
858 ATTR_IND_SIMPLIFIED_P (exp) = 1;
859 break;
861 case MATCH_OPERAND:
862 if (attr->is_const)
863 fatal_at (loc, "invalid operator `%s' in definition of constant"
864 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
865 attr->name);
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 (attr->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, "invalid operator `%s' in definition of attribute"
893 " `%s'", GET_RTX_NAME (GET_CODE (exp)), attr->name);
896 return exp;
899 /* Given an expression EXP, ensure that it is validly formed and that
900 all named attribute values are valid for ATTR. Issue an error if not.
901 LOC is the location of the .md construct that contains EXP.
903 Return a perhaps modified replacement expression for the value. */
905 static rtx
906 check_attr_value (file_location loc, 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 (loc,
918 "CONST_INT not valid for non-numeric attribute `%s'",
919 attr->name);
920 break;
923 if (INTVAL (exp) < 0)
925 error_at (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 (loc,
943 "non-numeric value specified for numeric"
944 " attribute `%s'", 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 (loc, "unknown value `%s' for attribute `%s'",
957 XSTR (exp, 0), attr->name);
958 break;
960 case IF_THEN_ELSE:
961 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
962 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
963 XEXP (exp, 2) = check_attr_value (loc, XEXP (exp, 2), attr);
964 break;
966 case PLUS:
967 case MINUS:
968 case MULT:
969 case DIV:
970 case MOD:
971 if (!attr->is_numeric)
973 error_at (loc, "invalid operation `%s' for non-numeric"
974 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
975 attr->name);
976 break;
978 /* Fall through. */
980 case IOR:
981 case AND:
982 XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
983 XEXP (exp, 1) = check_attr_value (loc, 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 (loc, XEXP (exp, 0), attr);
993 break;
995 case COND:
996 if (XVECLEN (exp, 0) % 2 != 0)
998 error_at (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 (attr->loc,
1005 XVECEXP (exp, 0, i),
1006 attr);
1007 XVECEXP (exp, 0, i + 1)
1008 = check_attr_value (loc, XVECEXP (exp, 0, i + 1), attr);
1011 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
1012 break;
1014 case ATTR:
1016 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1017 if (attr2 == NULL)
1018 error_at (loc, "unknown attribute `%s' in ATTR",
1019 XSTR (exp, 0));
1020 else if (attr->is_const && ! attr2->is_const)
1021 error_at (attr->loc,
1022 "constant attribute `%s' cannot refer to non-constant"
1023 " attribute `%s'", attr->name, attr2->name);
1024 else if (attr->is_numeric != attr2->is_numeric)
1025 error_at (loc,
1026 "numeric attribute mismatch calling `%s' from `%s'",
1027 attr2->name, attr->name);
1029 break;
1031 case SYMBOL_REF:
1032 /* A constant SYMBOL_REF is valid as a constant attribute test and
1033 is expanded later by make_canonical into a COND. In a non-constant
1034 attribute test, it is left be. */
1035 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1037 default:
1038 error_at (loc, "invalid operator `%s' in definition of attribute `%s'",
1039 GET_RTX_NAME (GET_CODE (exp)), attr->name);
1040 break;
1043 return exp;
1046 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1047 It becomes a COND with each test being (eq_attr "alternative" "n") */
1049 static rtx
1050 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1052 int num_alt = id->num_alternatives;
1053 rtx condexp;
1054 int i;
1056 if (XVECLEN (exp, 1) != num_alt)
1058 error_at (id->loc, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1059 " was %d expected %d", XVECLEN (exp, 1), num_alt);
1060 return NULL_RTX;
1063 /* Make a COND with all tests but the last. Select the last value via the
1064 default. */
1065 condexp = rtx_alloc (COND);
1066 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1068 for (i = 0; i < num_alt - 1; i++)
1070 const char *p;
1071 p = attr_numeral (i);
1073 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1074 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1077 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1079 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1082 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1083 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1085 static rtx
1086 convert_set_attr (rtx exp, struct insn_def *id)
1088 rtx newexp;
1089 const char *name_ptr;
1090 char *p;
1091 int n;
1093 /* See how many alternative specified. */
1094 n = n_comma_elts (XSTR (exp, 1));
1095 if (n == 1)
1096 return attr_rtx (SET,
1097 attr_rtx (ATTR, XSTR (exp, 0)),
1098 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1100 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1101 XSTR (newexp, 0) = XSTR (exp, 0);
1102 XVEC (newexp, 1) = rtvec_alloc (n);
1104 /* Process each comma-separated name. */
1105 name_ptr = XSTR (exp, 1);
1106 n = 0;
1107 while ((p = next_comma_elt (&name_ptr)) != NULL)
1108 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1110 return convert_set_attr_alternative (newexp, id);
1113 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1114 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1115 expressions. */
1117 static void
1118 check_defs (void)
1120 struct insn_def *id;
1121 struct attr_desc *attr;
1122 int i;
1123 rtx value;
1125 for (id = defs; id; id = id->next)
1127 if (XVEC (id->def, id->vec_idx) == NULL)
1128 continue;
1130 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1132 value = XVECEXP (id->def, id->vec_idx, i);
1133 switch (GET_CODE (value))
1135 case SET:
1136 if (GET_CODE (XEXP (value, 0)) != ATTR)
1138 error_at (id->loc, "bad attribute set");
1139 value = NULL_RTX;
1141 break;
1143 case SET_ATTR_ALTERNATIVE:
1144 value = convert_set_attr_alternative (value, id);
1145 break;
1147 case SET_ATTR:
1148 value = convert_set_attr (value, id);
1149 break;
1151 default:
1152 error_at (id->loc, "invalid attribute code %s",
1153 GET_RTX_NAME (GET_CODE (value)));
1154 value = NULL_RTX;
1156 if (value == NULL_RTX)
1157 continue;
1159 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1161 error_at (id->loc, "unknown attribute %s",
1162 XSTR (XEXP (value, 0), 0));
1163 continue;
1166 XVECEXP (id->def, id->vec_idx, i) = value;
1167 XEXP (value, 1) = check_attr_value (id->loc, XEXP (value, 1), attr);
1172 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1173 expressions by converting them into a COND. This removes cases from this
1174 program. Also, replace an attribute value of "*" with the default attribute
1175 value. LOC is the location to use for error reporting. */
1177 static rtx
1178 make_canonical (file_location loc, struct attr_desc *attr, rtx exp)
1180 int i;
1181 rtx newexp;
1183 switch (GET_CODE (exp))
1185 case CONST_INT:
1186 exp = make_numeric_value (INTVAL (exp));
1187 break;
1189 case CONST_STRING:
1190 if (! strcmp (XSTR (exp, 0), "*"))
1192 if (attr->default_val == 0)
1193 fatal_at (loc, "(attr_value \"*\") used in invalid context");
1194 exp = attr->default_val->value;
1196 else
1197 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1199 break;
1201 case SYMBOL_REF:
1202 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1203 break;
1204 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1205 This makes the COND something that won't be considered an arbitrary
1206 expression by walk_attr_value. */
1207 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1208 exp = check_attr_value (loc, exp, attr);
1209 break;
1211 case IF_THEN_ELSE:
1212 newexp = rtx_alloc (COND);
1213 XVEC (newexp, 0) = rtvec_alloc (2);
1214 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1215 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1217 XEXP (newexp, 1) = XEXP (exp, 2);
1219 exp = newexp;
1220 /* Fall through to COND case since this is now a COND. */
1222 case COND:
1224 int allsame = 1;
1225 rtx defval;
1227 /* First, check for degenerate COND. */
1228 if (XVECLEN (exp, 0) == 0)
1229 return make_canonical (loc, attr, XEXP (exp, 1));
1230 defval = XEXP (exp, 1) = make_canonical (loc, attr, XEXP (exp, 1));
1232 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1234 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1235 XVECEXP (exp, 0, i + 1)
1236 = make_canonical (loc, attr, XVECEXP (exp, 0, i + 1));
1237 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1238 allsame = 0;
1240 if (allsame)
1241 return defval;
1243 break;
1245 default:
1246 break;
1249 return exp;
1252 static rtx
1253 copy_boolean (rtx exp)
1255 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1256 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1257 copy_boolean (XEXP (exp, 1)));
1258 if (GET_CODE (exp) == MATCH_OPERAND)
1260 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1261 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1263 else if (GET_CODE (exp) == EQ_ATTR)
1265 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1266 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1269 return exp;
1272 /* Given a value and an attribute description, return a `struct attr_value *'
1273 that represents that value. This is either an existing structure, if the
1274 value has been previously encountered, or a newly-created structure.
1276 `insn_code' is the code of an insn whose attribute has the specified
1277 value (-2 if not processing an insn). We ensure that all insns for
1278 a given value have the same number of alternatives if the value checks
1279 alternatives. LOC is the location to use for error reporting. */
1281 static struct attr_value *
1282 get_attr_value (file_location loc, rtx value, struct attr_desc *attr,
1283 int insn_code)
1285 struct attr_value *av;
1286 uint64_t num_alt = 0;
1288 value = make_canonical (loc, attr, value);
1289 if (compares_alternatives_p (value))
1291 if (insn_code < 0 || insn_alternatives == NULL)
1292 fatal_at (loc, "(eq_attr \"alternatives\" ...) used in non-insn"
1293 " context");
1294 else
1295 num_alt = insn_alternatives[insn_code];
1298 for (av = attr->first_value; av; av = av->next)
1299 if (rtx_equal_p (value, av->value)
1300 && (num_alt == 0 || av->first_insn == NULL
1301 || insn_alternatives[av->first_insn->def->insn_code]))
1302 return av;
1304 av = oballoc (struct attr_value);
1305 av->value = value;
1306 av->next = attr->first_value;
1307 attr->first_value = av;
1308 av->first_insn = NULL;
1309 av->num_insns = 0;
1310 av->has_asm_insn = 0;
1312 return av;
1315 /* After all DEFINE_DELAYs have been read in, create internal attributes
1316 to generate the required routines.
1318 First, we compute the number of delay slots for each insn (as a COND of
1319 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1320 delay type is specified, we compute a similar function giving the
1321 DEFINE_DELAY ordinal for each insn.
1323 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1324 tells whether a given insn can be in that delay slot.
1326 Normal attribute filling and optimization expands these to contain the
1327 information needed to handle delay slots. */
1329 static void
1330 expand_delays (void)
1332 struct delay_desc *delay;
1333 rtx condexp;
1334 rtx newexp;
1335 int i;
1336 char *p;
1338 /* First, generate data for `num_delay_slots' function. */
1340 condexp = rtx_alloc (COND);
1341 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1342 XEXP (condexp, 1) = make_numeric_value (0);
1344 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1346 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1347 XVECEXP (condexp, 0, i + 1)
1348 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1351 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1353 /* If more than one delay type, do the same for computing the delay type. */
1354 if (num_delays > 1)
1356 condexp = rtx_alloc (COND);
1357 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1358 XEXP (condexp, 1) = make_numeric_value (0);
1360 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1362 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1363 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1366 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1369 /* For each delay possibility and delay slot, compute an eligibility
1370 attribute for non-annulled insns and for each type of annulled (annul
1371 if true and annul if false). */
1372 for (delay = delays; delay; delay = delay->next)
1374 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1376 condexp = XVECEXP (delay->def, 1, i);
1377 if (condexp == 0)
1378 condexp = false_rtx;
1379 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1380 make_numeric_value (1), make_numeric_value (0));
1382 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1383 "*delay_%d_%d", delay->num, i / 3);
1384 make_internal_attr (p, newexp, ATTR_SPECIAL);
1386 if (have_annul_true)
1388 condexp = XVECEXP (delay->def, 1, i + 1);
1389 if (condexp == 0) condexp = false_rtx;
1390 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1391 make_numeric_value (1),
1392 make_numeric_value (0));
1393 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1394 "*annul_true_%d_%d", delay->num, i / 3);
1395 make_internal_attr (p, newexp, ATTR_SPECIAL);
1398 if (have_annul_false)
1400 condexp = XVECEXP (delay->def, 1, i + 2);
1401 if (condexp == 0) condexp = false_rtx;
1402 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1403 make_numeric_value (1),
1404 make_numeric_value (0));
1405 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1406 "*annul_false_%d_%d", delay->num, i / 3);
1407 make_internal_attr (p, newexp, ATTR_SPECIAL);
1413 /* Once all attributes and insns have been read and checked, we construct for
1414 each attribute value a list of all the insns that have that value for
1415 the attribute. */
1417 static void
1418 fill_attr (struct attr_desc *attr)
1420 struct attr_value *av;
1421 struct insn_ent *ie;
1422 struct insn_def *id;
1423 int i;
1424 rtx value;
1426 /* Don't fill constant attributes. The value is independent of
1427 any particular insn. */
1428 if (attr->is_const)
1429 return;
1431 for (id = defs; id; id = id->next)
1433 /* If no value is specified for this insn for this attribute, use the
1434 default. */
1435 value = NULL;
1436 if (XVEC (id->def, id->vec_idx))
1437 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1438 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1439 attr->name))
1440 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1442 if (value == NULL)
1443 av = attr->default_val;
1444 else
1445 av = get_attr_value (id->loc, value, attr, id->insn_code);
1447 ie = oballoc (struct insn_ent);
1448 ie->def = id;
1449 insert_insn_ent (av, ie);
1453 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1454 test that checks relative positions of insns (uses MATCH_DUP or PC).
1455 If so, replace it with what is obtained by passing the expression to
1456 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1457 recursively on each value (including the default value). Otherwise,
1458 return the value returned by NO_ADDRESS_FN applied to EXP. */
1460 static rtx
1461 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1462 rtx (*address_fn) (rtx))
1464 int i;
1465 rtx newexp;
1467 if (GET_CODE (exp) == COND)
1469 /* See if any tests use addresses. */
1470 address_used = 0;
1471 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1472 walk_attr_value (XVECEXP (exp, 0, i));
1474 if (address_used)
1475 return (*address_fn) (exp);
1477 /* Make a new copy of this COND, replacing each element. */
1478 newexp = rtx_alloc (COND);
1479 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1480 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1482 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1483 XVECEXP (newexp, 0, i + 1)
1484 = substitute_address (XVECEXP (exp, 0, i + 1),
1485 no_address_fn, address_fn);
1488 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1489 no_address_fn, address_fn);
1491 return newexp;
1494 else if (GET_CODE (exp) == IF_THEN_ELSE)
1496 address_used = 0;
1497 walk_attr_value (XEXP (exp, 0));
1498 if (address_used)
1499 return (*address_fn) (exp);
1501 return attr_rtx (IF_THEN_ELSE,
1502 substitute_address (XEXP (exp, 0),
1503 no_address_fn, address_fn),
1504 substitute_address (XEXP (exp, 1),
1505 no_address_fn, address_fn),
1506 substitute_address (XEXP (exp, 2),
1507 no_address_fn, address_fn));
1510 return (*no_address_fn) (exp);
1513 /* Make new attributes from the `length' attribute. The following are made,
1514 each corresponding to a function called from `shorten_branches' or
1515 `get_attr_length':
1517 *insn_default_length This is the length of the insn to be returned
1518 by `get_attr_length' before `shorten_branches'
1519 has been called. In each case where the length
1520 depends on relative addresses, the largest
1521 possible is used. This routine is also used
1522 to compute the initial size of the insn.
1524 *insn_variable_length_p This returns 1 if the insn's length depends
1525 on relative addresses, zero otherwise.
1527 *insn_current_length This is only called when it is known that the
1528 insn has a variable length and returns the
1529 current length, based on relative addresses.
1532 static void
1533 make_length_attrs (void)
1535 static const char *new_names[] =
1537 "*insn_default_length",
1538 "*insn_min_length",
1539 "*insn_variable_length_p",
1540 "*insn_current_length"
1542 static rtx (*const no_address_fn[]) (rtx)
1543 = {identity_fn,identity_fn, zero_fn, zero_fn};
1544 static rtx (*const address_fn[]) (rtx)
1545 = {max_fn, min_fn, one_fn, identity_fn};
1546 size_t i;
1547 struct attr_desc *length_attr, *new_attr;
1548 struct attr_value *av, *new_av;
1549 struct insn_ent *ie, *new_ie;
1551 /* See if length attribute is defined. If so, it must be numeric. Make
1552 it special so we don't output anything for it. */
1553 length_attr = find_attr (&length_str, 0);
1554 if (length_attr == 0)
1555 return;
1557 if (! length_attr->is_numeric)
1558 fatal_at (length_attr->loc, "length attribute must be numeric");
1560 length_attr->is_const = 0;
1561 length_attr->is_special = 1;
1563 /* Make each new attribute, in turn. */
1564 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1566 make_internal_attr (new_names[i],
1567 substitute_address (length_attr->default_val->value,
1568 no_address_fn[i], address_fn[i]),
1569 ATTR_NONE);
1570 new_attr = find_attr (&new_names[i], 0);
1571 for (av = length_attr->first_value; av; av = av->next)
1572 for (ie = av->first_insn; ie; ie = ie->next)
1574 new_av = get_attr_value (ie->def->loc,
1575 substitute_address (av->value,
1576 no_address_fn[i],
1577 address_fn[i]),
1578 new_attr, ie->def->insn_code);
1579 new_ie = oballoc (struct insn_ent);
1580 new_ie->def = ie->def;
1581 insert_insn_ent (new_av, new_ie);
1586 /* Utility functions called from above routine. */
1588 static rtx
1589 identity_fn (rtx exp)
1591 return exp;
1594 static rtx
1595 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1597 return make_numeric_value (0);
1600 static rtx
1601 one_fn (rtx exp ATTRIBUTE_UNUSED)
1603 return make_numeric_value (1);
1606 static rtx
1607 max_fn (rtx exp)
1609 int unknown;
1610 return make_numeric_value (max_attr_value (exp, &unknown));
1613 static rtx
1614 min_fn (rtx exp)
1616 int unknown;
1617 return make_numeric_value (min_attr_value (exp, &unknown));
1620 static void
1621 write_length_unit_log (FILE *outf)
1623 struct attr_desc *length_attr = find_attr (&length_str, 0);
1624 struct attr_value *av;
1625 struct insn_ent *ie;
1626 unsigned int length_unit_log, length_or;
1627 int unknown = 0;
1629 if (length_attr)
1631 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1632 for (av = length_attr->first_value; av; av = av->next)
1633 for (ie = av->first_insn; ie; ie = ie->next)
1634 length_or |= or_attr_value (av->value, &unknown);
1637 if (length_attr == NULL || unknown)
1638 length_unit_log = 0;
1639 else
1641 length_or = ~length_or;
1642 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1643 length_unit_log++;
1645 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1648 /* Compute approximate cost of the expression. Used to decide whether
1649 expression is cheap enough for inline. */
1650 static int
1651 attr_rtx_cost (rtx x)
1653 int cost = 1;
1654 enum rtx_code code;
1655 if (!x)
1656 return 0;
1657 code = GET_CODE (x);
1658 switch (code)
1660 case MATCH_OPERAND:
1661 if (XSTR (x, 1)[0])
1662 return 10;
1663 else
1664 return 1;
1666 case EQ_ATTR_ALT:
1667 return 1;
1669 case EQ_ATTR:
1670 /* Alternatives don't result into function call. */
1671 if (!strcmp_check (XSTR (x, 0), alternative_name))
1672 return 1;
1673 else
1674 return 5;
1675 default:
1677 int i, j;
1678 const char *fmt = GET_RTX_FORMAT (code);
1679 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1681 switch (fmt[i])
1683 case 'V':
1684 case 'E':
1685 for (j = 0; j < XVECLEN (x, i); j++)
1686 cost += attr_rtx_cost (XVECEXP (x, i, j));
1687 break;
1688 case 'e':
1689 cost += attr_rtx_cost (XEXP (x, i));
1690 break;
1694 break;
1696 return cost;
1699 /* Take a COND expression and see if any of the conditions in it can be
1700 simplified. If any are known true or known false for the particular insn
1701 code, the COND can be further simplified.
1703 Also call ourselves on any COND operations that are values of this COND.
1705 We do not modify EXP; rather, we make and return a new rtx. */
1707 static rtx
1708 simplify_cond (rtx exp, int insn_code, int insn_index)
1710 int i, j;
1711 /* We store the desired contents here,
1712 then build a new expression if they don't match EXP. */
1713 rtx defval = XEXP (exp, 1);
1714 rtx new_defval = XEXP (exp, 1);
1715 int len = XVECLEN (exp, 0);
1716 rtx *tests = XNEWVEC (rtx, len);
1717 int allsame = 1;
1718 rtx ret;
1720 /* This lets us free all storage allocated below, if appropriate. */
1721 obstack_finish (rtl_obstack);
1723 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1725 /* See if default value needs simplification. */
1726 if (GET_CODE (defval) == COND)
1727 new_defval = simplify_cond (defval, insn_code, insn_index);
1729 /* Simplify the subexpressions, and see what tests we can get rid of. */
1731 for (i = 0; i < len; i += 2)
1733 rtx newtest, newval;
1735 /* Simplify this test. */
1736 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1737 tests[i] = newtest;
1739 newval = tests[i + 1];
1740 /* See if this value may need simplification. */
1741 if (GET_CODE (newval) == COND)
1742 newval = simplify_cond (newval, insn_code, insn_index);
1744 /* Look for ways to delete or combine this test. */
1745 if (newtest == true_rtx)
1747 /* If test is true, make this value the default
1748 and discard this + any following tests. */
1749 len = i;
1750 defval = tests[i + 1];
1751 new_defval = newval;
1754 else if (newtest == false_rtx)
1756 /* If test is false, discard it and its value. */
1757 for (j = i; j < len - 2; j++)
1758 tests[j] = tests[j + 2];
1759 i -= 2;
1760 len -= 2;
1763 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1765 /* If this value and the value for the prev test are the same,
1766 merge the tests. */
1768 tests[i - 2]
1769 = insert_right_side (IOR, tests[i - 2], newtest,
1770 insn_code, insn_index);
1772 /* Delete this test/value. */
1773 for (j = i; j < len - 2; j++)
1774 tests[j] = tests[j + 2];
1775 len -= 2;
1776 i -= 2;
1779 else
1780 tests[i + 1] = newval;
1783 /* If the last test in a COND has the same value
1784 as the default value, that test isn't needed. */
1786 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1787 len -= 2;
1789 /* See if we changed anything. */
1790 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1791 allsame = 0;
1792 else
1793 for (i = 0; i < len; i++)
1794 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1796 allsame = 0;
1797 break;
1800 if (len == 0)
1802 if (GET_CODE (defval) == COND)
1803 ret = simplify_cond (defval, insn_code, insn_index);
1804 else
1805 ret = defval;
1807 else if (allsame)
1808 ret = exp;
1809 else
1811 rtx newexp = rtx_alloc (COND);
1813 XVEC (newexp, 0) = rtvec_alloc (len);
1814 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1815 XEXP (newexp, 1) = new_defval;
1816 ret = newexp;
1818 free (tests);
1819 return ret;
1822 /* Remove an insn entry from an attribute value. */
1824 static void
1825 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1827 struct insn_ent *previe;
1829 if (av->first_insn == ie)
1830 av->first_insn = ie->next;
1831 else
1833 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1835 previe->next = ie->next;
1838 av->num_insns--;
1839 if (ie->def->insn_code == -1)
1840 av->has_asm_insn = 0;
1842 num_insn_ents--;
1845 /* Insert an insn entry in an attribute value list. */
1847 static void
1848 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1850 ie->next = av->first_insn;
1851 av->first_insn = ie;
1852 av->num_insns++;
1853 if (ie->def->insn_code == -1)
1854 av->has_asm_insn = 1;
1856 num_insn_ents++;
1859 /* This is a utility routine to take an expression that is a tree of either
1860 AND or IOR expressions and insert a new term. The new term will be
1861 inserted at the right side of the first node whose code does not match
1862 the root. A new node will be created with the root's code. Its left
1863 side will be the old right side and its right side will be the new
1864 term.
1866 If the `term' is itself a tree, all its leaves will be inserted. */
1868 static rtx
1869 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1871 rtx newexp;
1873 /* Avoid consing in some special cases. */
1874 if (code == AND && term == true_rtx)
1875 return exp;
1876 if (code == AND && term == false_rtx)
1877 return false_rtx;
1878 if (code == AND && exp == true_rtx)
1879 return term;
1880 if (code == AND && exp == false_rtx)
1881 return false_rtx;
1882 if (code == IOR && term == true_rtx)
1883 return true_rtx;
1884 if (code == IOR && term == false_rtx)
1885 return exp;
1886 if (code == IOR && exp == true_rtx)
1887 return true_rtx;
1888 if (code == IOR && exp == false_rtx)
1889 return term;
1890 if (attr_equal_p (exp, term))
1891 return exp;
1893 if (GET_CODE (term) == code)
1895 exp = insert_right_side (code, exp, XEXP (term, 0),
1896 insn_code, insn_index);
1897 exp = insert_right_side (code, exp, XEXP (term, 1),
1898 insn_code, insn_index);
1900 return exp;
1903 if (GET_CODE (exp) == code)
1905 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1906 term, insn_code, insn_index);
1907 if (new_rtx != XEXP (exp, 1))
1908 /* Make a copy of this expression and call recursively. */
1909 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1910 else
1911 newexp = exp;
1913 else
1915 /* Insert the new term. */
1916 newexp = attr_rtx (code, exp, term);
1919 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1922 /* If we have an expression which AND's a bunch of
1923 (not (eq_attrq "alternative" "n"))
1924 terms, we may have covered all or all but one of the possible alternatives.
1925 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1927 This routine is passed an expression and either AND or IOR. It returns a
1928 bitmask indicating which alternatives are mentioned within EXP. */
1930 static uint64_t
1931 compute_alternative_mask (rtx exp, enum rtx_code code)
1933 const char *string;
1934 if (GET_CODE (exp) == code)
1935 return compute_alternative_mask (XEXP (exp, 0), code)
1936 | compute_alternative_mask (XEXP (exp, 1), code);
1938 else if (code == AND && GET_CODE (exp) == NOT
1939 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1940 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1941 string = XSTR (XEXP (exp, 0), 1);
1943 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1944 && XSTR (exp, 0) == alternative_name)
1945 string = XSTR (exp, 1);
1947 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1949 if (code == AND && XINT (exp, 1))
1950 return XINT (exp, 0);
1952 if (code == IOR && !XINT (exp, 1))
1953 return XINT (exp, 0);
1955 return 0;
1957 else
1958 return 0;
1960 if (string[1] == 0)
1961 return ((uint64_t) 1) << (string[0] - '0');
1962 return ((uint64_t) 1) << atoi (string);
1965 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1966 attribute with the value represented by that bit. */
1968 static rtx
1969 make_alternative_compare (uint64_t mask)
1971 return mk_attr_alt (mask);
1974 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1975 of "attr" for this insn code. From that value, we can compute a test
1976 showing when the EQ_ATTR will be true. This routine performs that
1977 computation. If a test condition involves an address, we leave the EQ_ATTR
1978 intact because addresses are only valid for the `length' attribute.
1980 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1981 it refers. VALUE is the value of that attribute for the insn
1982 corresponding to INSN_CODE and INSN_INDEX. */
1984 static rtx
1985 evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
1986 int insn_code, int insn_index)
1988 rtx orexp, andexp;
1989 rtx right;
1990 rtx newexp;
1991 int i;
1993 while (GET_CODE (value) == ATTR)
1995 struct attr_value *av = NULL;
1997 attr = find_attr (&XSTR (value, 0), 0);
1999 if (insn_code_values)
2001 struct attr_value_list *iv;
2002 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2003 if (iv->attr == attr)
2005 av = iv->av;
2006 break;
2009 else
2011 struct insn_ent *ie;
2012 for (av = attr->first_value; av; av = av->next)
2013 for (ie = av->first_insn; ie; ie = ie->next)
2014 if (ie->def->insn_code == insn_code)
2015 goto got_av;
2017 if (av)
2019 got_av:
2020 value = av->value;
2024 switch (GET_CODE (value))
2026 case CONST_STRING:
2027 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
2028 newexp = true_rtx;
2029 else
2030 newexp = false_rtx;
2031 break;
2033 case SYMBOL_REF:
2035 const char *prefix;
2036 char *string, *p;
2038 gcc_assert (GET_CODE (exp) == EQ_ATTR);
2039 prefix = attr->enum_name ? attr->enum_name : attr->name;
2040 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
2041 for (p = string; *p; p++)
2042 *p = TOUPPER (*p);
2044 newexp = attr_rtx (EQ, value,
2045 attr_rtx (SYMBOL_REF,
2046 DEF_ATTR_STRING (string)));
2047 break;
2050 case COND:
2051 /* We construct an IOR of all the cases for which the
2052 requested attribute value is present. Since we start with
2053 FALSE, if it is not present, FALSE will be returned.
2055 Each case is the AND of the NOT's of the previous conditions with the
2056 current condition; in the default case the current condition is TRUE.
2058 For each possible COND value, call ourselves recursively.
2060 The extra TRUE and FALSE expressions will be eliminated by another
2061 call to the simplification routine. */
2063 orexp = false_rtx;
2064 andexp = true_rtx;
2066 for (i = 0; i < XVECLEN (value, 0); i += 2)
2068 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2069 insn_code, insn_index);
2071 right = insert_right_side (AND, andexp, this_cond,
2072 insn_code, insn_index);
2073 right = insert_right_side (AND, right,
2074 evaluate_eq_attr (exp, attr,
2075 XVECEXP (value, 0,
2076 i + 1),
2077 insn_code, insn_index),
2078 insn_code, insn_index);
2079 orexp = insert_right_side (IOR, orexp, right,
2080 insn_code, insn_index);
2082 /* Add this condition into the AND expression. */
2083 newexp = attr_rtx (NOT, this_cond);
2084 andexp = insert_right_side (AND, andexp, newexp,
2085 insn_code, insn_index);
2088 /* Handle the default case. */
2089 right = insert_right_side (AND, andexp,
2090 evaluate_eq_attr (exp, attr, XEXP (value, 1),
2091 insn_code, insn_index),
2092 insn_code, insn_index);
2093 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2094 break;
2096 default:
2097 gcc_unreachable ();
2100 /* If uses an address, must return original expression. But set the
2101 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2103 address_used = 0;
2104 walk_attr_value (newexp);
2106 if (address_used)
2108 if (! ATTR_IND_SIMPLIFIED_P (exp))
2109 return copy_rtx_unchanging (exp);
2110 return exp;
2112 else
2113 return newexp;
2116 /* This routine is called when an AND of a term with a tree of AND's is
2117 encountered. If the term or its complement is present in the tree, it
2118 can be replaced with TRUE or FALSE, respectively.
2120 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2121 be true and hence are complementary.
2123 There is one special case: If we see
2124 (and (not (eq_attr "att" "v1"))
2125 (eq_attr "att" "v2"))
2126 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2127 replace the term, not anything in the AND tree. So we pass a pointer to
2128 the term. */
2130 static rtx
2131 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2133 rtx left, right;
2134 rtx newexp;
2135 rtx temp;
2136 int left_eliminates_term, right_eliminates_term;
2138 if (GET_CODE (exp) == AND)
2140 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2141 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2142 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2144 newexp = attr_rtx (AND, left, right);
2146 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2150 else if (GET_CODE (exp) == IOR)
2152 /* For the IOR case, we do the same as above, except that we can
2153 only eliminate `term' if both sides of the IOR would do so. */
2154 temp = *pterm;
2155 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2156 left_eliminates_term = (temp == true_rtx);
2158 temp = *pterm;
2159 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2160 right_eliminates_term = (temp == true_rtx);
2162 if (left_eliminates_term && right_eliminates_term)
2163 *pterm = true_rtx;
2165 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2167 newexp = attr_rtx (IOR, left, right);
2169 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2173 /* Check for simplifications. Do some extra checking here since this
2174 routine is called so many times. */
2176 if (exp == *pterm)
2177 return true_rtx;
2179 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2180 return false_rtx;
2182 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2183 return false_rtx;
2185 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2187 if (attr_alt_subset_p (*pterm, exp))
2188 return true_rtx;
2190 if (attr_alt_subset_of_compl_p (*pterm, exp))
2191 return false_rtx;
2193 if (attr_alt_subset_p (exp, *pterm))
2194 *pterm = true_rtx;
2196 return exp;
2199 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2201 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2202 return exp;
2204 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2205 return true_rtx;
2206 else
2207 return false_rtx;
2210 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2211 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2213 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2214 return exp;
2216 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2217 return false_rtx;
2218 else
2219 return true_rtx;
2222 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2223 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2225 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2226 return exp;
2228 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2229 return false_rtx;
2230 else
2231 *pterm = true_rtx;
2234 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2236 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2237 return true_rtx;
2240 else if (GET_CODE (exp) == NOT)
2242 if (attr_equal_p (XEXP (exp, 0), *pterm))
2243 return false_rtx;
2246 else if (GET_CODE (*pterm) == NOT)
2248 if (attr_equal_p (XEXP (*pterm, 0), exp))
2249 return false_rtx;
2252 else if (attr_equal_p (exp, *pterm))
2253 return true_rtx;
2255 return exp;
2258 /* Similar to `simplify_and_tree', but for IOR trees. */
2260 static rtx
2261 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2263 rtx left, right;
2264 rtx newexp;
2265 rtx temp;
2266 int left_eliminates_term, right_eliminates_term;
2268 if (GET_CODE (exp) == IOR)
2270 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2271 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2272 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2274 newexp = attr_rtx (GET_CODE (exp), left, right);
2276 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2280 else if (GET_CODE (exp) == AND)
2282 /* For the AND case, we do the same as above, except that we can
2283 only eliminate `term' if both sides of the AND would do so. */
2284 temp = *pterm;
2285 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2286 left_eliminates_term = (temp == false_rtx);
2288 temp = *pterm;
2289 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2290 right_eliminates_term = (temp == false_rtx);
2292 if (left_eliminates_term && right_eliminates_term)
2293 *pterm = false_rtx;
2295 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2297 newexp = attr_rtx (GET_CODE (exp), left, right);
2299 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2303 if (attr_equal_p (exp, *pterm))
2304 return false_rtx;
2306 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2307 return true_rtx;
2309 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2310 return true_rtx;
2312 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2313 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2314 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2315 *pterm = false_rtx;
2317 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2318 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2319 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2320 return false_rtx;
2322 return exp;
2325 /* Simplify test expression and use temporary obstack in order to avoid
2326 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2327 and avoid unnecessary copying if possible. */
2329 static rtx
2330 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2332 rtx x;
2333 struct obstack *old;
2334 if (ATTR_IND_SIMPLIFIED_P (exp))
2335 return exp;
2336 old = rtl_obstack;
2337 rtl_obstack = temp_obstack;
2338 x = simplify_test_exp (exp, insn_code, insn_index);
2339 rtl_obstack = old;
2340 if (x == exp || rtl_obstack == temp_obstack)
2341 return x;
2342 return attr_copy_rtx (x);
2345 /* Returns true if S1 is a subset of S2. */
2347 static bool
2348 attr_alt_subset_p (rtx s1, rtx s2)
2350 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2352 case (0 << 1) | 0:
2353 return !(XINT (s1, 0) &~ XINT (s2, 0));
2355 case (0 << 1) | 1:
2356 return !(XINT (s1, 0) & XINT (s2, 0));
2358 case (1 << 1) | 0:
2359 return false;
2361 case (1 << 1) | 1:
2362 return !(XINT (s2, 0) &~ XINT (s1, 0));
2364 default:
2365 gcc_unreachable ();
2369 /* Returns true if S1 is a subset of complement of S2. */
2371 static bool
2372 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2374 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2376 case (0 << 1) | 0:
2377 return !(XINT (s1, 0) & XINT (s2, 0));
2379 case (0 << 1) | 1:
2380 return !(XINT (s1, 0) & ~XINT (s2, 0));
2382 case (1 << 1) | 0:
2383 return !(XINT (s2, 0) &~ XINT (s1, 0));
2385 case (1 << 1) | 1:
2386 return false;
2388 default:
2389 gcc_unreachable ();
2393 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2395 static rtx
2396 attr_alt_intersection (rtx s1, rtx s2)
2398 rtx result = rtx_alloc (EQ_ATTR_ALT);
2400 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2402 case (0 << 1) | 0:
2403 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2404 break;
2405 case (0 << 1) | 1:
2406 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2407 break;
2408 case (1 << 1) | 0:
2409 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2410 break;
2411 case (1 << 1) | 1:
2412 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2413 break;
2414 default:
2415 gcc_unreachable ();
2417 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2419 return result;
2422 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2424 static rtx
2425 attr_alt_union (rtx s1, rtx s2)
2427 rtx result = rtx_alloc (EQ_ATTR_ALT);
2429 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2431 case (0 << 1) | 0:
2432 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2433 break;
2434 case (0 << 1) | 1:
2435 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2436 break;
2437 case (1 << 1) | 0:
2438 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2439 break;
2440 case (1 << 1) | 1:
2441 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2442 break;
2443 default:
2444 gcc_unreachable ();
2447 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2448 return result;
2451 /* Return EQ_ATTR_ALT expression representing complement of S. */
2453 static rtx
2454 attr_alt_complement (rtx s)
2456 rtx result = rtx_alloc (EQ_ATTR_ALT);
2458 XINT (result, 0) = XINT (s, 0);
2459 XINT (result, 1) = 1 - XINT (s, 1);
2461 return result;
2464 /* Return EQ_ATTR_ALT expression representing set containing elements set
2465 in E. */
2467 static rtx
2468 mk_attr_alt (uint64_t e)
2470 rtx result = rtx_alloc (EQ_ATTR_ALT);
2472 XINT (result, 0) = e;
2473 XINT (result, 1) = 0;
2475 return result;
2478 /* Given an expression, see if it can be simplified for a particular insn
2479 code based on the values of other attributes being tested. This can
2480 eliminate nested get_attr_... calls.
2482 Note that if an endless recursion is specified in the patterns, the
2483 optimization will loop. However, it will do so in precisely the cases where
2484 an infinite recursion loop could occur during compilation. It's better that
2485 it occurs here! */
2487 static rtx
2488 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2490 rtx left, right;
2491 struct attr_desc *attr;
2492 struct attr_value *av;
2493 struct insn_ent *ie;
2494 struct attr_value_list *iv;
2495 uint64_t i;
2496 rtx newexp = exp;
2497 bool left_alt, right_alt;
2499 /* Don't re-simplify something we already simplified. */
2500 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2501 return exp;
2503 switch (GET_CODE (exp))
2505 case AND:
2506 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2507 if (left == false_rtx)
2508 return false_rtx;
2509 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2510 if (right == false_rtx)
2511 return false_rtx;
2513 if (GET_CODE (left) == EQ_ATTR_ALT
2514 && GET_CODE (right) == EQ_ATTR_ALT)
2516 exp = attr_alt_intersection (left, right);
2517 return simplify_test_exp (exp, insn_code, insn_index);
2520 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2521 present on both sides, apply the distributive law since this will
2522 yield simplifications. */
2523 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2524 && compute_alternative_mask (left, IOR)
2525 && compute_alternative_mask (right, IOR))
2527 if (GET_CODE (left) == IOR)
2528 std::swap (left, right);
2530 newexp = attr_rtx (IOR,
2531 attr_rtx (AND, left, XEXP (right, 0)),
2532 attr_rtx (AND, left, XEXP (right, 1)));
2534 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2537 /* Try with the term on both sides. */
2538 right = simplify_and_tree (right, &left, insn_code, insn_index);
2539 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2540 left = simplify_and_tree (left, &right, insn_code, insn_index);
2542 if (left == false_rtx || right == false_rtx)
2543 return false_rtx;
2544 else if (left == true_rtx)
2546 return right;
2548 else if (right == true_rtx)
2550 return left;
2552 /* See if all or all but one of the insn's alternatives are specified
2553 in this tree. Optimize if so. */
2555 if (GET_CODE (left) == NOT)
2556 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2557 && XSTR (XEXP (left, 0), 0) == alternative_name);
2558 else
2559 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2560 && XINT (left, 1));
2562 if (GET_CODE (right) == NOT)
2563 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2564 && XSTR (XEXP (right, 0), 0) == alternative_name);
2565 else
2566 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2567 && XINT (right, 1));
2569 if (insn_code >= 0
2570 && (GET_CODE (left) == AND
2571 || left_alt
2572 || GET_CODE (right) == AND
2573 || right_alt))
2575 i = compute_alternative_mask (exp, AND);
2576 if (i & ~insn_alternatives[insn_code])
2577 fatal ("invalid alternative specified for pattern number %d",
2578 insn_index);
2580 /* If all alternatives are excluded, this is false. */
2581 i ^= insn_alternatives[insn_code];
2582 if (i == 0)
2583 return false_rtx;
2584 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2586 /* If just one excluded, AND a comparison with that one to the
2587 front of the tree. The others will be eliminated by
2588 optimization. We do not want to do this if the insn has one
2589 alternative and we have tested none of them! */
2590 left = make_alternative_compare (i);
2591 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2592 newexp = attr_rtx (AND, left, right);
2594 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2598 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2600 newexp = attr_rtx (AND, left, right);
2601 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2603 break;
2605 case IOR:
2606 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2607 if (left == true_rtx)
2608 return true_rtx;
2609 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2610 if (right == true_rtx)
2611 return true_rtx;
2613 if (GET_CODE (left) == EQ_ATTR_ALT
2614 && GET_CODE (right) == EQ_ATTR_ALT)
2616 exp = attr_alt_union (left, right);
2617 return simplify_test_exp (exp, insn_code, insn_index);
2620 right = simplify_or_tree (right, &left, insn_code, insn_index);
2621 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2622 left = simplify_or_tree (left, &right, insn_code, insn_index);
2624 if (right == true_rtx || left == true_rtx)
2625 return true_rtx;
2626 else if (left == false_rtx)
2628 return right;
2630 else if (right == false_rtx)
2632 return left;
2635 /* Test for simple cases where the distributive law is useful. I.e.,
2636 convert (ior (and (x) (y))
2637 (and (x) (z)))
2638 to (and (x)
2639 (ior (y) (z)))
2642 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2643 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2645 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2647 left = XEXP (left, 0);
2648 right = newexp;
2649 newexp = attr_rtx (AND, left, right);
2650 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2653 /* Similarly,
2654 convert (ior (and (y) (x))
2655 (and (z) (x)))
2656 to (and (ior (y) (z))
2657 (x))
2658 Note that we want the common term to stay at the end.
2661 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2662 && attr_equal_p (XEXP (left, 1), XEXP (right, 1)))
2664 newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0));
2666 left = newexp;
2667 right = XEXP (right, 1);
2668 newexp = attr_rtx (AND, left, right);
2669 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2672 /* See if all or all but one of the insn's alternatives are specified
2673 in this tree. Optimize if so. */
2675 else if (insn_code >= 0
2676 && (GET_CODE (left) == IOR
2677 || (GET_CODE (left) == EQ_ATTR_ALT
2678 && !XINT (left, 1))
2679 || (GET_CODE (left) == EQ_ATTR
2680 && XSTR (left, 0) == alternative_name)
2681 || GET_CODE (right) == IOR
2682 || (GET_CODE (right) == EQ_ATTR_ALT
2683 && !XINT (right, 1))
2684 || (GET_CODE (right) == EQ_ATTR
2685 && XSTR (right, 0) == alternative_name)))
2687 i = compute_alternative_mask (exp, IOR);
2688 if (i & ~insn_alternatives[insn_code])
2689 fatal ("invalid alternative specified for pattern number %d",
2690 insn_index);
2692 /* If all alternatives are included, this is true. */
2693 i ^= insn_alternatives[insn_code];
2694 if (i == 0)
2695 return true_rtx;
2696 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2698 /* If just one excluded, IOR a comparison with that one to the
2699 front of the tree. The others will be eliminated by
2700 optimization. We do not want to do this if the insn has one
2701 alternative and we have tested none of them! */
2702 left = make_alternative_compare (i);
2703 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2704 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2706 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2710 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2712 newexp = attr_rtx (IOR, left, right);
2713 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2715 break;
2717 case NOT:
2718 if (GET_CODE (XEXP (exp, 0)) == NOT)
2720 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2721 insn_code, insn_index);
2722 return left;
2725 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2726 if (GET_CODE (left) == NOT)
2727 return XEXP (left, 0);
2729 if (left == false_rtx)
2730 return true_rtx;
2731 if (left == true_rtx)
2732 return false_rtx;
2734 if (GET_CODE (left) == EQ_ATTR_ALT)
2736 exp = attr_alt_complement (left);
2737 return simplify_test_exp (exp, insn_code, insn_index);
2740 /* Try to apply De`Morgan's laws. */
2741 if (GET_CODE (left) == IOR)
2743 newexp = attr_rtx (AND,
2744 attr_rtx (NOT, XEXP (left, 0)),
2745 attr_rtx (NOT, XEXP (left, 1)));
2747 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2749 else if (GET_CODE (left) == AND)
2751 newexp = attr_rtx (IOR,
2752 attr_rtx (NOT, XEXP (left, 0)),
2753 attr_rtx (NOT, XEXP (left, 1)));
2755 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2757 else if (left != XEXP (exp, 0))
2759 newexp = attr_rtx (NOT, left);
2761 break;
2763 case EQ_ATTR_ALT:
2764 if (!XINT (exp, 0))
2765 return XINT (exp, 1) ? true_rtx : false_rtx;
2766 break;
2768 case EQ_ATTR:
2769 if (XSTR (exp, 0) == alternative_name)
2771 newexp = mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1)));
2772 break;
2775 /* Look at the value for this insn code in the specified attribute.
2776 We normally can replace this comparison with the condition that
2777 would give this insn the values being tested for. */
2778 if (insn_code >= 0
2779 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2781 rtx x;
2783 av = NULL;
2784 if (insn_code_values)
2786 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2787 if (iv->attr == attr)
2789 av = iv->av;
2790 break;
2793 else
2795 for (av = attr->first_value; av; av = av->next)
2796 for (ie = av->first_insn; ie; ie = ie->next)
2797 if (ie->def->insn_code == insn_code)
2798 goto got_av;
2801 if (av)
2803 got_av:
2804 x = evaluate_eq_attr (exp, attr, av->value,
2805 insn_code, insn_index);
2806 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2807 if (attr_rtx_cost (x) < 7)
2808 return x;
2811 break;
2813 default:
2814 break;
2817 /* We have already simplified this expression. Simplifying it again
2818 won't buy anything unless we weren't given a valid insn code
2819 to process (i.e., we are canonicalizing something.). */
2820 if (insn_code != -2
2821 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2822 return copy_rtx_unchanging (newexp);
2824 return newexp;
2827 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2828 otherwise return 0. */
2830 static int
2831 tests_attr_p (rtx p, struct attr_desc *attr)
2833 const char *fmt;
2834 int i, ie, j, je;
2836 if (GET_CODE (p) == EQ_ATTR)
2838 if (XSTR (p, 0) != attr->name)
2839 return 0;
2840 return 1;
2843 fmt = GET_RTX_FORMAT (GET_CODE (p));
2844 ie = GET_RTX_LENGTH (GET_CODE (p));
2845 for (i = 0; i < ie; i++)
2847 switch (*fmt++)
2849 case 'e':
2850 if (tests_attr_p (XEXP (p, i), attr))
2851 return 1;
2852 break;
2854 case 'E':
2855 je = XVECLEN (p, i);
2856 for (j = 0; j < je; ++j)
2857 if (tests_attr_p (XVECEXP (p, i, j), attr))
2858 return 1;
2859 break;
2863 return 0;
2866 /* Calculate a topological sorting of all attributes so that
2867 all attributes only depend on attributes in front of it.
2868 Place the result in *RET (which is a pointer to an array of
2869 attr_desc pointers), and return the size of that array. */
2871 static int
2872 get_attr_order (struct attr_desc ***ret)
2874 int i, j;
2875 int num = 0;
2876 struct attr_desc *attr;
2877 struct attr_desc **all, **sorted;
2878 char *handled;
2879 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2880 for (attr = attrs[i]; attr; attr = attr->next)
2881 num++;
2882 all = XNEWVEC (struct attr_desc *, num);
2883 sorted = XNEWVEC (struct attr_desc *, num);
2884 handled = XCNEWVEC (char, num);
2885 num = 0;
2886 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2887 for (attr = attrs[i]; attr; attr = attr->next)
2888 all[num++] = attr;
2890 j = 0;
2891 for (i = 0; i < num; i++)
2892 if (all[i]->is_const)
2893 handled[i] = 1, sorted[j++] = all[i];
2895 /* We have only few attributes hence we can live with the inner
2896 loop being O(n^2), unlike the normal fast variants of topological
2897 sorting. */
2898 while (j < num)
2900 for (i = 0; i < num; i++)
2901 if (!handled[i])
2903 /* Let's see if I depends on anything interesting. */
2904 int k;
2905 for (k = 0; k < num; k++)
2906 if (!handled[k])
2908 struct attr_value *av;
2909 for (av = all[i]->first_value; av; av = av->next)
2910 if (av->num_insns != 0)
2911 if (tests_attr_p (av->value, all[k]))
2912 break;
2914 if (av)
2915 /* Something in I depends on K. */
2916 break;
2918 if (k == num)
2920 /* Nothing in I depended on anything intersting, so
2921 it's done. */
2922 handled[i] = 1;
2923 sorted[j++] = all[i];
2928 if (DEBUG)
2929 for (j = 0; j < num; j++)
2931 struct attr_desc *attr2;
2932 struct attr_value *av;
2934 attr = sorted[j];
2935 fprintf (stderr, "%s depends on: ", attr->name);
2936 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
2937 for (attr2 = attrs[i]; attr2; attr2 = attr2->next)
2938 if (!attr2->is_const)
2939 for (av = attr->first_value; av; av = av->next)
2940 if (av->num_insns != 0)
2941 if (tests_attr_p (av->value, attr2))
2943 fprintf (stderr, "%s, ", attr2->name);
2944 break;
2946 fprintf (stderr, "\n");
2949 free (all);
2950 *ret = sorted;
2951 return num;
2954 /* Optimize the attribute lists by seeing if we can determine conditional
2955 values from the known values of other attributes. This will save subroutine
2956 calls during the compilation. NUM_INSN_CODES is the number of unique
2957 instruction codes. */
2959 static void
2960 optimize_attrs (int num_insn_codes)
2962 struct attr_desc *attr;
2963 struct attr_value *av;
2964 struct insn_ent *ie;
2965 rtx newexp;
2966 int i;
2967 struct attr_value_list *ivbuf;
2968 struct attr_value_list *iv;
2969 struct attr_desc **topsort;
2970 int topnum;
2972 /* For each insn code, make a list of all the insn_ent's for it,
2973 for all values for all attributes. */
2975 if (num_insn_ents == 0)
2976 return;
2978 /* Make 2 extra elements, for "code" values -2 and -1. */
2979 insn_code_values = XCNEWVEC (struct attr_value_list *, num_insn_codes + 2);
2981 /* Offset the table address so we can index by -2 or -1. */
2982 insn_code_values += 2;
2984 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2986 /* Create the chain of insn*attr values such that we see dependend
2987 attributes after their dependencies. As we use a stack via the
2988 next pointers start from the end of the topological order. */
2989 topnum = get_attr_order (&topsort);
2990 for (i = topnum - 1; i >= 0; i--)
2991 for (av = topsort[i]->first_value; av; av = av->next)
2992 for (ie = av->first_insn; ie; ie = ie->next)
2994 iv->attr = topsort[i];
2995 iv->av = av;
2996 iv->ie = ie;
2997 iv->next = insn_code_values[ie->def->insn_code];
2998 insn_code_values[ie->def->insn_code] = iv;
2999 iv++;
3001 free (topsort);
3003 /* Sanity check on num_insn_ents. */
3004 gcc_assert (iv == ivbuf + num_insn_ents);
3006 /* Process one insn code at a time. */
3007 for (i = -2; i < num_insn_codes; i++)
3009 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3010 We use it to mean "already simplified for this insn". */
3011 for (iv = insn_code_values[i]; iv; iv = iv->next)
3012 clear_struct_flag (iv->av->value);
3014 for (iv = insn_code_values[i]; iv; iv = iv->next)
3016 struct obstack *old = rtl_obstack;
3018 attr = iv->attr;
3019 av = iv->av;
3020 ie = iv->ie;
3021 if (GET_CODE (av->value) != COND)
3022 continue;
3024 rtl_obstack = temp_obstack;
3025 newexp = av->value;
3026 while (GET_CODE (newexp) == COND)
3028 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
3029 ie->def->insn_index);
3030 if (newexp2 == newexp)
3031 break;
3032 newexp = newexp2;
3035 rtl_obstack = old;
3036 /* If we created a new value for this instruction, and it's
3037 cheaper than the old value, and overall cheap, use that
3038 one as specific value for the current instruction.
3039 The last test is to avoid exploding the get_attr_ function
3040 sizes for no much gain. */
3041 if (newexp != av->value
3042 && attr_rtx_cost (newexp) < attr_rtx_cost (av->value)
3043 && attr_rtx_cost (newexp) < 26
3046 newexp = attr_copy_rtx (newexp);
3047 remove_insn_ent (av, ie);
3048 av = get_attr_value (ie->def->loc, newexp, attr,
3049 ie->def->insn_code);
3050 iv->av = av;
3051 insert_insn_ent (av, ie);
3056 free (ivbuf);
3057 free (insn_code_values - 2);
3058 insn_code_values = NULL;
3061 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3063 static void
3064 clear_struct_flag (rtx x)
3066 int i;
3067 int j;
3068 enum rtx_code code;
3069 const char *fmt;
3071 ATTR_CURR_SIMPLIFIED_P (x) = 0;
3072 if (ATTR_IND_SIMPLIFIED_P (x))
3073 return;
3075 code = GET_CODE (x);
3077 switch (code)
3079 case REG:
3080 CASE_CONST_ANY:
3081 case MATCH_TEST:
3082 case SYMBOL_REF:
3083 case CODE_LABEL:
3084 case PC:
3085 case CC0:
3086 case EQ_ATTR:
3087 case ATTR_FLAG:
3088 return;
3090 default:
3091 break;
3094 /* Compare the elements. If any pair of corresponding elements
3095 fail to match, return 0 for the whole things. */
3097 fmt = GET_RTX_FORMAT (code);
3098 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3100 switch (fmt[i])
3102 case 'V':
3103 case 'E':
3104 for (j = 0; j < XVECLEN (x, i); j++)
3105 clear_struct_flag (XVECEXP (x, i, j));
3106 break;
3108 case 'e':
3109 clear_struct_flag (XEXP (x, i));
3110 break;
3115 /* Add attribute value NAME to the beginning of ATTR's list. */
3117 static void
3118 add_attr_value (struct attr_desc *attr, const char *name)
3120 struct attr_value *av;
3122 av = oballoc (struct attr_value);
3123 av->value = attr_rtx (CONST_STRING, name);
3124 av->next = attr->first_value;
3125 attr->first_value = av;
3126 av->first_insn = NULL;
3127 av->num_insns = 0;
3128 av->has_asm_insn = 0;
3131 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3133 static void
3134 gen_attr (md_rtx_info *info)
3136 struct enum_type *et;
3137 struct enum_value *ev;
3138 struct attr_desc *attr;
3139 const char *name_ptr;
3140 char *p;
3141 rtx def = info->def;
3143 /* Make a new attribute structure. Check for duplicate by looking at
3144 attr->default_val, since it is initialized by this routine. */
3145 attr = find_attr (&XSTR (def, 0), 1);
3146 if (attr->default_val)
3148 error_at (info->loc, "duplicate definition for attribute %s",
3149 attr->name);
3150 message_at (attr->loc, "previous definition");
3151 return;
3153 attr->loc = info->loc;
3155 if (GET_CODE (def) == DEFINE_ENUM_ATTR)
3157 attr->enum_name = XSTR (def, 1);
3158 et = lookup_enum_type (XSTR (def, 1));
3159 if (!et || !et->md_p)
3160 error_at (info->loc, "No define_enum called `%s' defined",
3161 attr->name);
3162 if (et)
3163 for (ev = et->values; ev; ev = ev->next)
3164 add_attr_value (attr, ev->name);
3166 else if (*XSTR (def, 1) == '\0')
3167 attr->is_numeric = 1;
3168 else
3170 name_ptr = XSTR (def, 1);
3171 while ((p = next_comma_elt (&name_ptr)) != NULL)
3172 add_attr_value (attr, p);
3175 if (GET_CODE (XEXP (def, 2)) == CONST)
3177 attr->is_const = 1;
3178 if (attr->is_numeric)
3179 error_at (info->loc,
3180 "constant attributes may not take numeric values");
3182 /* Get rid of the CONST node. It is allowed only at top-level. */
3183 XEXP (def, 2) = XEXP (XEXP (def, 2), 0);
3186 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3187 error_at (info->loc, "`length' attribute must take numeric values");
3189 /* Set up the default value. */
3190 XEXP (def, 2) = check_attr_value (info->loc, XEXP (def, 2), attr);
3191 attr->default_val = get_attr_value (info->loc, XEXP (def, 2), attr, -2);
3194 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3195 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3196 number of alternatives as this should be checked elsewhere. */
3198 static int
3199 count_alternatives (rtx exp)
3201 int i, j, n;
3202 const char *fmt;
3204 if (GET_CODE (exp) == MATCH_OPERAND)
3205 return n_comma_elts (XSTR (exp, 2));
3207 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3208 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3209 switch (*fmt++)
3211 case 'e':
3212 case 'u':
3213 n = count_alternatives (XEXP (exp, i));
3214 if (n)
3215 return n;
3216 break;
3218 case 'E':
3219 case 'V':
3220 if (XVEC (exp, i) != NULL)
3221 for (j = 0; j < XVECLEN (exp, i); j++)
3223 n = count_alternatives (XVECEXP (exp, i, j));
3224 if (n)
3225 return n;
3229 return 0;
3232 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3233 `alternative' attribute. */
3235 static int
3236 compares_alternatives_p (rtx exp)
3238 int i, j;
3239 const char *fmt;
3241 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3242 return 1;
3244 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3245 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3246 switch (*fmt++)
3248 case 'e':
3249 case 'u':
3250 if (compares_alternatives_p (XEXP (exp, i)))
3251 return 1;
3252 break;
3254 case 'E':
3255 for (j = 0; j < XVECLEN (exp, i); j++)
3256 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3257 return 1;
3258 break;
3261 return 0;
3264 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3266 static void
3267 gen_insn (md_rtx_info *info)
3269 struct insn_def *id;
3270 rtx def = info->def;
3272 id = oballoc (struct insn_def);
3273 id->next = defs;
3274 defs = id;
3275 id->def = def;
3276 id->loc = info->loc;
3278 switch (GET_CODE (def))
3280 case DEFINE_INSN:
3281 id->insn_code = info->index;
3282 id->insn_index = insn_index_number;
3283 id->num_alternatives = count_alternatives (def);
3284 if (id->num_alternatives == 0)
3285 id->num_alternatives = 1;
3286 id->vec_idx = 4;
3287 break;
3289 case DEFINE_PEEPHOLE:
3290 id->insn_code = info->index;
3291 id->insn_index = insn_index_number;
3292 id->num_alternatives = count_alternatives (def);
3293 if (id->num_alternatives == 0)
3294 id->num_alternatives = 1;
3295 id->vec_idx = 3;
3296 break;
3298 case DEFINE_ASM_ATTRIBUTES:
3299 id->insn_code = -1;
3300 id->insn_index = -1;
3301 id->num_alternatives = 1;
3302 id->vec_idx = 0;
3303 got_define_asm_attributes = 1;
3304 break;
3306 default:
3307 gcc_unreachable ();
3311 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3312 true or annul false is specified, and make a `struct delay_desc'. */
3314 static void
3315 gen_delay (md_rtx_info *info)
3317 struct delay_desc *delay;
3318 int i;
3320 rtx def = info->def;
3321 if (XVECLEN (def, 1) % 3 != 0)
3323 error_at (info->loc, "number of elements in DEFINE_DELAY must"
3324 " be multiple of three");
3325 return;
3328 for (i = 0; i < XVECLEN (def, 1); i += 3)
3330 if (XVECEXP (def, 1, i + 1))
3331 have_annul_true = 1;
3332 if (XVECEXP (def, 1, i + 2))
3333 have_annul_false = 1;
3336 delay = oballoc (struct delay_desc);
3337 delay->def = def;
3338 delay->num = ++num_delays;
3339 delay->next = delays;
3340 delay->loc = info->loc;
3341 delays = delay;
3344 /* Names of attributes that could be possibly cached. */
3345 static const char *cached_attrs[32];
3346 /* Number of such attributes. */
3347 static int cached_attr_count;
3348 /* Bitmasks of possibly cached attributes. */
3349 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3350 static unsigned int attrs_to_cache;
3351 static unsigned int attrs_cached_inside, attrs_cached_after;
3353 /* Finds non-const attributes that could be possibly cached.
3354 When create is TRUE, fills in cached_attrs array.
3355 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3356 bitmasks. */
3358 static void
3359 find_attrs_to_cache (rtx exp, bool create)
3361 int i;
3362 const char *name;
3363 struct attr_desc *attr;
3365 if (exp == NULL)
3366 return;
3368 switch (GET_CODE (exp))
3370 case NOT:
3371 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3372 find_attrs_to_cache (XEXP (exp, 0), create);
3373 return;
3375 case EQ_ATTR:
3376 name = XSTR (exp, 0);
3377 if (name == alternative_name)
3378 return;
3379 for (i = 0; i < cached_attr_count; i++)
3380 if (name == cached_attrs[i])
3382 if ((attrs_seen_once & (1U << i)) != 0)
3383 attrs_seen_more_than_once |= (1U << i);
3384 else
3385 attrs_seen_once |= (1U << i);
3386 return;
3388 if (!create)
3389 return;
3390 attr = find_attr (&name, 0);
3391 gcc_assert (attr);
3392 if (attr->is_const)
3393 return;
3394 if (cached_attr_count == 32)
3395 return;
3396 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3397 attrs_seen_once |= (1U << cached_attr_count);
3398 cached_attr_count++;
3399 return;
3401 case AND:
3402 case IOR:
3403 find_attrs_to_cache (XEXP (exp, 0), create);
3404 find_attrs_to_cache (XEXP (exp, 1), create);
3405 return;
3407 case COND:
3408 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3409 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3410 return;
3412 default:
3413 return;
3417 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3418 We use AND and IOR both for logical and bit-wise operations, so
3419 interpret them as logical unless they are inside a comparison expression. */
3421 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3422 #define FLG_BITWISE 1
3423 /* Set if cached attribute will be known initialized in else block after
3424 this condition. This is true for LHS of toplevel && and || and
3425 even for RHS of ||, but not for RHS of &&. */
3426 #define FLG_AFTER 2
3427 /* Set if cached attribute will be known initialized in then block after
3428 this condition. This is true for LHS of toplevel && and || and
3429 even for RHS of &&, but not for RHS of ||. */
3430 #define FLG_INSIDE 4
3431 /* Cleared when an operand of &&. */
3432 #define FLG_OUTSIDE_AND 8
3434 static unsigned int
3435 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags)
3437 int comparison_operator = 0;
3438 RTX_CODE code;
3439 struct attr_desc *attr;
3441 /* In order not to worry about operator precedence, surround our part of
3442 the expression with parentheses. */
3444 fprintf (outf, "(");
3445 code = GET_CODE (exp);
3446 switch (code)
3448 /* Binary operators. */
3449 case GEU: case GTU:
3450 case LEU: case LTU:
3451 fprintf (outf, "(unsigned) ");
3452 /* Fall through. */
3454 case EQ: case NE:
3455 case GE: case GT:
3456 case LE: case LT:
3457 comparison_operator = FLG_BITWISE;
3459 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3460 case AND: case IOR: case XOR:
3461 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3462 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3464 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3465 write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3466 flags | comparison_operator);
3468 else
3470 if (code == AND)
3471 flags &= ~FLG_OUTSIDE_AND;
3472 if (GET_CODE (XEXP (exp, 0)) == code
3473 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3474 || (GET_CODE (XEXP (exp, 0)) == NOT
3475 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3476 attrs_cached
3477 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3478 else
3479 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3481 switch (code)
3483 case EQ:
3484 fprintf (outf, " == ");
3485 break;
3486 case NE:
3487 fprintf (outf, " != ");
3488 break;
3489 case GE:
3490 fprintf (outf, " >= ");
3491 break;
3492 case GT:
3493 fprintf (outf, " > ");
3494 break;
3495 case GEU:
3496 fprintf (outf, " >= (unsigned) ");
3497 break;
3498 case GTU:
3499 fprintf (outf, " > (unsigned) ");
3500 break;
3501 case LE:
3502 fprintf (outf, " <= ");
3503 break;
3504 case LT:
3505 fprintf (outf, " < ");
3506 break;
3507 case LEU:
3508 fprintf (outf, " <= (unsigned) ");
3509 break;
3510 case LTU:
3511 fprintf (outf, " < (unsigned) ");
3512 break;
3513 case PLUS:
3514 fprintf (outf, " + ");
3515 break;
3516 case MINUS:
3517 fprintf (outf, " - ");
3518 break;
3519 case MULT:
3520 fprintf (outf, " * ");
3521 break;
3522 case DIV:
3523 fprintf (outf, " / ");
3524 break;
3525 case MOD:
3526 fprintf (outf, " %% ");
3527 break;
3528 case AND:
3529 if (flags & FLG_BITWISE)
3530 fprintf (outf, " & ");
3531 else
3532 fprintf (outf, " && ");
3533 break;
3534 case IOR:
3535 if (flags & FLG_BITWISE)
3536 fprintf (outf, " | ");
3537 else
3538 fprintf (outf, " || ");
3539 break;
3540 case XOR:
3541 fprintf (outf, " ^ ");
3542 break;
3543 case ASHIFT:
3544 fprintf (outf, " << ");
3545 break;
3546 case LSHIFTRT:
3547 case ASHIFTRT:
3548 fprintf (outf, " >> ");
3549 break;
3550 default:
3551 gcc_unreachable ();
3554 if (code == AND)
3556 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3557 cached_x is only known to be initialized in then block. */
3558 flags &= ~FLG_AFTER;
3560 else if (code == IOR)
3562 if (flags & FLG_OUTSIDE_AND)
3563 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3564 cached_x is only known to be initialized in else block
3565 and else if conditions. */
3566 flags &= ~FLG_INSIDE;
3567 else
3568 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3569 && something_else)
3570 cached_x is not know to be initialized anywhere. */
3571 flags &= ~(FLG_AFTER | FLG_INSIDE);
3573 if ((code == AND || code == IOR)
3574 && (GET_CODE (XEXP (exp, 1)) == code
3575 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3576 || (GET_CODE (XEXP (exp, 1)) == NOT
3577 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3578 attrs_cached
3579 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags);
3580 else
3581 write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3582 flags | comparison_operator);
3583 break;
3585 case NOT:
3586 /* Special-case (not (eq_attrq "alternative" "x")) */
3587 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3589 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3591 fprintf (outf, "which_alternative != %s",
3592 XSTR (XEXP (exp, 0), 1));
3593 break;
3596 fprintf (outf, "! ");
3597 attrs_cached =
3598 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3599 break;
3602 /* Otherwise, fall through to normal unary operator. */
3604 /* Unary operators. */
3605 case ABS: case NEG:
3606 switch (code)
3608 case NOT:
3609 if (flags & FLG_BITWISE)
3610 fprintf (outf, "~ ");
3611 else
3612 fprintf (outf, "! ");
3613 break;
3614 case ABS:
3615 fprintf (outf, "abs ");
3616 break;
3617 case NEG:
3618 fprintf (outf, "-");
3619 break;
3620 default:
3621 gcc_unreachable ();
3624 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3625 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3626 break;
3628 case EQ_ATTR_ALT:
3630 int set = XINT (exp, 0), bit = 0;
3632 if (flags & FLG_BITWISE)
3633 fatal ("EQ_ATTR_ALT not valid inside comparison");
3635 if (!set)
3636 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3638 if (!(set & (set - 1)))
3640 if (!(set & 0xffff))
3642 bit += 16;
3643 set >>= 16;
3645 if (!(set & 0xff))
3647 bit += 8;
3648 set >>= 8;
3650 if (!(set & 0xf))
3652 bit += 4;
3653 set >>= 4;
3655 if (!(set & 0x3))
3657 bit += 2;
3658 set >>= 2;
3660 if (!(set & 1))
3661 bit++;
3663 fprintf (outf, "which_alternative %s= %d",
3664 XINT (exp, 1) ? "!" : "=", bit);
3666 else
3668 fprintf (outf, "%s((1 << which_alternative) & %#x)",
3669 XINT (exp, 1) ? "!" : "", set);
3672 break;
3674 /* Comparison test of an attribute with a value. Most of these will
3675 have been removed by optimization. Handle "alternative"
3676 specially and give error if EQ_ATTR present inside a comparison. */
3677 case EQ_ATTR:
3678 if (flags & FLG_BITWISE)
3679 fatal ("EQ_ATTR not valid inside comparison");
3681 if (XSTR (exp, 0) == alternative_name)
3683 fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3684 break;
3687 attr = find_attr (&XSTR (exp, 0), 0);
3688 gcc_assert (attr);
3690 /* Now is the time to expand the value of a constant attribute. */
3691 if (attr->is_const)
3693 write_test_expr (outf,
3694 evaluate_eq_attr (exp, attr,
3695 attr->default_val->value,
3696 -2, -2),
3697 attrs_cached, 0);
3699 else
3701 int i;
3702 for (i = 0; i < cached_attr_count; i++)
3703 if (attr->name == cached_attrs[i])
3704 break;
3705 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3706 fprintf (outf, "cached_%s", attr->name);
3707 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3709 fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3710 attr->name, attr->name);
3711 if (flags & FLG_AFTER)
3712 attrs_cached_after |= (1U << i);
3713 if (flags & FLG_INSIDE)
3714 attrs_cached_inside |= (1U << i);
3715 attrs_cached |= (1U << i);
3717 else
3718 fprintf (outf, "get_attr_%s (insn)", attr->name);
3719 fprintf (outf, " == ");
3720 write_attr_valueq (outf, attr, XSTR (exp, 1));
3722 break;
3724 /* Comparison test of flags for define_delays. */
3725 case ATTR_FLAG:
3726 if (flags & FLG_BITWISE)
3727 fatal ("ATTR_FLAG not valid inside comparison");
3728 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3729 break;
3731 /* See if an operand matches a predicate. */
3732 case MATCH_OPERAND:
3733 /* If only a mode is given, just ensure the mode matches the operand.
3734 If neither a mode nor predicate is given, error. */
3735 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3737 if (GET_MODE (exp) == VOIDmode)
3738 fatal ("null MATCH_OPERAND specified as test");
3739 else
3740 fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3741 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3743 else
3744 fprintf (outf, "%s (operands[%d], %smode)",
3745 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3746 break;
3748 /* Constant integer. */
3749 case CONST_INT:
3750 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3751 break;
3753 case MATCH_TEST:
3754 fprint_c_condition (outf, XSTR (exp, 0));
3755 if (flags & FLG_BITWISE)
3756 fprintf (outf, " != 0");
3757 break;
3759 /* A random C expression. */
3760 case SYMBOL_REF:
3761 fprint_c_condition (outf, XSTR (exp, 0));
3762 break;
3764 /* The address of the branch target. */
3765 case MATCH_DUP:
3766 fprintf (outf,
3767 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3768 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3769 break;
3771 case PC:
3772 /* The address of the current insn. We implement this actually as the
3773 address of the current insn for backward branches, but the last
3774 address of the next insn for forward branches, and both with
3775 adjustments that account for the worst-case possible stretching of
3776 intervening alignments between this insn and its destination. */
3777 fprintf (outf, "insn_current_reference_address (insn)");
3778 break;
3780 case CONST_STRING:
3781 fprintf (outf, "%s", XSTR (exp, 0));
3782 break;
3784 case IF_THEN_ELSE:
3785 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3786 fprintf (outf, " ? ");
3787 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3788 fprintf (outf, " : ");
3789 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3790 break;
3792 default:
3793 fatal ("bad RTX code `%s' in attribute calculation\n",
3794 GET_RTX_NAME (code));
3797 fprintf (outf, ")");
3798 return attrs_cached;
3801 /* Given an attribute value, return the maximum CONST_STRING argument
3802 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3804 static int
3805 max_attr_value (rtx exp, int *unknownp)
3807 int current_max;
3808 int i, n;
3810 switch (GET_CODE (exp))
3812 case CONST_STRING:
3813 current_max = atoi (XSTR (exp, 0));
3814 break;
3816 case COND:
3817 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3818 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3820 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3821 if (n > current_max)
3822 current_max = n;
3824 break;
3826 case IF_THEN_ELSE:
3827 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3828 n = max_attr_value (XEXP (exp, 2), unknownp);
3829 if (n > current_max)
3830 current_max = n;
3831 break;
3833 default:
3834 *unknownp = 1;
3835 current_max = INT_MAX;
3836 break;
3839 return current_max;
3842 /* Given an attribute value, return the minimum CONST_STRING argument
3843 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3845 static int
3846 min_attr_value (rtx exp, int *unknownp)
3848 int current_min;
3849 int i, n;
3851 switch (GET_CODE (exp))
3853 case CONST_STRING:
3854 current_min = atoi (XSTR (exp, 0));
3855 break;
3857 case COND:
3858 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3859 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3861 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3862 if (n < current_min)
3863 current_min = n;
3865 break;
3867 case IF_THEN_ELSE:
3868 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3869 n = min_attr_value (XEXP (exp, 2), unknownp);
3870 if (n < current_min)
3871 current_min = n;
3872 break;
3874 default:
3875 *unknownp = 1;
3876 current_min = INT_MAX;
3877 break;
3880 return current_min;
3883 /* Given an attribute value, return the result of ORing together all
3884 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3885 if the numeric value is not known. */
3887 static int
3888 or_attr_value (rtx exp, int *unknownp)
3890 int current_or;
3891 int i;
3893 switch (GET_CODE (exp))
3895 case CONST_STRING:
3896 current_or = atoi (XSTR (exp, 0));
3897 break;
3899 case COND:
3900 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3901 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3902 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3903 break;
3905 case IF_THEN_ELSE:
3906 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3907 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3908 break;
3910 default:
3911 *unknownp = 1;
3912 current_or = -1;
3913 break;
3916 return current_or;
3919 /* Scan an attribute value, possibly a conditional, and record what actions
3920 will be required to do any conditional tests in it.
3922 Specifically, set
3923 `must_extract' if we need to extract the insn operands
3924 `must_constrain' if we must compute `which_alternative'
3925 `address_used' if an address expression was used
3926 `length_used' if an (eq_attr "length" ...) was used
3929 static void
3930 walk_attr_value (rtx exp)
3932 int i, j;
3933 const char *fmt;
3934 RTX_CODE code;
3936 if (exp == NULL)
3937 return;
3939 code = GET_CODE (exp);
3940 switch (code)
3942 case SYMBOL_REF:
3943 if (! ATTR_IND_SIMPLIFIED_P (exp))
3944 /* Since this is an arbitrary expression, it can look at anything.
3945 However, constant expressions do not depend on any particular
3946 insn. */
3947 must_extract = must_constrain = 1;
3948 return;
3950 case MATCH_OPERAND:
3951 must_extract = 1;
3952 return;
3954 case MATCH_TEST:
3955 case EQ_ATTR_ALT:
3956 must_extract = must_constrain = 1;
3957 break;
3959 case EQ_ATTR:
3960 if (XSTR (exp, 0) == alternative_name)
3961 must_extract = must_constrain = 1;
3962 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3963 length_used = 1;
3964 return;
3966 case MATCH_DUP:
3967 must_extract = 1;
3968 address_used = 1;
3969 return;
3971 case PC:
3972 address_used = 1;
3973 return;
3975 case ATTR_FLAG:
3976 return;
3978 default:
3979 break;
3982 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3983 switch (*fmt++)
3985 case 'e':
3986 case 'u':
3987 walk_attr_value (XEXP (exp, i));
3988 break;
3990 case 'E':
3991 if (XVEC (exp, i) != NULL)
3992 for (j = 0; j < XVECLEN (exp, i); j++)
3993 walk_attr_value (XVECEXP (exp, i, j));
3994 break;
3998 /* Write out a function to obtain the attribute for a given INSN. */
4000 static void
4001 write_attr_get (FILE *outf, struct attr_desc *attr)
4003 struct attr_value *av, *common_av;
4004 int i, j;
4006 /* Find the most used attribute value. Handle that as the `default' of the
4007 switch we will generate. */
4008 common_av = find_most_used (attr);
4010 /* Write out start of function, then all values with explicit `case' lines,
4011 then a `default', then the value with the most uses. */
4012 if (attr->enum_name)
4013 fprintf (outf, "enum %s\n", attr->enum_name);
4014 else if (!attr->is_numeric)
4015 fprintf (outf, "enum attr_%s\n", attr->name);
4016 else
4017 fprintf (outf, "int\n");
4019 /* If the attribute name starts with a star, the remainder is the name of
4020 the subroutine to use, instead of `get_attr_...'. */
4021 if (attr->name[0] == '*')
4022 fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4023 else if (attr->is_const == 0)
4024 fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
4025 else
4027 fprintf (outf, "get_attr_%s (void)\n", attr->name);
4028 fprintf (outf, "{\n");
4030 for (av = attr->first_value; av; av = av->next)
4031 if (av->num_insns == 1)
4032 write_attr_set (outf, attr, 2, av->value, "return", ";",
4033 true_rtx, av->first_insn->def->insn_code,
4034 av->first_insn->def->insn_index, 0);
4035 else if (av->num_insns != 0)
4036 write_attr_set (outf, attr, 2, av->value, "return", ";",
4037 true_rtx, -2, 0, 0);
4039 fprintf (outf, "}\n\n");
4040 return;
4043 fprintf (outf, "{\n");
4045 /* Find attributes that are worth caching in the conditions. */
4046 cached_attr_count = 0;
4047 attrs_seen_more_than_once = 0;
4048 for (av = attr->first_value; av; av = av->next)
4050 attrs_seen_once = 0;
4051 find_attrs_to_cache (av->value, true);
4053 /* Remove those that aren't worth caching from the array. */
4054 for (i = 0, j = 0; i < cached_attr_count; i++)
4055 if ((attrs_seen_more_than_once & (1U << i)) != 0)
4057 const char *name = cached_attrs[i];
4058 struct attr_desc *cached_attr;
4059 if (i != j)
4060 cached_attrs[j] = name;
4061 cached_attr = find_attr (&name, 0);
4062 gcc_assert (cached_attr && cached_attr->is_const == 0);
4063 if (cached_attr->enum_name)
4064 fprintf (outf, " enum %s", cached_attr->enum_name);
4065 else if (!cached_attr->is_numeric)
4066 fprintf (outf, " enum attr_%s", cached_attr->name);
4067 else
4068 fprintf (outf, " int");
4069 fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
4070 j++;
4072 cached_attr_count = j;
4073 if (cached_attr_count)
4074 fprintf (outf, "\n");
4076 fprintf (outf, " switch (recog_memoized (insn))\n");
4077 fprintf (outf, " {\n");
4079 for (av = attr->first_value; av; av = av->next)
4080 if (av != common_av)
4081 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4083 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4084 fprintf (outf, " }\n}\n\n");
4085 cached_attr_count = 0;
4088 /* Given an AND tree of known true terms (because we are inside an `if' with
4089 that as the condition or are in an `else' clause) and an expression,
4090 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4091 the bulk of the work. */
4093 static rtx
4094 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4096 rtx term;
4098 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4100 if (GET_CODE (known_true) == AND)
4102 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4103 insn_code, insn_index);
4104 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4105 insn_code, insn_index);
4107 else
4109 term = known_true;
4110 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4113 return exp;
4116 /* Write out a series of tests and assignment statements to perform tests and
4117 sets of an attribute value. We are passed an indentation amount and prefix
4118 and suffix strings to write around each attribute value (e.g., "return"
4119 and ";"). */
4121 static void
4122 write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
4123 const char *prefix, const char *suffix, rtx known_true,
4124 int insn_code, int insn_index, unsigned int attrs_cached)
4126 if (GET_CODE (value) == COND)
4128 /* Assume the default value will be the default of the COND unless we
4129 find an always true expression. */
4130 rtx default_val = XEXP (value, 1);
4131 rtx our_known_true = known_true;
4132 rtx newexp;
4133 int first_if = 1;
4134 int i;
4136 if (cached_attr_count)
4138 attrs_seen_once = 0;
4139 attrs_seen_more_than_once = 0;
4140 for (i = 0; i < XVECLEN (value, 0); i += 2)
4141 find_attrs_to_cache (XVECEXP (value, 0, i), false);
4142 attrs_to_cache |= attrs_seen_more_than_once;
4145 for (i = 0; i < XVECLEN (value, 0); i += 2)
4147 rtx testexp;
4148 rtx inner_true;
4150 /* Reset our_known_true after some time to not accumulate
4151 too much cruft (slowing down genattrtab). */
4152 if ((i & 31) == 0)
4153 our_known_true = known_true;
4154 testexp = eliminate_known_true (our_known_true,
4155 XVECEXP (value, 0, i),
4156 insn_code, insn_index);
4157 newexp = attr_rtx (NOT, testexp);
4158 newexp = insert_right_side (AND, our_known_true, newexp,
4159 insn_code, insn_index);
4161 /* If the test expression is always true or if the next `known_true'
4162 expression is always false, this is the last case, so break
4163 out and let this value be the `else' case. */
4164 if (testexp == true_rtx || newexp == false_rtx)
4166 default_val = XVECEXP (value, 0, i + 1);
4167 break;
4170 /* Compute the expression to pass to our recursive call as being
4171 known true. */
4172 inner_true = insert_right_side (AND, our_known_true,
4173 testexp, insn_code, insn_index);
4175 /* If this is always false, skip it. */
4176 if (inner_true == false_rtx)
4177 continue;
4179 attrs_cached_inside = attrs_cached;
4180 attrs_cached_after = attrs_cached;
4181 write_indent (outf, indent);
4182 fprintf (outf, "%sif ", first_if ? "" : "else ");
4183 first_if = 0;
4184 write_test_expr (outf, testexp, attrs_cached,
4185 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4186 attrs_cached = attrs_cached_after;
4187 fprintf (outf, "\n");
4188 write_indent (outf, indent + 2);
4189 fprintf (outf, "{\n");
4191 write_attr_set (outf, attr, indent + 4,
4192 XVECEXP (value, 0, i + 1), prefix, suffix,
4193 inner_true, insn_code, insn_index,
4194 attrs_cached_inside);
4195 write_indent (outf, indent + 2);
4196 fprintf (outf, "}\n");
4197 our_known_true = newexp;
4200 if (! first_if)
4202 write_indent (outf, indent);
4203 fprintf (outf, "else\n");
4204 write_indent (outf, indent + 2);
4205 fprintf (outf, "{\n");
4208 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4209 prefix, suffix, our_known_true, insn_code, insn_index,
4210 attrs_cached);
4212 if (! first_if)
4214 write_indent (outf, indent + 2);
4215 fprintf (outf, "}\n");
4218 else
4220 write_indent (outf, indent);
4221 fprintf (outf, "%s ", prefix);
4222 write_attr_value (outf, attr, value);
4223 fprintf (outf, "%s\n", suffix);
4227 /* Write a series of case statements for every instruction in list IE.
4228 INDENT is the amount of indentation to write before each case. */
4230 static void
4231 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4233 for (; ie != 0; ie = ie->next)
4234 if (ie->def->insn_code != -1)
4236 write_indent (outf, indent);
4237 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4238 fprintf (outf, "case %d: /* define_peephole, %s:%d */\n",
4239 ie->def->insn_code, ie->def->loc.filename,
4240 ie->def->loc.lineno);
4241 else
4242 fprintf (outf, "case %d: /* %s */\n",
4243 ie->def->insn_code, XSTR (ie->def->def, 0));
4247 /* Write out the computation for one attribute value. */
4249 static void
4250 write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
4251 int write_case_lines, const char *prefix, const char *suffix,
4252 int indent, rtx known_true)
4254 if (av->num_insns == 0)
4255 return;
4257 if (av->has_asm_insn)
4259 write_indent (outf, indent);
4260 fprintf (outf, "case -1:\n");
4261 write_indent (outf, indent + 2);
4262 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4263 write_indent (outf, indent + 2);
4264 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
4265 write_indent (outf, indent + 2);
4266 fprintf (outf, " fatal_insn_not_found (insn);\n");
4269 if (write_case_lines)
4270 write_insn_cases (outf, av->first_insn, indent);
4271 else
4273 write_indent (outf, indent);
4274 fprintf (outf, "default:\n");
4277 /* See what we have to do to output this value. */
4278 must_extract = must_constrain = address_used = 0;
4279 walk_attr_value (av->value);
4281 if (must_constrain)
4283 write_indent (outf, indent + 2);
4284 fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4286 else if (must_extract)
4288 write_indent (outf, indent + 2);
4289 fprintf (outf, "extract_insn_cached (insn);\n");
4292 attrs_to_cache = 0;
4293 if (av->num_insns == 1)
4294 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4295 known_true, av->first_insn->def->insn_code,
4296 av->first_insn->def->insn_index, 0);
4297 else
4298 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4299 known_true, -2, 0, 0);
4301 if (strncmp (prefix, "return", 6))
4303 write_indent (outf, indent + 2);
4304 fprintf (outf, "break;\n");
4306 fprintf (outf, "\n");
4309 /* Utilities to write in various forms. */
4311 static void
4312 write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
4314 if (attr->is_numeric)
4316 int num = atoi (s);
4318 fprintf (outf, "%d", num);
4320 if (num > 9 || num < 0)
4321 fprintf (outf, " /* %#x */", num);
4323 else
4325 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4326 fprintf (outf, "_");
4327 write_upcase (outf, s);
4331 static void
4332 write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
4334 int op;
4336 switch (GET_CODE (value))
4338 case CONST_STRING:
4339 write_attr_valueq (outf, attr, XSTR (value, 0));
4340 break;
4342 case CONST_INT:
4343 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4344 break;
4346 case SYMBOL_REF:
4347 fprint_c_condition (outf, XSTR (value, 0));
4348 break;
4350 case ATTR:
4352 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4353 if (attr->enum_name)
4354 fprintf (outf, "(enum %s)", attr->enum_name);
4355 else if (!attr->is_numeric)
4356 fprintf (outf, "(enum attr_%s)", attr->name);
4357 else if (!attr2->is_numeric)
4358 fprintf (outf, "(int)");
4360 fprintf (outf, "get_attr_%s (%s)", attr2->name,
4361 (attr2->is_const ? "" : "insn"));
4363 break;
4365 case PLUS:
4366 op = '+';
4367 goto do_operator;
4368 case MINUS:
4369 op = '-';
4370 goto do_operator;
4371 case MULT:
4372 op = '*';
4373 goto do_operator;
4374 case DIV:
4375 op = '/';
4376 goto do_operator;
4377 case MOD:
4378 op = '%';
4379 goto do_operator;
4381 do_operator:
4382 write_attr_value (outf, attr, XEXP (value, 0));
4383 fputc (' ', outf);
4384 fputc (op, outf);
4385 fputc (' ', outf);
4386 write_attr_value (outf, attr, XEXP (value, 1));
4387 break;
4389 default:
4390 gcc_unreachable ();
4394 static void
4395 write_upcase (FILE *outf, const char *str)
4397 while (*str)
4399 /* The argument of TOUPPER should not have side effects. */
4400 fputc (TOUPPER (*str), outf);
4401 str++;
4405 static void
4406 write_indent (FILE *outf, int indent)
4408 for (; indent > 8; indent -= 8)
4409 fprintf (outf, "\t");
4411 for (; indent; indent--)
4412 fprintf (outf, " ");
4415 /* If the target does not have annul-true or annul-false delay slots, this
4416 function will create a dummy eligible_for function on OUTF which always
4417 returns false. KIND will be annul_true or annul_false. */
4419 static void
4420 write_dummy_eligible_delay (FILE *outf, const char *kind)
4422 /* Write function prelude. */
4424 fprintf (outf, "int\n");
4425 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4426 " int slot ATTRIBUTE_UNUSED,\n"
4427 " rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4428 " int flags ATTRIBUTE_UNUSED)\n",
4429 kind);
4430 fprintf (outf, "{\n");
4431 fprintf (outf, " return 0;\n");
4432 fprintf (outf, "}\n\n");
4435 /* Write a subroutine that is given an insn that requires a delay slot, a
4436 delay slot ordinal, and a candidate insn. It returns nonzero if the
4437 candidate can be placed in the specified delay slot of the insn.
4439 We can write as many as three subroutines. `eligible_for_delay'
4440 handles normal delay slots, `eligible_for_annul_true' indicates that
4441 the specified insn can be annulled if the branch is true, and likewise
4442 for `eligible_for_annul_false'.
4444 KIND is a string distinguishing these three cases ("delay", "annul_true",
4445 or "annul_false"). */
4447 static void
4448 write_eligible_delay (FILE *outf, const char *kind)
4450 struct delay_desc *delay;
4451 int max_slots;
4452 char str[50];
4453 const char *pstr;
4454 struct attr_desc *attr;
4455 struct attr_value *av, *common_av;
4456 int i;
4458 /* Compute the maximum number of delay slots required. We use the delay
4459 ordinal times this number plus one, plus the slot number as an index into
4460 the appropriate predicate to test. */
4462 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4463 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4464 max_slots = XVECLEN (delay->def, 1) / 3;
4466 /* Write function prelude. */
4468 fprintf (outf, "int\n");
4469 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4470 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4471 kind);
4472 fprintf (outf, "{\n");
4473 fprintf (outf, " rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4474 fprintf (outf, "\n");
4475 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
4476 fprintf (outf, "\n");
4477 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4478 converts a compound instruction into a loop. */
4479 fprintf (outf, " if (!INSN_P (candidate_insn))\n");
4480 fprintf (outf, " return 0;\n");
4481 fprintf (outf, "\n");
4483 /* If more than one delay type, find out which type the delay insn is. */
4485 if (num_delays > 1)
4487 attr = find_attr (&delay_type_str, 0);
4488 gcc_assert (attr);
4489 common_av = find_most_used (attr);
4491 fprintf (outf, " insn = delay_insn;\n");
4492 fprintf (outf, " switch (recog_memoized (insn))\n");
4493 fprintf (outf, " {\n");
4495 sprintf (str, " * %d;\n break;", max_slots);
4496 for (av = attr->first_value; av; av = av->next)
4497 if (av != common_av)
4498 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4500 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4501 fprintf (outf, " }\n\n");
4503 /* Ensure matched. Otherwise, shouldn't have been called. */
4504 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
4507 /* If just one type of delay slot, write simple switch. */
4508 if (num_delays == 1 && max_slots == 1)
4510 fprintf (outf, " insn = candidate_insn;\n");
4511 fprintf (outf, " switch (recog_memoized (insn))\n");
4512 fprintf (outf, " {\n");
4514 attr = find_attr (&delay_1_0_str, 0);
4515 gcc_assert (attr);
4516 common_av = find_most_used (attr);
4518 for (av = attr->first_value; av; av = av->next)
4519 if (av != common_av)
4520 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4522 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4523 fprintf (outf, " }\n");
4526 else
4528 /* Write a nested CASE. The first indicates which condition we need to
4529 test, and the inner CASE tests the condition. */
4530 fprintf (outf, " insn = candidate_insn;\n");
4531 fprintf (outf, " switch (slot)\n");
4532 fprintf (outf, " {\n");
4534 for (delay = delays; delay; delay = delay->next)
4535 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4537 fprintf (outf, " case %d:\n",
4538 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4539 fprintf (outf, " switch (recog_memoized (insn))\n");
4540 fprintf (outf, "\t{\n");
4542 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4543 pstr = str;
4544 attr = find_attr (&pstr, 0);
4545 gcc_assert (attr);
4546 common_av = find_most_used (attr);
4548 for (av = attr->first_value; av; av = av->next)
4549 if (av != common_av)
4550 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4552 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4553 fprintf (outf, " }\n");
4556 fprintf (outf, " default:\n");
4557 fprintf (outf, " gcc_unreachable ();\n");
4558 fprintf (outf, " }\n");
4561 fprintf (outf, "}\n\n");
4564 /* This page contains miscellaneous utility routines. */
4566 /* Given a pointer to a (char *), return a malloc'ed string containing the
4567 next comma-separated element. Advance the pointer to after the string
4568 scanned, or the end-of-string. Return NULL if at end of string. */
4570 static char *
4571 next_comma_elt (const char **pstr)
4573 const char *start;
4575 start = scan_comma_elt (pstr);
4577 if (start == NULL)
4578 return NULL;
4580 return attr_string (start, *pstr - start);
4583 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4584 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4585 replaced by a pointer to a canonical copy of the string. */
4587 static struct attr_desc *
4588 find_attr (const char **name_p, int create)
4590 struct attr_desc *attr;
4591 int index;
4592 const char *name = *name_p;
4594 /* Before we resort to using `strcmp', see if the string address matches
4595 anywhere. In most cases, it should have been canonicalized to do so. */
4596 if (name == alternative_name)
4597 return NULL;
4599 index = name[0] & (MAX_ATTRS_INDEX - 1);
4600 for (attr = attrs[index]; attr; attr = attr->next)
4601 if (name == attr->name)
4602 return attr;
4604 /* Otherwise, do it the slow way. */
4605 for (attr = attrs[index]; attr; attr = attr->next)
4606 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4608 *name_p = attr->name;
4609 return attr;
4612 if (! create)
4613 return NULL;
4615 attr = oballoc (struct attr_desc);
4616 attr->name = DEF_ATTR_STRING (name);
4617 attr->enum_name = 0;
4618 attr->first_value = attr->default_val = NULL;
4619 attr->is_numeric = attr->is_const = attr->is_special = 0;
4620 attr->next = attrs[index];
4621 attrs[index] = attr;
4623 *name_p = attr->name;
4625 return attr;
4628 /* Create internal attribute with the given default value. */
4630 static void
4631 make_internal_attr (const char *name, rtx value, int special)
4633 struct attr_desc *attr;
4635 attr = find_attr (&name, 1);
4636 gcc_assert (!attr->default_val);
4638 attr->is_numeric = 1;
4639 attr->is_const = 0;
4640 attr->is_special = (special & ATTR_SPECIAL) != 0;
4641 attr->default_val = get_attr_value (file_location ("<internal>", 0),
4642 value, attr, -2);
4645 /* Find the most used value of an attribute. */
4647 static struct attr_value *
4648 find_most_used (struct attr_desc *attr)
4650 struct attr_value *av;
4651 struct attr_value *most_used;
4652 int nuses;
4654 most_used = NULL;
4655 nuses = -1;
4657 for (av = attr->first_value; av; av = av->next)
4658 if (av->num_insns > nuses)
4659 nuses = av->num_insns, most_used = av;
4661 return most_used;
4664 /* Return (attr_value "n") */
4666 static rtx
4667 make_numeric_value (int n)
4669 static rtx int_values[20];
4670 rtx exp;
4671 char *p;
4673 gcc_assert (n >= 0);
4675 if (n < 20 && int_values[n])
4676 return int_values[n];
4678 p = attr_printf (MAX_DIGITS, "%d", n);
4679 exp = attr_rtx (CONST_STRING, p);
4681 if (n < 20)
4682 int_values[n] = exp;
4684 return exp;
4687 static rtx
4688 copy_rtx_unchanging (rtx orig)
4690 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4691 return orig;
4693 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4694 return orig;
4697 /* Determine if an insn has a constant number of delay slots, i.e., the
4698 number of delay slots is not a function of the length of the insn. */
4700 static void
4701 write_const_num_delay_slots (FILE *outf)
4703 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4704 struct attr_value *av;
4706 if (attr)
4708 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4709 fprintf (outf, "{\n");
4710 fprintf (outf, " switch (recog_memoized (insn))\n");
4711 fprintf (outf, " {\n");
4713 for (av = attr->first_value; av; av = av->next)
4715 length_used = 0;
4716 walk_attr_value (av->value);
4717 if (length_used)
4718 write_insn_cases (outf, av->first_insn, 4);
4721 fprintf (outf, " default:\n");
4722 fprintf (outf, " return 1;\n");
4723 fprintf (outf, " }\n}\n\n");
4727 /* Synthetic attributes used by insn-automata.c and the scheduler.
4728 These are primarily concerned with (define_insn_reservation)
4729 patterns. */
4731 struct insn_reserv
4733 struct insn_reserv *next;
4735 const char *name;
4736 int default_latency;
4737 rtx condexp;
4739 /* Sequence number of this insn. */
4740 int insn_num;
4742 /* Whether a (define_bypass) construct names this insn in its
4743 output list. */
4744 bool bypassed;
4747 static struct insn_reserv *all_insn_reservs = 0;
4748 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4749 static size_t n_insn_reservs;
4751 /* Store information from a DEFINE_INSN_RESERVATION for future
4752 attribute generation. */
4753 static void
4754 gen_insn_reserv (md_rtx_info *info)
4756 struct insn_reserv *decl = oballoc (struct insn_reserv);
4757 rtx def = info->def;
4759 struct attr_desc attr;
4760 memset (&attr, 0, sizeof (attr));
4761 attr.name = DEF_ATTR_STRING (XSTR (def, 0));
4762 attr.loc = info->loc;
4764 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4765 decl->default_latency = XINT (def, 1);
4766 decl->condexp = check_attr_test (info->loc, XEXP (def, 2), &attr);
4767 decl->insn_num = n_insn_reservs;
4768 decl->bypassed = false;
4769 decl->next = 0;
4771 *last_insn_reserv_p = decl;
4772 last_insn_reserv_p = &decl->next;
4773 n_insn_reservs++;
4776 /* Store information from a DEFINE_BYPASS for future attribute
4777 generation. The only thing we care about is the list of output
4778 insns, which will later be used to tag reservation structures with
4779 a 'bypassed' bit. */
4781 struct bypass_list
4783 struct bypass_list *next;
4784 const char *pattern;
4787 static struct bypass_list *all_bypasses;
4788 static size_t n_bypasses;
4789 static size_t n_bypassed;
4791 static void
4792 gen_bypass_1 (const char *s, size_t len)
4794 struct bypass_list *b;
4796 if (len == 0)
4797 return;
4799 s = attr_string (s, len);
4800 for (b = all_bypasses; b; b = b->next)
4801 if (s == b->pattern)
4802 return; /* already got that one */
4804 b = oballoc (struct bypass_list);
4805 b->pattern = s;
4806 b->next = all_bypasses;
4807 all_bypasses = b;
4808 n_bypasses++;
4811 static void
4812 gen_bypass (md_rtx_info *info)
4814 const char *p, *base;
4816 rtx def = info->def;
4817 for (p = base = XSTR (def, 1); *p; p++)
4818 if (*p == ',')
4820 gen_bypass_1 (base, p - base);
4822 p++;
4823 while (ISSPACE (*p));
4824 base = p;
4826 gen_bypass_1 (base, p - base);
4829 /* Find and mark all of the bypassed insns. */
4830 static void
4831 process_bypasses (void)
4833 struct bypass_list *b;
4834 struct insn_reserv *r;
4836 n_bypassed = 0;
4838 /* The reservation list is likely to be much longer than the bypass
4839 list. */
4840 for (r = all_insn_reservs; r; r = r->next)
4841 for (b = all_bypasses; b; b = b->next)
4842 if (fnmatch (b->pattern, r->name, 0) == 0)
4844 n_bypassed++;
4845 r->bypassed = true;
4846 break;
4850 /* Check that attribute NAME is used in define_insn_reservation condition
4851 EXP. Return true if it is. */
4852 static bool
4853 check_tune_attr (const char *name, rtx exp)
4855 switch (GET_CODE (exp))
4857 case AND:
4858 if (check_tune_attr (name, XEXP (exp, 0)))
4859 return true;
4860 return check_tune_attr (name, XEXP (exp, 1));
4862 case IOR:
4863 return (check_tune_attr (name, XEXP (exp, 0))
4864 && check_tune_attr (name, XEXP (exp, 1)));
4866 case EQ_ATTR:
4867 return XSTR (exp, 0) == name;
4869 default:
4870 return false;
4874 /* Try to find a const attribute (usually cpu or tune) that is used
4875 in all define_insn_reservation conditions. */
4876 static struct attr_desc *
4877 find_tune_attr (rtx exp)
4879 struct attr_desc *attr;
4881 switch (GET_CODE (exp))
4883 case AND:
4884 case IOR:
4885 attr = find_tune_attr (XEXP (exp, 0));
4886 if (attr)
4887 return attr;
4888 return find_tune_attr (XEXP (exp, 1));
4890 case EQ_ATTR:
4891 if (XSTR (exp, 0) == alternative_name)
4892 return NULL;
4894 attr = find_attr (&XSTR (exp, 0), 0);
4895 gcc_assert (attr);
4897 if (attr->is_const && !attr->is_special)
4899 struct insn_reserv *decl;
4901 for (decl = all_insn_reservs; decl; decl = decl->next)
4902 if (! check_tune_attr (attr->name, decl->condexp))
4903 return NULL;
4904 return attr;
4906 return NULL;
4908 default:
4909 return NULL;
4913 /* Create all of the attributes that describe automaton properties.
4914 Write the DFA and latency function prototypes to the files that
4915 need to have them, and write the init_sched_attrs(). */
4917 static void
4918 make_automaton_attrs (void)
4920 int i;
4921 struct insn_reserv *decl;
4922 rtx code_exp, lats_exp, byps_exp;
4923 struct attr_desc *tune_attr;
4925 if (n_insn_reservs == 0)
4926 return;
4928 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4929 if (tune_attr != NULL)
4931 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4932 struct attr_value *val;
4933 bool first = true;
4935 gcc_assert (tune_attr->is_const
4936 && !tune_attr->is_special
4937 && !tune_attr->is_numeric);
4939 /* Write the prototypes for all DFA functions. */
4940 for (val = tune_attr->first_value; val; val = val->next)
4942 if (val == tune_attr->default_val)
4943 continue;
4944 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4945 fprintf (dfa_file,
4946 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4947 XSTR (val->value, 0));
4949 fprintf (dfa_file, "\n");
4951 /* Write the prototypes for all latency functions. */
4952 for (val = tune_attr->first_value; val; val = val->next)
4954 if (val == tune_attr->default_val)
4955 continue;
4956 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4957 fprintf (latency_file,
4958 "extern int insn_default_latency_%s (rtx_insn *);\n",
4959 XSTR (val->value, 0));
4961 fprintf (latency_file, "\n");
4963 /* Write the prototypes for all automaton functions. */
4964 for (val = tune_attr->first_value; val; val = val->next)
4966 if (val == tune_attr->default_val)
4967 continue;
4968 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4969 fprintf (attr_file,
4970 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4971 "extern int insn_default_latency_%s (rtx_insn *);\n",
4972 XSTR (val->value, 0), XSTR (val->value, 0));
4974 fprintf (attr_file, "\n");
4975 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4976 fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n");
4977 fprintf (attr_file, "\n");
4978 fprintf (attr_file, "void\n");
4979 fprintf (attr_file, "init_sched_attrs (void)\n");
4980 fprintf (attr_file, "{\n");
4982 for (val = tune_attr->first_value; val; val = val->next)
4984 int j;
4985 char *name;
4986 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
4988 if (val == tune_attr->default_val)
4989 continue;
4990 for (decl = all_insn_reservs, i = 0;
4991 decl;
4992 decl = decl->next)
4994 rtx ctest = test;
4995 rtx condexp
4996 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
4997 if (condexp == false_rtx)
4998 continue;
4999 if (condexp == true_rtx)
5000 break;
5001 condexps[i] = condexp;
5002 condexps[i + 1] = make_numeric_value (decl->insn_num);
5003 condexps[i + 2] = make_numeric_value (decl->default_latency);
5004 i += 3;
5007 code_exp = rtx_alloc (COND);
5008 lats_exp = rtx_alloc (COND);
5010 j = i / 3 * 2;
5011 XVEC (code_exp, 0) = rtvec_alloc (j);
5012 XVEC (lats_exp, 0) = rtvec_alloc (j);
5014 if (decl)
5016 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
5017 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
5019 else
5021 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5022 XEXP (lats_exp, 1) = make_numeric_value (0);
5025 while (i > 0)
5027 i -= 3;
5028 j -= 2;
5029 XVECEXP (code_exp, 0, j) = condexps[i];
5030 XVECEXP (lats_exp, 0, j) = condexps[i];
5032 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
5033 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5036 name = XNEWVEC (char,
5037 sizeof ("*internal_dfa_insn_code_")
5038 + strlen (XSTR (val->value, 0)));
5039 strcpy (name, "*internal_dfa_insn_code_");
5040 strcat (name, XSTR (val->value, 0));
5041 make_internal_attr (name, code_exp, ATTR_NONE);
5042 strcpy (name, "*insn_default_latency_");
5043 strcat (name, XSTR (val->value, 0));
5044 make_internal_attr (name, lats_exp, ATTR_NONE);
5045 XDELETEVEC (name);
5047 if (first)
5049 fprintf (attr_file, " if (");
5050 first = false;
5052 else
5053 fprintf (attr_file, " else if (");
5054 write_test_expr (attr_file, test, 0, 0);
5055 fprintf (attr_file, ")\n");
5056 fprintf (attr_file, " {\n");
5057 fprintf (attr_file, " internal_dfa_insn_code\n");
5058 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
5059 XSTR (val->value, 0));
5060 fprintf (attr_file, " insn_default_latency\n");
5061 fprintf (attr_file, " = insn_default_latency_%s;\n",
5062 XSTR (val->value, 0));
5063 fprintf (attr_file, " }\n");
5066 fprintf (attr_file, " else\n");
5067 fprintf (attr_file, " gcc_unreachable ();\n");
5068 fprintf (attr_file, "}\n");
5069 fprintf (attr_file, "\n");
5071 XDELETEVEC (condexps);
5073 else
5075 code_exp = rtx_alloc (COND);
5076 lats_exp = rtx_alloc (COND);
5078 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5079 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5081 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5082 XEXP (lats_exp, 1) = make_numeric_value (0);
5084 for (decl = all_insn_reservs, i = 0;
5085 decl;
5086 decl = decl->next, i += 2)
5088 XVECEXP (code_exp, 0, i) = decl->condexp;
5089 XVECEXP (lats_exp, 0, i) = decl->condexp;
5091 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5092 XVECEXP (lats_exp, 0, i+1)
5093 = make_numeric_value (decl->default_latency);
5095 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5096 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
5099 if (n_bypasses == 0)
5100 byps_exp = make_numeric_value (0);
5101 else
5103 process_bypasses ();
5105 byps_exp = rtx_alloc (COND);
5106 XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2);
5107 XEXP (byps_exp, 1) = make_numeric_value (0);
5108 for (decl = all_insn_reservs, i = 0;
5109 decl;
5110 decl = decl->next)
5111 if (decl->bypassed)
5113 XVECEXP (byps_exp, 0, i) = decl->condexp;
5114 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5115 i += 2;
5119 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5122 static void
5123 write_header (FILE *outf)
5125 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5126 " from the machine description file `md'. */\n\n");
5128 fprintf (outf, "#include \"config.h\"\n");
5129 fprintf (outf, "#include \"system.h\"\n");
5130 fprintf (outf, "#include \"coretypes.h\"\n");
5131 fprintf (outf, "#include \"backend.h\"\n");
5132 fprintf (outf, "#include \"predict.h\"\n");
5133 fprintf (outf, "#include \"tree.h\"\n");
5134 fprintf (outf, "#include \"rtl.h\"\n");
5135 fprintf (outf, "#include \"alias.h\"\n");
5136 fprintf (outf, "#include \"options.h\"\n");
5137 fprintf (outf, "#include \"varasm.h\"\n");
5138 fprintf (outf, "#include \"stor-layout.h\"\n");
5139 fprintf (outf, "#include \"calls.h\"\n");
5140 fprintf (outf, "#include \"insn-attr.h\"\n");
5141 fprintf (outf, "#include \"tm_p.h\"\n");
5142 fprintf (outf, "#include \"insn-config.h\"\n");
5143 fprintf (outf, "#include \"recog.h\"\n");
5144 fprintf (outf, "#include \"regs.h\"\n");
5145 fprintf (outf, "#include \"real.h\"\n");
5146 fprintf (outf, "#include \"output.h\"\n");
5147 fprintf (outf, "#include \"toplev.h\"\n");
5148 fprintf (outf, "#include \"flags.h\"\n");
5149 fprintf (outf, "#include \"emit-rtl.h\"\n");
5150 fprintf (outf, "\n");
5151 fprintf (outf, "#define operands recog_data.operand\n\n");
5154 static FILE *
5155 open_outfile (const char *file_name)
5157 FILE *outf;
5158 outf = fopen (file_name, "w");
5159 if (! outf)
5160 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5161 write_header (outf);
5162 return outf;
5165 static bool
5166 handle_arg (const char *arg)
5168 switch (arg[1])
5170 case 'A':
5171 attr_file_name = &arg[2];
5172 return true;
5173 case 'D':
5174 dfa_file_name = &arg[2];
5175 return true;
5176 case 'L':
5177 latency_file_name = &arg[2];
5178 return true;
5179 default:
5180 return false;
5185 main (int argc, char **argv)
5187 struct attr_desc *attr;
5188 struct insn_def *id;
5189 int i;
5191 progname = "genattrtab";
5193 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5194 return FATAL_EXIT_CODE;
5196 attr_file = open_outfile (attr_file_name);
5197 dfa_file = open_outfile (dfa_file_name);
5198 latency_file = open_outfile (latency_file_name);
5200 obstack_init (hash_obstack);
5201 obstack_init (temp_obstack);
5203 /* Set up true and false rtx's */
5204 true_rtx = rtx_alloc (CONST_INT);
5205 XWINT (true_rtx, 0) = 1;
5206 false_rtx = rtx_alloc (CONST_INT);
5207 XWINT (false_rtx, 0) = 0;
5208 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5209 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5211 alternative_name = DEF_ATTR_STRING ("alternative");
5212 length_str = DEF_ATTR_STRING ("length");
5213 delay_type_str = DEF_ATTR_STRING ("*delay_type");
5214 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5215 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5217 /* Read the machine description. */
5219 md_rtx_info info;
5220 while (read_md_rtx (&info))
5222 switch (GET_CODE (info.def))
5224 case DEFINE_INSN:
5225 case DEFINE_PEEPHOLE:
5226 case DEFINE_ASM_ATTRIBUTES:
5227 gen_insn (&info);
5228 break;
5230 case DEFINE_ATTR:
5231 case DEFINE_ENUM_ATTR:
5232 gen_attr (&info);
5233 break;
5235 case DEFINE_DELAY:
5236 gen_delay (&info);
5237 break;
5239 case DEFINE_INSN_RESERVATION:
5240 gen_insn_reserv (&info);
5241 break;
5243 case DEFINE_BYPASS:
5244 gen_bypass (&info);
5245 break;
5247 default:
5248 break;
5250 if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
5251 insn_index_number++;
5254 if (have_error)
5255 return FATAL_EXIT_CODE;
5257 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5258 if (! got_define_asm_attributes)
5260 md_rtx_info info;
5261 info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5262 XVEC (info.def, 0) = rtvec_alloc (0);
5263 info.loc = file_location ("<internal>", 0);
5264 info.index = -1;
5265 gen_insn (&info);
5268 /* Expand DEFINE_DELAY information into new attribute. */
5269 expand_delays ();
5271 /* Make `insn_alternatives'. */
5272 int num_insn_codes = get_num_insn_codes ();
5273 insn_alternatives = oballocvec (uint64_t, num_insn_codes);
5274 for (id = defs; id; id = id->next)
5275 if (id->insn_code >= 0)
5276 insn_alternatives[id->insn_code]
5277 = (((uint64_t) 1) << id->num_alternatives) - 1;
5279 /* Make `insn_n_alternatives'. */
5280 insn_n_alternatives = oballocvec (int, num_insn_codes);
5281 for (id = defs; id; id = id->next)
5282 if (id->insn_code >= 0)
5283 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5285 /* Construct extra attributes for automata. */
5286 make_automaton_attrs ();
5288 /* Prepare to write out attribute subroutines by checking everything stored
5289 away and building the attribute cases. */
5291 check_defs ();
5293 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5294 for (attr = attrs[i]; attr; attr = attr->next)
5295 attr->default_val->value
5296 = check_attr_value (attr->loc, attr->default_val->value, attr);
5298 if (have_error)
5299 return FATAL_EXIT_CODE;
5301 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5302 for (attr = attrs[i]; attr; attr = attr->next)
5303 fill_attr (attr);
5305 /* Construct extra attributes for `length'. */
5306 make_length_attrs ();
5308 /* Perform any possible optimizations to speed up compilation. */
5309 optimize_attrs (num_insn_codes);
5311 /* Now write out all the `gen_attr_...' routines. Do these before the
5312 special routines so that they get defined before they are used. */
5314 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5315 for (attr = attrs[i]; attr; attr = attr->next)
5317 FILE *outf;
5319 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5320 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5321 outf = dfa_file;
5322 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5323 outf = latency_file;
5324 else
5325 outf = attr_file;
5326 #undef IS_ATTR_GROUP
5328 if (! attr->is_special && ! attr->is_const)
5329 write_attr_get (outf, attr);
5332 /* Write out delay eligibility information, if DEFINE_DELAY present.
5333 (The function to compute the number of delay slots will be written
5334 below.) */
5335 write_eligible_delay (attr_file, "delay");
5336 if (have_annul_true)
5337 write_eligible_delay (attr_file, "annul_true");
5338 else
5339 write_dummy_eligible_delay (attr_file, "annul_true");
5340 if (have_annul_false)
5341 write_eligible_delay (attr_file, "annul_false");
5342 else
5343 write_dummy_eligible_delay (attr_file, "annul_false");
5345 /* Write out constant delay slot info. */
5346 write_const_num_delay_slots (attr_file);
5348 write_length_unit_log (attr_file);
5350 if (fclose (attr_file) != 0)
5351 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5352 if (fclose (dfa_file) != 0)
5353 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5354 if (fclose (latency_file) != 0)
5355 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5357 return SUCCESS_EXIT_CODE;