2016-07-28 Steven G. Kargl <kargl@gcc.gnu.org>
[official-gcc.git] / gcc / genattrtab.c
blobd39d4a70e924d6fd92a8230a0deecfd2931e3476
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 An outermost pair of parentheses is emitted around this C expression unless
3422 EMIT_PARENS is false. */
3424 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3425 #define FLG_BITWISE 1
3426 /* Set if cached attribute will be known initialized in else block after
3427 this condition. This is true for LHS of toplevel && and || and
3428 even for RHS of ||, but not for RHS of &&. */
3429 #define FLG_AFTER 2
3430 /* Set if cached attribute will be known initialized in then block after
3431 this condition. This is true for LHS of toplevel && and || and
3432 even for RHS of &&, but not for RHS of ||. */
3433 #define FLG_INSIDE 4
3434 /* Cleared when an operand of &&. */
3435 #define FLG_OUTSIDE_AND 8
3437 static unsigned int
3438 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
3439 bool emit_parens = true)
3441 int comparison_operator = 0;
3442 RTX_CODE code;
3443 struct attr_desc *attr;
3445 if (emit_parens)
3446 fprintf (outf, "(");
3448 code = GET_CODE (exp);
3449 switch (code)
3451 /* Binary operators. */
3452 case GEU: case GTU:
3453 case LEU: case LTU:
3454 fprintf (outf, "(unsigned) ");
3455 /* Fall through. */
3457 case EQ: case NE:
3458 case GE: case GT:
3459 case LE: case LT:
3460 comparison_operator = FLG_BITWISE;
3462 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3463 case AND: case IOR: case XOR:
3464 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3465 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3467 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3468 write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3469 flags | comparison_operator);
3471 else
3473 if (code == AND)
3474 flags &= ~FLG_OUTSIDE_AND;
3475 if (GET_CODE (XEXP (exp, 0)) == code
3476 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3477 || (GET_CODE (XEXP (exp, 0)) == NOT
3478 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3479 attrs_cached
3480 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3481 else
3482 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3484 switch (code)
3486 case EQ:
3487 fprintf (outf, " == ");
3488 break;
3489 case NE:
3490 fprintf (outf, " != ");
3491 break;
3492 case GE:
3493 fprintf (outf, " >= ");
3494 break;
3495 case GT:
3496 fprintf (outf, " > ");
3497 break;
3498 case GEU:
3499 fprintf (outf, " >= (unsigned) ");
3500 break;
3501 case GTU:
3502 fprintf (outf, " > (unsigned) ");
3503 break;
3504 case LE:
3505 fprintf (outf, " <= ");
3506 break;
3507 case LT:
3508 fprintf (outf, " < ");
3509 break;
3510 case LEU:
3511 fprintf (outf, " <= (unsigned) ");
3512 break;
3513 case LTU:
3514 fprintf (outf, " < (unsigned) ");
3515 break;
3516 case PLUS:
3517 fprintf (outf, " + ");
3518 break;
3519 case MINUS:
3520 fprintf (outf, " - ");
3521 break;
3522 case MULT:
3523 fprintf (outf, " * ");
3524 break;
3525 case DIV:
3526 fprintf (outf, " / ");
3527 break;
3528 case MOD:
3529 fprintf (outf, " %% ");
3530 break;
3531 case AND:
3532 if (flags & FLG_BITWISE)
3533 fprintf (outf, " & ");
3534 else
3535 fprintf (outf, " && ");
3536 break;
3537 case IOR:
3538 if (flags & FLG_BITWISE)
3539 fprintf (outf, " | ");
3540 else
3541 fprintf (outf, " || ");
3542 break;
3543 case XOR:
3544 fprintf (outf, " ^ ");
3545 break;
3546 case ASHIFT:
3547 fprintf (outf, " << ");
3548 break;
3549 case LSHIFTRT:
3550 case ASHIFTRT:
3551 fprintf (outf, " >> ");
3552 break;
3553 default:
3554 gcc_unreachable ();
3557 if (code == AND)
3559 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3560 cached_x is only known to be initialized in then block. */
3561 flags &= ~FLG_AFTER;
3563 else if (code == IOR)
3565 if (flags & FLG_OUTSIDE_AND)
3566 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3567 cached_x is only known to be initialized in else block
3568 and else if conditions. */
3569 flags &= ~FLG_INSIDE;
3570 else
3571 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3572 && something_else)
3573 cached_x is not know to be initialized anywhere. */
3574 flags &= ~(FLG_AFTER | FLG_INSIDE);
3576 if ((code == AND || code == IOR)
3577 && (GET_CODE (XEXP (exp, 1)) == code
3578 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3579 || (GET_CODE (XEXP (exp, 1)) == NOT
3580 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3582 bool need_parens = true;
3584 /* No need to emit parentheses around the right-hand operand if we are
3585 continuing a chain of && or || (or & or |). */
3586 if (GET_CODE (XEXP (exp, 1)) == code)
3587 need_parens = false;
3589 attrs_cached
3590 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags,
3591 need_parens);
3593 else
3594 write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3595 flags | comparison_operator);
3596 break;
3598 case NOT:
3599 /* Special-case (not (eq_attrq "alternative" "x")) */
3600 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3602 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3604 fprintf (outf, "which_alternative != %s",
3605 XSTR (XEXP (exp, 0), 1));
3606 break;
3609 fprintf (outf, "! ");
3610 attrs_cached =
3611 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3612 break;
3615 /* Otherwise, fall through to normal unary operator. */
3617 /* Unary operators. */
3618 case ABS: case NEG:
3619 switch (code)
3621 case NOT:
3622 if (flags & FLG_BITWISE)
3623 fprintf (outf, "~ ");
3624 else
3625 fprintf (outf, "! ");
3626 break;
3627 case ABS:
3628 fprintf (outf, "abs ");
3629 break;
3630 case NEG:
3631 fprintf (outf, "-");
3632 break;
3633 default:
3634 gcc_unreachable ();
3637 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3638 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3639 break;
3641 case EQ_ATTR_ALT:
3643 int set = XINT (exp, 0), bit = 0;
3645 if (flags & FLG_BITWISE)
3646 fatal ("EQ_ATTR_ALT not valid inside comparison");
3648 if (!set)
3649 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3651 if (!(set & (set - 1)))
3653 if (!(set & 0xffff))
3655 bit += 16;
3656 set >>= 16;
3658 if (!(set & 0xff))
3660 bit += 8;
3661 set >>= 8;
3663 if (!(set & 0xf))
3665 bit += 4;
3666 set >>= 4;
3668 if (!(set & 0x3))
3670 bit += 2;
3671 set >>= 2;
3673 if (!(set & 1))
3674 bit++;
3676 fprintf (outf, "which_alternative %s= %d",
3677 XINT (exp, 1) ? "!" : "=", bit);
3679 else
3681 fprintf (outf, "%s((1 << which_alternative) & %#x)",
3682 XINT (exp, 1) ? "!" : "", set);
3685 break;
3687 /* Comparison test of an attribute with a value. Most of these will
3688 have been removed by optimization. Handle "alternative"
3689 specially and give error if EQ_ATTR present inside a comparison. */
3690 case EQ_ATTR:
3691 if (flags & FLG_BITWISE)
3692 fatal ("EQ_ATTR not valid inside comparison");
3694 if (XSTR (exp, 0) == alternative_name)
3696 fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3697 break;
3700 attr = find_attr (&XSTR (exp, 0), 0);
3701 gcc_assert (attr);
3703 /* Now is the time to expand the value of a constant attribute. */
3704 if (attr->is_const)
3706 write_test_expr (outf,
3707 evaluate_eq_attr (exp, attr,
3708 attr->default_val->value,
3709 -2, -2),
3710 attrs_cached, 0);
3712 else
3714 int i;
3715 for (i = 0; i < cached_attr_count; i++)
3716 if (attr->name == cached_attrs[i])
3717 break;
3718 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3719 fprintf (outf, "cached_%s", attr->name);
3720 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3722 fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3723 attr->name, attr->name);
3724 if (flags & FLG_AFTER)
3725 attrs_cached_after |= (1U << i);
3726 if (flags & FLG_INSIDE)
3727 attrs_cached_inside |= (1U << i);
3728 attrs_cached |= (1U << i);
3730 else
3731 fprintf (outf, "get_attr_%s (insn)", attr->name);
3732 fprintf (outf, " == ");
3733 write_attr_valueq (outf, attr, XSTR (exp, 1));
3735 break;
3737 /* Comparison test of flags for define_delays. */
3738 case ATTR_FLAG:
3739 if (flags & FLG_BITWISE)
3740 fatal ("ATTR_FLAG not valid inside comparison");
3741 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3742 break;
3744 /* See if an operand matches a predicate. */
3745 case MATCH_OPERAND:
3746 /* If only a mode is given, just ensure the mode matches the operand.
3747 If neither a mode nor predicate is given, error. */
3748 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3750 if (GET_MODE (exp) == VOIDmode)
3751 fatal ("null MATCH_OPERAND specified as test");
3752 else
3753 fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3754 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3756 else
3757 fprintf (outf, "%s (operands[%d], %smode)",
3758 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3759 break;
3761 /* Constant integer. */
3762 case CONST_INT:
3763 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3764 break;
3766 case MATCH_TEST:
3767 fprint_c_condition (outf, XSTR (exp, 0));
3768 if (flags & FLG_BITWISE)
3769 fprintf (outf, " != 0");
3770 break;
3772 /* A random C expression. */
3773 case SYMBOL_REF:
3774 fprint_c_condition (outf, XSTR (exp, 0));
3775 break;
3777 /* The address of the branch target. */
3778 case MATCH_DUP:
3779 fprintf (outf,
3780 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3781 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3782 break;
3784 case PC:
3785 /* The address of the current insn. We implement this actually as the
3786 address of the current insn for backward branches, but the last
3787 address of the next insn for forward branches, and both with
3788 adjustments that account for the worst-case possible stretching of
3789 intervening alignments between this insn and its destination. */
3790 fprintf (outf, "insn_current_reference_address (insn)");
3791 break;
3793 case CONST_STRING:
3794 fprintf (outf, "%s", XSTR (exp, 0));
3795 break;
3797 case IF_THEN_ELSE:
3798 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3799 fprintf (outf, " ? ");
3800 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3801 fprintf (outf, " : ");
3802 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3803 break;
3805 default:
3806 fatal ("bad RTX code `%s' in attribute calculation\n",
3807 GET_RTX_NAME (code));
3810 if (emit_parens)
3811 fprintf (outf, ")");
3813 return attrs_cached;
3816 /* Given an attribute value, return the maximum CONST_STRING argument
3817 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3819 static int
3820 max_attr_value (rtx exp, int *unknownp)
3822 int current_max;
3823 int i, n;
3825 switch (GET_CODE (exp))
3827 case CONST_STRING:
3828 current_max = atoi (XSTR (exp, 0));
3829 break;
3831 case COND:
3832 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3833 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3835 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3836 if (n > current_max)
3837 current_max = n;
3839 break;
3841 case IF_THEN_ELSE:
3842 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3843 n = max_attr_value (XEXP (exp, 2), unknownp);
3844 if (n > current_max)
3845 current_max = n;
3846 break;
3848 default:
3849 *unknownp = 1;
3850 current_max = INT_MAX;
3851 break;
3854 return current_max;
3857 /* Given an attribute value, return the minimum CONST_STRING argument
3858 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3860 static int
3861 min_attr_value (rtx exp, int *unknownp)
3863 int current_min;
3864 int i, n;
3866 switch (GET_CODE (exp))
3868 case CONST_STRING:
3869 current_min = atoi (XSTR (exp, 0));
3870 break;
3872 case COND:
3873 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3874 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3876 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3877 if (n < current_min)
3878 current_min = n;
3880 break;
3882 case IF_THEN_ELSE:
3883 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3884 n = min_attr_value (XEXP (exp, 2), unknownp);
3885 if (n < current_min)
3886 current_min = n;
3887 break;
3889 default:
3890 *unknownp = 1;
3891 current_min = INT_MAX;
3892 break;
3895 return current_min;
3898 /* Given an attribute value, return the result of ORing together all
3899 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3900 if the numeric value is not known. */
3902 static int
3903 or_attr_value (rtx exp, int *unknownp)
3905 int current_or;
3906 int i;
3908 switch (GET_CODE (exp))
3910 case CONST_STRING:
3911 current_or = atoi (XSTR (exp, 0));
3912 break;
3914 case COND:
3915 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3916 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3917 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3918 break;
3920 case IF_THEN_ELSE:
3921 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3922 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3923 break;
3925 default:
3926 *unknownp = 1;
3927 current_or = -1;
3928 break;
3931 return current_or;
3934 /* Scan an attribute value, possibly a conditional, and record what actions
3935 will be required to do any conditional tests in it.
3937 Specifically, set
3938 `must_extract' if we need to extract the insn operands
3939 `must_constrain' if we must compute `which_alternative'
3940 `address_used' if an address expression was used
3941 `length_used' if an (eq_attr "length" ...) was used
3944 static void
3945 walk_attr_value (rtx exp)
3947 int i, j;
3948 const char *fmt;
3949 RTX_CODE code;
3951 if (exp == NULL)
3952 return;
3954 code = GET_CODE (exp);
3955 switch (code)
3957 case SYMBOL_REF:
3958 if (! ATTR_IND_SIMPLIFIED_P (exp))
3959 /* Since this is an arbitrary expression, it can look at anything.
3960 However, constant expressions do not depend on any particular
3961 insn. */
3962 must_extract = must_constrain = 1;
3963 return;
3965 case MATCH_OPERAND:
3966 must_extract = 1;
3967 return;
3969 case MATCH_TEST:
3970 case EQ_ATTR_ALT:
3971 must_extract = must_constrain = 1;
3972 break;
3974 case EQ_ATTR:
3975 if (XSTR (exp, 0) == alternative_name)
3976 must_extract = must_constrain = 1;
3977 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3978 length_used = 1;
3979 return;
3981 case MATCH_DUP:
3982 must_extract = 1;
3983 address_used = 1;
3984 return;
3986 case PC:
3987 address_used = 1;
3988 return;
3990 case ATTR_FLAG:
3991 return;
3993 default:
3994 break;
3997 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3998 switch (*fmt++)
4000 case 'e':
4001 case 'u':
4002 walk_attr_value (XEXP (exp, i));
4003 break;
4005 case 'E':
4006 if (XVEC (exp, i) != NULL)
4007 for (j = 0; j < XVECLEN (exp, i); j++)
4008 walk_attr_value (XVECEXP (exp, i, j));
4009 break;
4013 /* Write out a function to obtain the attribute for a given INSN. */
4015 static void
4016 write_attr_get (FILE *outf, struct attr_desc *attr)
4018 struct attr_value *av, *common_av;
4019 int i, j;
4021 /* Find the most used attribute value. Handle that as the `default' of the
4022 switch we will generate. */
4023 common_av = find_most_used (attr);
4025 /* Write out start of function, then all values with explicit `case' lines,
4026 then a `default', then the value with the most uses. */
4027 if (attr->enum_name)
4028 fprintf (outf, "enum %s\n", attr->enum_name);
4029 else if (!attr->is_numeric)
4030 fprintf (outf, "enum attr_%s\n", attr->name);
4031 else
4032 fprintf (outf, "int\n");
4034 /* If the attribute name starts with a star, the remainder is the name of
4035 the subroutine to use, instead of `get_attr_...'. */
4036 if (attr->name[0] == '*')
4037 fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4038 else if (attr->is_const == 0)
4039 fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
4040 else
4042 fprintf (outf, "get_attr_%s (void)\n", attr->name);
4043 fprintf (outf, "{\n");
4045 for (av = attr->first_value; av; av = av->next)
4046 if (av->num_insns == 1)
4047 write_attr_set (outf, attr, 2, av->value, "return", ";",
4048 true_rtx, av->first_insn->def->insn_code,
4049 av->first_insn->def->insn_index, 0);
4050 else if (av->num_insns != 0)
4051 write_attr_set (outf, attr, 2, av->value, "return", ";",
4052 true_rtx, -2, 0, 0);
4054 fprintf (outf, "}\n\n");
4055 return;
4058 fprintf (outf, "{\n");
4060 /* Find attributes that are worth caching in the conditions. */
4061 cached_attr_count = 0;
4062 attrs_seen_more_than_once = 0;
4063 for (av = attr->first_value; av; av = av->next)
4065 attrs_seen_once = 0;
4066 find_attrs_to_cache (av->value, true);
4068 /* Remove those that aren't worth caching from the array. */
4069 for (i = 0, j = 0; i < cached_attr_count; i++)
4070 if ((attrs_seen_more_than_once & (1U << i)) != 0)
4072 const char *name = cached_attrs[i];
4073 struct attr_desc *cached_attr;
4074 if (i != j)
4075 cached_attrs[j] = name;
4076 cached_attr = find_attr (&name, 0);
4077 gcc_assert (cached_attr && cached_attr->is_const == 0);
4078 if (cached_attr->enum_name)
4079 fprintf (outf, " enum %s", cached_attr->enum_name);
4080 else if (!cached_attr->is_numeric)
4081 fprintf (outf, " enum attr_%s", cached_attr->name);
4082 else
4083 fprintf (outf, " int");
4084 fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
4085 j++;
4087 cached_attr_count = j;
4088 if (cached_attr_count)
4089 fprintf (outf, "\n");
4091 fprintf (outf, " switch (recog_memoized (insn))\n");
4092 fprintf (outf, " {\n");
4094 for (av = attr->first_value; av; av = av->next)
4095 if (av != common_av)
4096 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4098 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4099 fprintf (outf, " }\n}\n\n");
4100 cached_attr_count = 0;
4103 /* Given an AND tree of known true terms (because we are inside an `if' with
4104 that as the condition or are in an `else' clause) and an expression,
4105 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4106 the bulk of the work. */
4108 static rtx
4109 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4111 rtx term;
4113 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4115 if (GET_CODE (known_true) == AND)
4117 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4118 insn_code, insn_index);
4119 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4120 insn_code, insn_index);
4122 else
4124 term = known_true;
4125 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4128 return exp;
4131 /* Write out a series of tests and assignment statements to perform tests and
4132 sets of an attribute value. We are passed an indentation amount and prefix
4133 and suffix strings to write around each attribute value (e.g., "return"
4134 and ";"). */
4136 static void
4137 write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
4138 const char *prefix, const char *suffix, rtx known_true,
4139 int insn_code, int insn_index, unsigned int attrs_cached)
4141 if (GET_CODE (value) == COND)
4143 /* Assume the default value will be the default of the COND unless we
4144 find an always true expression. */
4145 rtx default_val = XEXP (value, 1);
4146 rtx our_known_true = known_true;
4147 rtx newexp;
4148 int first_if = 1;
4149 int i;
4151 if (cached_attr_count)
4153 attrs_seen_once = 0;
4154 attrs_seen_more_than_once = 0;
4155 for (i = 0; i < XVECLEN (value, 0); i += 2)
4156 find_attrs_to_cache (XVECEXP (value, 0, i), false);
4157 attrs_to_cache |= attrs_seen_more_than_once;
4160 for (i = 0; i < XVECLEN (value, 0); i += 2)
4162 rtx testexp;
4163 rtx inner_true;
4165 /* Reset our_known_true after some time to not accumulate
4166 too much cruft (slowing down genattrtab). */
4167 if ((i & 31) == 0)
4168 our_known_true = known_true;
4169 testexp = eliminate_known_true (our_known_true,
4170 XVECEXP (value, 0, i),
4171 insn_code, insn_index);
4172 newexp = attr_rtx (NOT, testexp);
4173 newexp = insert_right_side (AND, our_known_true, newexp,
4174 insn_code, insn_index);
4176 /* If the test expression is always true or if the next `known_true'
4177 expression is always false, this is the last case, so break
4178 out and let this value be the `else' case. */
4179 if (testexp == true_rtx || newexp == false_rtx)
4181 default_val = XVECEXP (value, 0, i + 1);
4182 break;
4185 /* Compute the expression to pass to our recursive call as being
4186 known true. */
4187 inner_true = insert_right_side (AND, our_known_true,
4188 testexp, insn_code, insn_index);
4190 /* If this is always false, skip it. */
4191 if (inner_true == false_rtx)
4192 continue;
4194 attrs_cached_inside = attrs_cached;
4195 attrs_cached_after = attrs_cached;
4196 write_indent (outf, indent);
4197 fprintf (outf, "%sif ", first_if ? "" : "else ");
4198 first_if = 0;
4199 write_test_expr (outf, testexp, attrs_cached,
4200 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4201 attrs_cached = attrs_cached_after;
4202 fprintf (outf, "\n");
4203 write_indent (outf, indent + 2);
4204 fprintf (outf, "{\n");
4206 write_attr_set (outf, attr, indent + 4,
4207 XVECEXP (value, 0, i + 1), prefix, suffix,
4208 inner_true, insn_code, insn_index,
4209 attrs_cached_inside);
4210 write_indent (outf, indent + 2);
4211 fprintf (outf, "}\n");
4212 our_known_true = newexp;
4215 if (! first_if)
4217 write_indent (outf, indent);
4218 fprintf (outf, "else\n");
4219 write_indent (outf, indent + 2);
4220 fprintf (outf, "{\n");
4223 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4224 prefix, suffix, our_known_true, insn_code, insn_index,
4225 attrs_cached);
4227 if (! first_if)
4229 write_indent (outf, indent + 2);
4230 fprintf (outf, "}\n");
4233 else
4235 write_indent (outf, indent);
4236 fprintf (outf, "%s ", prefix);
4237 write_attr_value (outf, attr, value);
4238 fprintf (outf, "%s\n", suffix);
4242 /* Write a series of case statements for every instruction in list IE.
4243 INDENT is the amount of indentation to write before each case. */
4245 static void
4246 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4248 for (; ie != 0; ie = ie->next)
4249 if (ie->def->insn_code != -1)
4251 write_indent (outf, indent);
4252 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4253 fprintf (outf, "case %d: /* define_peephole, %s:%d */\n",
4254 ie->def->insn_code, ie->def->loc.filename,
4255 ie->def->loc.lineno);
4256 else
4257 fprintf (outf, "case %d: /* %s */\n",
4258 ie->def->insn_code, XSTR (ie->def->def, 0));
4262 /* Write out the computation for one attribute value. */
4264 static void
4265 write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
4266 int write_case_lines, const char *prefix, const char *suffix,
4267 int indent, rtx known_true)
4269 if (av->num_insns == 0)
4270 return;
4272 if (av->has_asm_insn)
4274 write_indent (outf, indent);
4275 fprintf (outf, "case -1:\n");
4276 write_indent (outf, indent + 2);
4277 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4278 write_indent (outf, indent + 2);
4279 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
4280 write_indent (outf, indent + 2);
4281 fprintf (outf, " fatal_insn_not_found (insn);\n");
4284 if (write_case_lines)
4285 write_insn_cases (outf, av->first_insn, indent);
4286 else
4288 write_indent (outf, indent);
4289 fprintf (outf, "default:\n");
4292 /* See what we have to do to output this value. */
4293 must_extract = must_constrain = address_used = 0;
4294 walk_attr_value (av->value);
4296 if (must_constrain)
4298 write_indent (outf, indent + 2);
4299 fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4301 else if (must_extract)
4303 write_indent (outf, indent + 2);
4304 fprintf (outf, "extract_insn_cached (insn);\n");
4307 attrs_to_cache = 0;
4308 if (av->num_insns == 1)
4309 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4310 known_true, av->first_insn->def->insn_code,
4311 av->first_insn->def->insn_index, 0);
4312 else
4313 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4314 known_true, -2, 0, 0);
4316 if (strncmp (prefix, "return", 6))
4318 write_indent (outf, indent + 2);
4319 fprintf (outf, "break;\n");
4321 fprintf (outf, "\n");
4324 /* Utilities to write in various forms. */
4326 static void
4327 write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
4329 if (attr->is_numeric)
4331 int num = atoi (s);
4333 fprintf (outf, "%d", num);
4335 if (num > 9 || num < 0)
4336 fprintf (outf, " /* %#x */", num);
4338 else
4340 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4341 fprintf (outf, "_");
4342 write_upcase (outf, s);
4346 static void
4347 write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
4349 int op;
4351 switch (GET_CODE (value))
4353 case CONST_STRING:
4354 write_attr_valueq (outf, attr, XSTR (value, 0));
4355 break;
4357 case CONST_INT:
4358 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4359 break;
4361 case SYMBOL_REF:
4362 fprint_c_condition (outf, XSTR (value, 0));
4363 break;
4365 case ATTR:
4367 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4368 if (attr->enum_name)
4369 fprintf (outf, "(enum %s)", attr->enum_name);
4370 else if (!attr->is_numeric)
4371 fprintf (outf, "(enum attr_%s)", attr->name);
4372 else if (!attr2->is_numeric)
4373 fprintf (outf, "(int)");
4375 fprintf (outf, "get_attr_%s (%s)", attr2->name,
4376 (attr2->is_const ? "" : "insn"));
4378 break;
4380 case PLUS:
4381 op = '+';
4382 goto do_operator;
4383 case MINUS:
4384 op = '-';
4385 goto do_operator;
4386 case MULT:
4387 op = '*';
4388 goto do_operator;
4389 case DIV:
4390 op = '/';
4391 goto do_operator;
4392 case MOD:
4393 op = '%';
4394 goto do_operator;
4396 do_operator:
4397 write_attr_value (outf, attr, XEXP (value, 0));
4398 fputc (' ', outf);
4399 fputc (op, outf);
4400 fputc (' ', outf);
4401 write_attr_value (outf, attr, XEXP (value, 1));
4402 break;
4404 default:
4405 gcc_unreachable ();
4409 static void
4410 write_upcase (FILE *outf, const char *str)
4412 while (*str)
4414 /* The argument of TOUPPER should not have side effects. */
4415 fputc (TOUPPER (*str), outf);
4416 str++;
4420 static void
4421 write_indent (FILE *outf, int indent)
4423 for (; indent > 8; indent -= 8)
4424 fprintf (outf, "\t");
4426 for (; indent; indent--)
4427 fprintf (outf, " ");
4430 /* If the target does not have annul-true or annul-false delay slots, this
4431 function will create a dummy eligible_for function on OUTF which always
4432 returns false. KIND will be annul_true or annul_false. */
4434 static void
4435 write_dummy_eligible_delay (FILE *outf, const char *kind)
4437 /* Write function prelude. */
4439 fprintf (outf, "int\n");
4440 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4441 " int slot ATTRIBUTE_UNUSED,\n"
4442 " rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4443 " int flags ATTRIBUTE_UNUSED)\n",
4444 kind);
4445 fprintf (outf, "{\n");
4446 fprintf (outf, " return 0;\n");
4447 fprintf (outf, "}\n\n");
4450 /* Write a subroutine that is given an insn that requires a delay slot, a
4451 delay slot ordinal, and a candidate insn. It returns nonzero if the
4452 candidate can be placed in the specified delay slot of the insn.
4454 We can write as many as three subroutines. `eligible_for_delay'
4455 handles normal delay slots, `eligible_for_annul_true' indicates that
4456 the specified insn can be annulled if the branch is true, and likewise
4457 for `eligible_for_annul_false'.
4459 KIND is a string distinguishing these three cases ("delay", "annul_true",
4460 or "annul_false"). */
4462 static void
4463 write_eligible_delay (FILE *outf, const char *kind)
4465 struct delay_desc *delay;
4466 int max_slots;
4467 char str[50];
4468 const char *pstr;
4469 struct attr_desc *attr;
4470 struct attr_value *av, *common_av;
4471 int i;
4473 /* Compute the maximum number of delay slots required. We use the delay
4474 ordinal times this number plus one, plus the slot number as an index into
4475 the appropriate predicate to test. */
4477 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4478 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4479 max_slots = XVECLEN (delay->def, 1) / 3;
4481 /* Write function prelude. */
4483 fprintf (outf, "int\n");
4484 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4485 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4486 kind);
4487 fprintf (outf, "{\n");
4488 fprintf (outf, " rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4489 fprintf (outf, "\n");
4490 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
4491 fprintf (outf, "\n");
4492 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4493 converts a compound instruction into a loop. */
4494 fprintf (outf, " if (!INSN_P (candidate_insn))\n");
4495 fprintf (outf, " return 0;\n");
4496 fprintf (outf, "\n");
4498 /* If more than one delay type, find out which type the delay insn is. */
4500 if (num_delays > 1)
4502 attr = find_attr (&delay_type_str, 0);
4503 gcc_assert (attr);
4504 common_av = find_most_used (attr);
4506 fprintf (outf, " insn = delay_insn;\n");
4507 fprintf (outf, " switch (recog_memoized (insn))\n");
4508 fprintf (outf, " {\n");
4510 sprintf (str, " * %d;\n break;", max_slots);
4511 for (av = attr->first_value; av; av = av->next)
4512 if (av != common_av)
4513 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4515 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4516 fprintf (outf, " }\n\n");
4518 /* Ensure matched. Otherwise, shouldn't have been called. */
4519 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
4522 /* If just one type of delay slot, write simple switch. */
4523 if (num_delays == 1 && max_slots == 1)
4525 fprintf (outf, " insn = candidate_insn;\n");
4526 fprintf (outf, " switch (recog_memoized (insn))\n");
4527 fprintf (outf, " {\n");
4529 attr = find_attr (&delay_1_0_str, 0);
4530 gcc_assert (attr);
4531 common_av = find_most_used (attr);
4533 for (av = attr->first_value; av; av = av->next)
4534 if (av != common_av)
4535 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4537 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4538 fprintf (outf, " }\n");
4541 else
4543 /* Write a nested CASE. The first indicates which condition we need to
4544 test, and the inner CASE tests the condition. */
4545 fprintf (outf, " insn = candidate_insn;\n");
4546 fprintf (outf, " switch (slot)\n");
4547 fprintf (outf, " {\n");
4549 for (delay = delays; delay; delay = delay->next)
4550 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4552 fprintf (outf, " case %d:\n",
4553 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4554 fprintf (outf, " switch (recog_memoized (insn))\n");
4555 fprintf (outf, "\t{\n");
4557 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4558 pstr = str;
4559 attr = find_attr (&pstr, 0);
4560 gcc_assert (attr);
4561 common_av = find_most_used (attr);
4563 for (av = attr->first_value; av; av = av->next)
4564 if (av != common_av)
4565 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4567 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4568 fprintf (outf, " }\n");
4571 fprintf (outf, " default:\n");
4572 fprintf (outf, " gcc_unreachable ();\n");
4573 fprintf (outf, " }\n");
4576 fprintf (outf, "}\n\n");
4579 /* This page contains miscellaneous utility routines. */
4581 /* Given a pointer to a (char *), return a malloc'ed string containing the
4582 next comma-separated element. Advance the pointer to after the string
4583 scanned, or the end-of-string. Return NULL if at end of string. */
4585 static char *
4586 next_comma_elt (const char **pstr)
4588 const char *start;
4590 start = scan_comma_elt (pstr);
4592 if (start == NULL)
4593 return NULL;
4595 return attr_string (start, *pstr - start);
4598 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4599 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4600 replaced by a pointer to a canonical copy of the string. */
4602 static struct attr_desc *
4603 find_attr (const char **name_p, int create)
4605 struct attr_desc *attr;
4606 int index;
4607 const char *name = *name_p;
4609 /* Before we resort to using `strcmp', see if the string address matches
4610 anywhere. In most cases, it should have been canonicalized to do so. */
4611 if (name == alternative_name)
4612 return NULL;
4614 index = name[0] & (MAX_ATTRS_INDEX - 1);
4615 for (attr = attrs[index]; attr; attr = attr->next)
4616 if (name == attr->name)
4617 return attr;
4619 /* Otherwise, do it the slow way. */
4620 for (attr = attrs[index]; attr; attr = attr->next)
4621 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4623 *name_p = attr->name;
4624 return attr;
4627 if (! create)
4628 return NULL;
4630 attr = oballoc (struct attr_desc);
4631 attr->name = DEF_ATTR_STRING (name);
4632 attr->enum_name = 0;
4633 attr->first_value = attr->default_val = NULL;
4634 attr->is_numeric = attr->is_const = attr->is_special = 0;
4635 attr->next = attrs[index];
4636 attrs[index] = attr;
4638 *name_p = attr->name;
4640 return attr;
4643 /* Create internal attribute with the given default value. */
4645 static void
4646 make_internal_attr (const char *name, rtx value, int special)
4648 struct attr_desc *attr;
4650 attr = find_attr (&name, 1);
4651 gcc_assert (!attr->default_val);
4653 attr->is_numeric = 1;
4654 attr->is_const = 0;
4655 attr->is_special = (special & ATTR_SPECIAL) != 0;
4656 attr->default_val = get_attr_value (file_location ("<internal>", 0),
4657 value, attr, -2);
4660 /* Find the most used value of an attribute. */
4662 static struct attr_value *
4663 find_most_used (struct attr_desc *attr)
4665 struct attr_value *av;
4666 struct attr_value *most_used;
4667 int nuses;
4669 most_used = NULL;
4670 nuses = -1;
4672 for (av = attr->first_value; av; av = av->next)
4673 if (av->num_insns > nuses)
4674 nuses = av->num_insns, most_used = av;
4676 return most_used;
4679 /* Return (attr_value "n") */
4681 static rtx
4682 make_numeric_value (int n)
4684 static rtx int_values[20];
4685 rtx exp;
4686 char *p;
4688 gcc_assert (n >= 0);
4690 if (n < 20 && int_values[n])
4691 return int_values[n];
4693 p = attr_printf (MAX_DIGITS, "%d", n);
4694 exp = attr_rtx (CONST_STRING, p);
4696 if (n < 20)
4697 int_values[n] = exp;
4699 return exp;
4702 static rtx
4703 copy_rtx_unchanging (rtx orig)
4705 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4706 return orig;
4708 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4709 return orig;
4712 /* Determine if an insn has a constant number of delay slots, i.e., the
4713 number of delay slots is not a function of the length of the insn. */
4715 static void
4716 write_const_num_delay_slots (FILE *outf)
4718 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4719 struct attr_value *av;
4721 if (attr)
4723 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4724 fprintf (outf, "{\n");
4725 fprintf (outf, " switch (recog_memoized (insn))\n");
4726 fprintf (outf, " {\n");
4728 for (av = attr->first_value; av; av = av->next)
4730 length_used = 0;
4731 walk_attr_value (av->value);
4732 if (length_used)
4733 write_insn_cases (outf, av->first_insn, 4);
4736 fprintf (outf, " default:\n");
4737 fprintf (outf, " return 1;\n");
4738 fprintf (outf, " }\n}\n\n");
4742 /* Synthetic attributes used by insn-automata.c and the scheduler.
4743 These are primarily concerned with (define_insn_reservation)
4744 patterns. */
4746 struct insn_reserv
4748 struct insn_reserv *next;
4750 const char *name;
4751 int default_latency;
4752 rtx condexp;
4754 /* Sequence number of this insn. */
4755 int insn_num;
4757 /* Whether a (define_bypass) construct names this insn in its
4758 output list. */
4759 bool bypassed;
4762 static struct insn_reserv *all_insn_reservs = 0;
4763 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4764 static size_t n_insn_reservs;
4766 /* Store information from a DEFINE_INSN_RESERVATION for future
4767 attribute generation. */
4768 static void
4769 gen_insn_reserv (md_rtx_info *info)
4771 struct insn_reserv *decl = oballoc (struct insn_reserv);
4772 rtx def = info->def;
4774 struct attr_desc attr;
4775 memset (&attr, 0, sizeof (attr));
4776 attr.name = DEF_ATTR_STRING (XSTR (def, 0));
4777 attr.loc = info->loc;
4779 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4780 decl->default_latency = XINT (def, 1);
4781 decl->condexp = check_attr_test (info->loc, XEXP (def, 2), &attr);
4782 decl->insn_num = n_insn_reservs;
4783 decl->bypassed = false;
4784 decl->next = 0;
4786 *last_insn_reserv_p = decl;
4787 last_insn_reserv_p = &decl->next;
4788 n_insn_reservs++;
4791 /* Store information from a DEFINE_BYPASS for future attribute
4792 generation. The only thing we care about is the list of output
4793 insns, which will later be used to tag reservation structures with
4794 a 'bypassed' bit. */
4796 struct bypass_list
4798 struct bypass_list *next;
4799 const char *pattern;
4802 static struct bypass_list *all_bypasses;
4803 static size_t n_bypasses;
4804 static size_t n_bypassed;
4806 static void
4807 gen_bypass_1 (const char *s, size_t len)
4809 struct bypass_list *b;
4811 if (len == 0)
4812 return;
4814 s = attr_string (s, len);
4815 for (b = all_bypasses; b; b = b->next)
4816 if (s == b->pattern)
4817 return; /* already got that one */
4819 b = oballoc (struct bypass_list);
4820 b->pattern = s;
4821 b->next = all_bypasses;
4822 all_bypasses = b;
4823 n_bypasses++;
4826 static void
4827 gen_bypass (md_rtx_info *info)
4829 const char *p, *base;
4831 rtx def = info->def;
4832 for (p = base = XSTR (def, 1); *p; p++)
4833 if (*p == ',')
4835 gen_bypass_1 (base, p - base);
4837 p++;
4838 while (ISSPACE (*p));
4839 base = p;
4841 gen_bypass_1 (base, p - base);
4844 /* Find and mark all of the bypassed insns. */
4845 static void
4846 process_bypasses (void)
4848 struct bypass_list *b;
4849 struct insn_reserv *r;
4851 n_bypassed = 0;
4853 /* The reservation list is likely to be much longer than the bypass
4854 list. */
4855 for (r = all_insn_reservs; r; r = r->next)
4856 for (b = all_bypasses; b; b = b->next)
4857 if (fnmatch (b->pattern, r->name, 0) == 0)
4859 n_bypassed++;
4860 r->bypassed = true;
4861 break;
4865 /* Check that attribute NAME is used in define_insn_reservation condition
4866 EXP. Return true if it is. */
4867 static bool
4868 check_tune_attr (const char *name, rtx exp)
4870 switch (GET_CODE (exp))
4872 case AND:
4873 if (check_tune_attr (name, XEXP (exp, 0)))
4874 return true;
4875 return check_tune_attr (name, XEXP (exp, 1));
4877 case IOR:
4878 return (check_tune_attr (name, XEXP (exp, 0))
4879 && check_tune_attr (name, XEXP (exp, 1)));
4881 case EQ_ATTR:
4882 return XSTR (exp, 0) == name;
4884 default:
4885 return false;
4889 /* Try to find a const attribute (usually cpu or tune) that is used
4890 in all define_insn_reservation conditions. */
4891 static struct attr_desc *
4892 find_tune_attr (rtx exp)
4894 struct attr_desc *attr;
4896 switch (GET_CODE (exp))
4898 case AND:
4899 case IOR:
4900 attr = find_tune_attr (XEXP (exp, 0));
4901 if (attr)
4902 return attr;
4903 return find_tune_attr (XEXP (exp, 1));
4905 case EQ_ATTR:
4906 if (XSTR (exp, 0) == alternative_name)
4907 return NULL;
4909 attr = find_attr (&XSTR (exp, 0), 0);
4910 gcc_assert (attr);
4912 if (attr->is_const && !attr->is_special)
4914 struct insn_reserv *decl;
4916 for (decl = all_insn_reservs; decl; decl = decl->next)
4917 if (! check_tune_attr (attr->name, decl->condexp))
4918 return NULL;
4919 return attr;
4921 return NULL;
4923 default:
4924 return NULL;
4928 /* Create all of the attributes that describe automaton properties.
4929 Write the DFA and latency function prototypes to the files that
4930 need to have them, and write the init_sched_attrs(). */
4932 static void
4933 make_automaton_attrs (void)
4935 int i;
4936 struct insn_reserv *decl;
4937 rtx code_exp, lats_exp, byps_exp;
4938 struct attr_desc *tune_attr;
4940 if (n_insn_reservs == 0)
4941 return;
4943 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4944 if (tune_attr != NULL)
4946 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4947 struct attr_value *val;
4948 bool first = true;
4950 gcc_assert (tune_attr->is_const
4951 && !tune_attr->is_special
4952 && !tune_attr->is_numeric);
4954 /* Write the prototypes for all DFA functions. */
4955 for (val = tune_attr->first_value; val; val = val->next)
4957 if (val == tune_attr->default_val)
4958 continue;
4959 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4960 fprintf (dfa_file,
4961 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4962 XSTR (val->value, 0));
4964 fprintf (dfa_file, "\n");
4966 /* Write the prototypes for all latency functions. */
4967 for (val = tune_attr->first_value; val; val = val->next)
4969 if (val == tune_attr->default_val)
4970 continue;
4971 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4972 fprintf (latency_file,
4973 "extern int insn_default_latency_%s (rtx_insn *);\n",
4974 XSTR (val->value, 0));
4976 fprintf (latency_file, "\n");
4978 /* Write the prototypes for all automaton functions. */
4979 for (val = tune_attr->first_value; val; val = val->next)
4981 if (val == tune_attr->default_val)
4982 continue;
4983 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4984 fprintf (attr_file,
4985 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4986 "extern int insn_default_latency_%s (rtx_insn *);\n",
4987 XSTR (val->value, 0), XSTR (val->value, 0));
4989 fprintf (attr_file, "\n");
4990 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4991 fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n");
4992 fprintf (attr_file, "\n");
4993 fprintf (attr_file, "void\n");
4994 fprintf (attr_file, "init_sched_attrs (void)\n");
4995 fprintf (attr_file, "{\n");
4997 for (val = tune_attr->first_value; val; val = val->next)
4999 int j;
5000 char *name;
5001 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
5003 if (val == tune_attr->default_val)
5004 continue;
5005 for (decl = all_insn_reservs, i = 0;
5006 decl;
5007 decl = decl->next)
5009 rtx ctest = test;
5010 rtx condexp
5011 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
5012 if (condexp == false_rtx)
5013 continue;
5014 if (condexp == true_rtx)
5015 break;
5016 condexps[i] = condexp;
5017 condexps[i + 1] = make_numeric_value (decl->insn_num);
5018 condexps[i + 2] = make_numeric_value (decl->default_latency);
5019 i += 3;
5022 code_exp = rtx_alloc (COND);
5023 lats_exp = rtx_alloc (COND);
5025 j = i / 3 * 2;
5026 XVEC (code_exp, 0) = rtvec_alloc (j);
5027 XVEC (lats_exp, 0) = rtvec_alloc (j);
5029 if (decl)
5031 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
5032 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
5034 else
5036 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5037 XEXP (lats_exp, 1) = make_numeric_value (0);
5040 while (i > 0)
5042 i -= 3;
5043 j -= 2;
5044 XVECEXP (code_exp, 0, j) = condexps[i];
5045 XVECEXP (lats_exp, 0, j) = condexps[i];
5047 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
5048 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5051 name = XNEWVEC (char,
5052 sizeof ("*internal_dfa_insn_code_")
5053 + strlen (XSTR (val->value, 0)));
5054 strcpy (name, "*internal_dfa_insn_code_");
5055 strcat (name, XSTR (val->value, 0));
5056 make_internal_attr (name, code_exp, ATTR_NONE);
5057 strcpy (name, "*insn_default_latency_");
5058 strcat (name, XSTR (val->value, 0));
5059 make_internal_attr (name, lats_exp, ATTR_NONE);
5060 XDELETEVEC (name);
5062 if (first)
5064 fprintf (attr_file, " if (");
5065 first = false;
5067 else
5068 fprintf (attr_file, " else if (");
5069 write_test_expr (attr_file, test, 0, 0);
5070 fprintf (attr_file, ")\n");
5071 fprintf (attr_file, " {\n");
5072 fprintf (attr_file, " internal_dfa_insn_code\n");
5073 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
5074 XSTR (val->value, 0));
5075 fprintf (attr_file, " insn_default_latency\n");
5076 fprintf (attr_file, " = insn_default_latency_%s;\n",
5077 XSTR (val->value, 0));
5078 fprintf (attr_file, " }\n");
5081 fprintf (attr_file, " else\n");
5082 fprintf (attr_file, " gcc_unreachable ();\n");
5083 fprintf (attr_file, "}\n");
5084 fprintf (attr_file, "\n");
5086 XDELETEVEC (condexps);
5088 else
5090 code_exp = rtx_alloc (COND);
5091 lats_exp = rtx_alloc (COND);
5093 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5094 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5096 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5097 XEXP (lats_exp, 1) = make_numeric_value (0);
5099 for (decl = all_insn_reservs, i = 0;
5100 decl;
5101 decl = decl->next, i += 2)
5103 XVECEXP (code_exp, 0, i) = decl->condexp;
5104 XVECEXP (lats_exp, 0, i) = decl->condexp;
5106 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5107 XVECEXP (lats_exp, 0, i+1)
5108 = make_numeric_value (decl->default_latency);
5110 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5111 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
5114 if (n_bypasses == 0)
5115 byps_exp = make_numeric_value (0);
5116 else
5118 process_bypasses ();
5120 byps_exp = rtx_alloc (COND);
5121 XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2);
5122 XEXP (byps_exp, 1) = make_numeric_value (0);
5123 for (decl = all_insn_reservs, i = 0;
5124 decl;
5125 decl = decl->next)
5126 if (decl->bypassed)
5128 XVECEXP (byps_exp, 0, i) = decl->condexp;
5129 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5130 i += 2;
5134 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5137 static void
5138 write_header (FILE *outf)
5140 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5141 " from the machine description file `md'. */\n\n");
5143 fprintf (outf, "#include \"config.h\"\n");
5144 fprintf (outf, "#include \"system.h\"\n");
5145 fprintf (outf, "#include \"coretypes.h\"\n");
5146 fprintf (outf, "#include \"backend.h\"\n");
5147 fprintf (outf, "#include \"predict.h\"\n");
5148 fprintf (outf, "#include \"tree.h\"\n");
5149 fprintf (outf, "#include \"rtl.h\"\n");
5150 fprintf (outf, "#include \"alias.h\"\n");
5151 fprintf (outf, "#include \"options.h\"\n");
5152 fprintf (outf, "#include \"varasm.h\"\n");
5153 fprintf (outf, "#include \"stor-layout.h\"\n");
5154 fprintf (outf, "#include \"calls.h\"\n");
5155 fprintf (outf, "#include \"insn-attr.h\"\n");
5156 fprintf (outf, "#include \"tm_p.h\"\n");
5157 fprintf (outf, "#include \"insn-config.h\"\n");
5158 fprintf (outf, "#include \"recog.h\"\n");
5159 fprintf (outf, "#include \"regs.h\"\n");
5160 fprintf (outf, "#include \"real.h\"\n");
5161 fprintf (outf, "#include \"output.h\"\n");
5162 fprintf (outf, "#include \"toplev.h\"\n");
5163 fprintf (outf, "#include \"flags.h\"\n");
5164 fprintf (outf, "#include \"emit-rtl.h\"\n");
5165 fprintf (outf, "\n");
5166 fprintf (outf, "#define operands recog_data.operand\n\n");
5169 static FILE *
5170 open_outfile (const char *file_name)
5172 FILE *outf;
5173 outf = fopen (file_name, "w");
5174 if (! outf)
5175 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5176 write_header (outf);
5177 return outf;
5180 static bool
5181 handle_arg (const char *arg)
5183 switch (arg[1])
5185 case 'A':
5186 attr_file_name = &arg[2];
5187 return true;
5188 case 'D':
5189 dfa_file_name = &arg[2];
5190 return true;
5191 case 'L':
5192 latency_file_name = &arg[2];
5193 return true;
5194 default:
5195 return false;
5200 main (int argc, const char **argv)
5202 struct attr_desc *attr;
5203 struct insn_def *id;
5204 int i;
5206 progname = "genattrtab";
5208 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5209 return FATAL_EXIT_CODE;
5211 attr_file = open_outfile (attr_file_name);
5212 dfa_file = open_outfile (dfa_file_name);
5213 latency_file = open_outfile (latency_file_name);
5215 obstack_init (hash_obstack);
5216 obstack_init (temp_obstack);
5218 /* Set up true and false rtx's */
5219 true_rtx = rtx_alloc (CONST_INT);
5220 XWINT (true_rtx, 0) = 1;
5221 false_rtx = rtx_alloc (CONST_INT);
5222 XWINT (false_rtx, 0) = 0;
5223 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5224 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5226 alternative_name = DEF_ATTR_STRING ("alternative");
5227 length_str = DEF_ATTR_STRING ("length");
5228 delay_type_str = DEF_ATTR_STRING ("*delay_type");
5229 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5230 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5232 /* Read the machine description. */
5234 md_rtx_info info;
5235 while (read_md_rtx (&info))
5237 switch (GET_CODE (info.def))
5239 case DEFINE_INSN:
5240 case DEFINE_PEEPHOLE:
5241 case DEFINE_ASM_ATTRIBUTES:
5242 gen_insn (&info);
5243 break;
5245 case DEFINE_ATTR:
5246 case DEFINE_ENUM_ATTR:
5247 gen_attr (&info);
5248 break;
5250 case DEFINE_DELAY:
5251 gen_delay (&info);
5252 break;
5254 case DEFINE_INSN_RESERVATION:
5255 gen_insn_reserv (&info);
5256 break;
5258 case DEFINE_BYPASS:
5259 gen_bypass (&info);
5260 break;
5262 default:
5263 break;
5265 if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
5266 insn_index_number++;
5269 if (have_error)
5270 return FATAL_EXIT_CODE;
5272 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5273 if (! got_define_asm_attributes)
5275 md_rtx_info info;
5276 info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5277 XVEC (info.def, 0) = rtvec_alloc (0);
5278 info.loc = file_location ("<internal>", 0);
5279 info.index = -1;
5280 gen_insn (&info);
5283 /* Expand DEFINE_DELAY information into new attribute. */
5284 expand_delays ();
5286 /* Make `insn_alternatives'. */
5287 int num_insn_codes = get_num_insn_codes ();
5288 insn_alternatives = oballocvec (uint64_t, num_insn_codes);
5289 for (id = defs; id; id = id->next)
5290 if (id->insn_code >= 0)
5291 insn_alternatives[id->insn_code]
5292 = (((uint64_t) 1) << id->num_alternatives) - 1;
5294 /* Make `insn_n_alternatives'. */
5295 insn_n_alternatives = oballocvec (int, num_insn_codes);
5296 for (id = defs; id; id = id->next)
5297 if (id->insn_code >= 0)
5298 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5300 /* Construct extra attributes for automata. */
5301 make_automaton_attrs ();
5303 /* Prepare to write out attribute subroutines by checking everything stored
5304 away and building the attribute cases. */
5306 check_defs ();
5308 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5309 for (attr = attrs[i]; attr; attr = attr->next)
5310 attr->default_val->value
5311 = check_attr_value (attr->loc, attr->default_val->value, attr);
5313 if (have_error)
5314 return FATAL_EXIT_CODE;
5316 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5317 for (attr = attrs[i]; attr; attr = attr->next)
5318 fill_attr (attr);
5320 /* Construct extra attributes for `length'. */
5321 make_length_attrs ();
5323 /* Perform any possible optimizations to speed up compilation. */
5324 optimize_attrs (num_insn_codes);
5326 /* Now write out all the `gen_attr_...' routines. Do these before the
5327 special routines so that they get defined before they are used. */
5329 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5330 for (attr = attrs[i]; attr; attr = attr->next)
5332 FILE *outf;
5334 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5335 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5336 outf = dfa_file;
5337 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5338 outf = latency_file;
5339 else
5340 outf = attr_file;
5341 #undef IS_ATTR_GROUP
5343 if (! attr->is_special && ! attr->is_const)
5344 write_attr_get (outf, attr);
5347 /* Write out delay eligibility information, if DEFINE_DELAY present.
5348 (The function to compute the number of delay slots will be written
5349 below.) */
5350 write_eligible_delay (attr_file, "delay");
5351 if (have_annul_true)
5352 write_eligible_delay (attr_file, "annul_true");
5353 else
5354 write_dummy_eligible_delay (attr_file, "annul_true");
5355 if (have_annul_false)
5356 write_eligible_delay (attr_file, "annul_false");
5357 else
5358 write_dummy_eligible_delay (attr_file, "annul_false");
5360 /* Write out constant delay slot info. */
5361 write_const_num_delay_slots (attr_file);
5363 write_length_unit_log (attr_file);
5365 if (fclose (attr_file) != 0)
5366 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5367 if (fclose (dfa_file) != 0)
5368 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5369 if (fclose (latency_file) != 0)
5370 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5372 return SUCCESS_EXIT_CODE;