[PR target/115123] Fix testsuite fallout from sinking heuristic change
[official-gcc.git] / gcc / genattrtab.cc
blob1622ba951327bb1880104d29bb3d0b9280e10f66
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991-2025 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 class insn_def
138 public:
139 class insn_def *next; /* Next insn in chain. */
140 rtx def; /* The DEFINE_... */
141 int insn_code; /* Instruction number. */
142 int insn_index; /* Expression number in file, for errors. */
143 file_location loc; /* Where in the .md files it occurs. */
144 int num_alternatives; /* Number of alternatives. */
145 int vec_idx; /* Index of attribute vector in `def'. */
148 /* Once everything has been read in, we store in each attribute value a list
149 of insn codes that have that value. Here is the structure used for the
150 list. */
152 struct insn_ent
154 struct insn_ent *next; /* Next in chain. */
155 class insn_def *def; /* Instruction definition. */
158 /* Each value of an attribute (either constant or computed) is assigned a
159 structure which is used as the listhead of the insns that have that
160 value. */
162 struct attr_value
164 rtx value; /* Value of attribute. */
165 struct attr_value *next; /* Next attribute value in chain. */
166 struct insn_ent *first_insn; /* First insn with this value. */
167 int num_insns; /* Number of insns with this value. */
168 int has_asm_insn; /* True if this value used for `asm' insns */
171 /* Structure for each attribute. */
173 class attr_desc
175 public:
176 char *name; /* Name of attribute. */
177 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */
178 const char *cxx_type; /* The associated C++ type. */
179 class attr_desc *next; /* Next attribute. */
180 struct attr_value *first_value; /* First value of this attribute. */
181 struct attr_value *default_val; /* Default value for this attribute. */
182 file_location loc; /* Where in the .md files it occurs. */
183 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
184 unsigned is_const : 1; /* Attribute value constant for each run. */
185 unsigned is_special : 1; /* Don't call `write_attr_set'. */
188 /* Structure for each DEFINE_DELAY. */
190 class delay_desc
192 public:
193 rtx def; /* DEFINE_DELAY expression. */
194 class delay_desc *next; /* Next DEFINE_DELAY. */
195 file_location loc; /* Where in the .md files it occurs. */
196 int num; /* Number of DEFINE_DELAY, starting at 1. */
199 struct attr_value_list
201 struct attr_value *av;
202 struct insn_ent *ie;
203 class attr_desc *attr;
204 struct attr_value_list *next;
207 /* Listheads of above structures. */
209 /* This one is indexed by the first character of the attribute name. */
210 #define MAX_ATTRS_INDEX 256
211 static class attr_desc *attrs[MAX_ATTRS_INDEX];
212 static class insn_def *defs;
213 static class delay_desc *delays;
214 struct attr_value_list **insn_code_values;
216 /* Other variables. */
218 static int insn_index_number;
219 static int got_define_asm_attributes;
220 static int must_extract;
221 static int must_constrain;
222 static int address_used;
223 static int length_used;
224 static int num_delays;
225 static int have_annul_true, have_annul_false;
226 static int num_insn_ents;
228 /* Stores, for each insn code, the number of constraint alternatives. */
230 static int *insn_n_alternatives;
232 /* Stores, for each insn code, a bitmap that has bits on for each possible
233 alternative. */
235 /* Keep this in sync with recog.h. */
236 typedef uint64_t alternative_mask;
237 static alternative_mask *insn_alternatives;
239 /* Used to simplify expressions. */
241 static rtx true_rtx, false_rtx;
243 /* Used to reduce calls to `strcmp' */
245 static const char *alternative_name;
246 static const char *length_str;
247 static const char *delay_type_str;
248 static const char *delay_1_0_str;
249 static const char *num_delay_slots_str;
251 /* Simplify an expression. Only call the routine if there is something to
252 simplify. */
253 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
254 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
255 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
257 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
259 /* Forward declarations of functions used before their definitions, only. */
260 static char *attr_string (const char *, int);
261 static char *attr_printf (unsigned int, const char *, ...)
262 ATTRIBUTE_PRINTF_2;
263 static rtx make_numeric_value (int);
264 static class attr_desc *find_attr (const char **, int);
265 static rtx mk_attr_alt (alternative_mask);
266 static char *next_comma_elt (const char **);
267 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
268 static rtx copy_boolean (rtx);
269 static int compares_alternatives_p (rtx);
270 static void make_internal_attr (const char *, rtx, int);
271 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
272 static void walk_attr_value (rtx);
273 static int max_attr_value (rtx);
274 static int min_attr_value (rtx);
275 static unsigned int attr_value_alignment (rtx);
276 static rtx simplify_test_exp (rtx, int, int);
277 static rtx simplify_test_exp_in_temp (rtx, int, int);
278 static rtx copy_rtx_unchanging (rtx);
279 static bool attr_alt_subset_p (rtx, rtx);
280 static bool attr_alt_subset_of_compl_p (rtx, rtx);
281 static void clear_struct_flag (rtx);
282 static void write_attr_valueq (FILE *, class attr_desc *, const char *);
283 static struct attr_value *find_most_used (class attr_desc *);
284 static void write_attr_set (FILE *, class attr_desc *, int, rtx,
285 const char *, const char *, rtx,
286 int, int, unsigned int);
287 static void write_attr_case (FILE *, class attr_desc *,
288 struct attr_value *,
289 int, const char *, const char *, int, rtx);
290 static void write_attr_value (FILE *, class attr_desc *, rtx);
291 static void write_upcase (FILE *, const char *);
292 static void write_indent (FILE *, int);
293 static rtx identity_fn (rtx);
294 static rtx zero_fn (rtx);
295 static rtx one_fn (rtx);
296 static rtx max_fn (rtx);
297 static rtx min_fn (rtx);
299 #define oballoc(T) XOBNEW (hash_obstack, T)
300 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
302 /* This gen* file is unique, in that it writes out multiple files.
304 Before GCC 4.8, insn-attrtab.cc was written out containing many large
305 functions and tables. This made insn-attrtab.cc _the_ bottle-neck in
306 a parallel build, and even made it impossible to build GCC on machines
307 with relatively small RAM space (PR other/29442). Therefore, the
308 atrribute functions/tables are now written out to three separate
309 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
310 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
311 rest goes to ATTR_FILE_NAME. */
313 static const char *attr_file_name = NULL;
314 static const char *dfa_file_name = NULL;
315 static const char *latency_file_name = NULL;
317 static FILE *attr_file, *dfa_file, *latency_file;
319 /* Hash table for sharing RTL and strings. */
321 /* Each hash table slot is a bucket containing a chain of these structures.
322 Strings are given negative hash codes; RTL expressions are given positive
323 hash codes. */
325 struct attr_hash
327 struct attr_hash *next; /* Next structure in the bucket. */
328 unsigned int hashcode; /* Hash code of this rtx or string. */
329 union
331 char *str; /* The string (negative hash codes) */
332 rtx rtl; /* or the RTL recorded here. */
333 } u;
336 /* Now here is the hash table. When recording an RTL, it is added to
337 the slot whose index is the hash code mod the table size. Note
338 that the hash table is used for several kinds of RTL (see attr_rtx)
339 and for strings. While all these live in the same table, they are
340 completely independent, and the hash code is computed differently
341 for each. */
343 #define RTL_HASH_SIZE 4093
344 static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
346 /* Here is how primitive or already-shared RTL's hash
347 codes are made. */
348 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
350 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
352 static void
353 attr_hash_add_rtx (unsigned int hashcode, rtx rtl)
355 struct attr_hash *h;
357 h = XOBNEW (hash_obstack, struct attr_hash);
358 h->hashcode = hashcode;
359 h->u.rtl = rtl;
360 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
361 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
364 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
366 static void
367 attr_hash_add_string (unsigned int hashcode, char *str)
369 struct attr_hash *h;
371 h = XOBNEW (hash_obstack, struct attr_hash);
372 h->hashcode = -hashcode;
373 h->u.str = str;
374 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
375 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
378 /* Generate an RTL expression, but avoid duplicates.
379 Set the ATTR_PERMANENT_P flag for these permanent objects.
381 In some cases we cannot uniquify; then we return an ordinary
382 impermanent rtx with ATTR_PERMANENT_P clear.
384 Args are as follows:
386 rtx attr_rtx (code, [element1, ..., elementn]) */
388 static rtx
389 attr_rtx_1 (enum rtx_code code, va_list p)
391 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
392 unsigned int hashcode;
393 struct attr_hash *h;
394 struct obstack *old_obstack = rtl_obstack;
395 int permanent_p = 1;
397 /* For each of several cases, search the hash table for an existing entry.
398 Use that entry if one is found; otherwise create a new RTL and add it
399 to the table. */
401 if (GET_RTX_CLASS (code) == RTX_UNARY)
403 rtx arg0 = va_arg (p, rtx);
405 if (! ATTR_PERMANENT_P (arg0))
406 permanent_p = 0;
408 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
409 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
410 if (h->hashcode == hashcode
411 && GET_CODE (h->u.rtl) == code
412 && XEXP (h->u.rtl, 0) == arg0)
413 return h->u.rtl;
415 if (h == 0)
417 rtl_obstack = hash_obstack;
418 rt_val = rtx_alloc (code);
419 XEXP (rt_val, 0) = arg0;
422 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
423 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
424 || GET_RTX_CLASS (code) == RTX_COMPARE
425 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
427 rtx arg0 = va_arg (p, rtx);
428 rtx arg1 = va_arg (p, rtx);
430 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
431 permanent_p = 0;
433 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
434 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
435 if (h->hashcode == hashcode
436 && GET_CODE (h->u.rtl) == code
437 && XEXP (h->u.rtl, 0) == arg0
438 && XEXP (h->u.rtl, 1) == arg1)
440 ATTR_CURR_SIMPLIFIED_P (h->u.rtl) = 0;
441 return h->u.rtl;
444 if (h == 0)
446 rtl_obstack = hash_obstack;
447 rt_val = rtx_alloc (code);
448 XEXP (rt_val, 0) = arg0;
449 XEXP (rt_val, 1) = arg1;
452 else if (code == SYMBOL_REF
453 || (GET_RTX_LENGTH (code) == 1
454 && GET_RTX_FORMAT (code)[0] == 's'))
456 char *arg0 = va_arg (p, char *);
458 arg0 = DEF_ATTR_STRING (arg0);
460 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
461 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
462 if (h->hashcode == hashcode
463 && GET_CODE (h->u.rtl) == code
464 && XSTR (h->u.rtl, 0) == arg0)
465 return h->u.rtl;
467 if (h == 0)
469 rtl_obstack = hash_obstack;
470 rt_val = rtx_alloc (code);
471 XSTR (rt_val, 0) = arg0;
472 if (code == SYMBOL_REF)
473 X0EXP (rt_val, 1) = NULL_RTX;
476 else if (GET_RTX_LENGTH (code) == 2
477 && GET_RTX_FORMAT (code)[0] == 's'
478 && GET_RTX_FORMAT (code)[1] == 's')
480 char *arg0 = va_arg (p, char *);
481 char *arg1 = va_arg (p, char *);
483 arg0 = DEF_ATTR_STRING (arg0);
484 arg1 = DEF_ATTR_STRING (arg1);
486 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
487 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
488 if (h->hashcode == hashcode
489 && GET_CODE (h->u.rtl) == code
490 && XSTR (h->u.rtl, 0) == arg0
491 && XSTR (h->u.rtl, 1) == arg1)
492 return h->u.rtl;
494 if (h == 0)
496 rtl_obstack = hash_obstack;
497 rt_val = rtx_alloc (code);
498 XSTR (rt_val, 0) = arg0;
499 XSTR (rt_val, 1) = arg1;
502 else if (GET_RTX_LENGTH (code) == 2
503 && GET_RTX_FORMAT (code)[0] == 'w'
504 && GET_RTX_FORMAT (code)[1] == 'w')
506 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
507 HOST_WIDE_INT arg1 = va_arg (p, HOST_WIDE_INT);
509 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
510 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
511 if (h->hashcode == hashcode
512 && GET_CODE (h->u.rtl) == code
513 && XWINT (h->u.rtl, 0) == arg0
514 && XWINT (h->u.rtl, 1) == arg1)
515 return h->u.rtl;
517 if (h == 0)
519 rtl_obstack = hash_obstack;
520 rt_val = rtx_alloc (code);
521 XWINT (rt_val, 0) = arg0;
522 XWINT (rt_val, 1) = arg1;
525 else if (code == CONST_INT)
527 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
528 if (arg0 == 0)
529 return false_rtx;
530 else if (arg0 == 1)
531 return true_rtx;
532 else
533 goto nohash;
535 else
537 int i; /* Array indices... */
538 const char *fmt; /* Current rtx's format... */
539 nohash:
540 rt_val = rtx_alloc (code); /* Allocate the storage space. */
542 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
543 for (i = 0; i < GET_RTX_LENGTH (code); i++)
545 switch (*fmt++)
547 case '0': /* Unused field. */
548 break;
550 case 'i': /* An integer? */
551 XINT (rt_val, i) = va_arg (p, int);
552 break;
554 case 'L': /* A location_t? */
555 XLOC (rt_val, i) = va_arg (p, location_t);
556 break;
558 case 'w': /* A wide integer? */
559 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
560 break;
562 case 's': /* A string? */
563 XSTR (rt_val, i) = va_arg (p, char *);
564 break;
566 case 'e': /* An expression? */
567 case 'u': /* An insn? Same except when printing. */
568 XEXP (rt_val, i) = va_arg (p, rtx);
569 break;
571 case 'E': /* An RTX vector? */
572 XVEC (rt_val, i) = va_arg (p, rtvec);
573 break;
575 default:
576 /* Don't need to handle 'p' for attributes. */
577 gcc_unreachable ();
580 return rt_val;
583 rtl_obstack = old_obstack;
584 attr_hash_add_rtx (hashcode, rt_val);
585 ATTR_PERMANENT_P (rt_val) = permanent_p;
586 return rt_val;
589 static rtx
590 attr_rtx (enum rtx_code code, ...)
592 rtx result;
593 va_list p;
595 va_start (p, code);
596 result = attr_rtx_1 (code, p);
597 va_end (p);
598 return result;
601 /* Create a new string printed with the printf line arguments into a space
602 of at most LEN bytes:
604 rtx attr_printf (len, format, [arg1, ..., argn]) */
606 static char *
607 attr_printf (unsigned int len, const char *fmt, ...)
609 char str[256];
610 va_list p;
612 va_start (p, fmt);
614 gcc_assert (len < sizeof str); /* Leave room for \0. */
616 vsprintf (str, fmt, p);
617 va_end (p);
619 return DEF_ATTR_STRING (str);
622 static rtx
623 attr_eq (const char *name, const char *value)
625 return attr_rtx (EQ_ATTR, name, value);
628 static const char *
629 attr_numeral (int n)
631 return XSTR (make_numeric_value (n), 0);
634 /* Return a permanent (possibly shared) copy of a string STR (not assumed
635 to be null terminated) with LEN bytes. */
637 static char *
638 attr_string (const char *str, int len)
640 struct attr_hash *h;
641 unsigned int hashcode;
642 int i;
643 char *new_str;
645 /* Compute the hash code. */
646 hashcode = (len + 1) * 613U + (unsigned) str[0];
647 for (i = 1; i < len; i += 2)
648 hashcode = ((hashcode * 613) + (unsigned) str[i]);
649 if ((int) hashcode < 0)
650 hashcode = -hashcode;
652 /* Search the table for the string. */
653 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
654 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
655 && !strncmp (h->u.str, str, len))
656 return h->u.str; /* <-- return if found. */
658 /* Not found; create a permanent copy and add it to the hash table. */
659 new_str = XOBNEWVAR (hash_obstack, char, len + 1);
660 memcpy (new_str, str, len);
661 new_str[len] = '\0';
662 attr_hash_add_string (hashcode, new_str);
663 rtx_reader_ptr->copy_md_ptr_loc (new_str, str);
665 return new_str; /* Return the new string. */
668 /* Check two rtx's for equality of contents,
669 taking advantage of the fact that if both are hashed
670 then they can't be equal unless they are the same object. */
672 static int
673 attr_equal_p (rtx x, rtx y)
675 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
676 && rtx_equal_p (x, y)));
679 /* Given a test expression EXP for attribute ATTR, ensure it is validly
680 formed. LOC is the location of the .md construct that contains EXP.
682 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
683 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
684 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
686 Update the string address in EQ_ATTR expression to be the same used
687 in the attribute (or `alternative_name') to speed up subsequent
688 `find_attr' calls and eliminate most `strcmp' calls.
690 Return the new expression, if any. */
692 static rtx
693 check_attr_test (file_location loc, rtx exp, attr_desc *attr)
695 struct attr_value *av;
696 const char *name_ptr, *p;
697 rtx orexp, newexp;
699 switch (GET_CODE (exp))
701 case EQ_ATTR:
702 /* Handle negation test. */
703 if (XSTR (exp, 1)[0] == '!')
704 return check_attr_test (loc,
705 attr_rtx (NOT,
706 attr_eq (XSTR (exp, 0),
707 &XSTR (exp, 1)[1])),
708 attr);
710 else if (n_comma_elts (XSTR (exp, 1)) == 1)
712 attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
713 if (attr2 == NULL)
715 if (! strcmp (XSTR (exp, 0), "alternative"))
716 return mk_attr_alt (((alternative_mask) 1)
717 << atoi (XSTR (exp, 1)));
718 else
719 fatal_at (loc, "unknown attribute `%s' in definition of"
720 " attribute `%s'", XSTR (exp, 0), attr->name);
723 if (attr->is_const && ! attr2->is_const)
724 fatal_at (loc, "constant attribute `%s' cannot test non-constant"
725 " attribute `%s'", attr->name, attr2->name);
727 /* Copy this just to make it permanent,
728 so expressions using it can be permanent too. */
729 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
731 /* It shouldn't be possible to simplify the value given to a
732 constant attribute, so don't expand this until it's time to
733 write the test expression. */
734 if (attr2->is_const)
735 ATTR_IND_SIMPLIFIED_P (exp) = 1;
737 if (attr2->is_numeric)
739 for (p = XSTR (exp, 1); *p; p++)
740 if (! ISDIGIT (*p))
741 fatal_at (loc, "attribute `%s' takes only numeric values",
742 attr2->name);
744 else
746 for (av = attr2->first_value; av; av = av->next)
747 if (GET_CODE (av->value) == CONST_STRING
748 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
749 break;
751 if (av == NULL)
752 fatal_at (loc, "unknown value `%s' for attribute `%s'",
753 XSTR (exp, 1), attr2->name);
756 else
758 if (! strcmp (XSTR (exp, 0), "alternative"))
760 int set = 0;
762 name_ptr = XSTR (exp, 1);
763 while ((p = next_comma_elt (&name_ptr)) != NULL)
764 set |= ((alternative_mask) 1) << atoi (p);
766 return mk_attr_alt (set);
768 else
770 /* Make an IOR tree of the possible values. */
771 orexp = false_rtx;
772 name_ptr = XSTR (exp, 1);
773 while ((p = next_comma_elt (&name_ptr)) != NULL)
775 newexp = attr_eq (XSTR (exp, 0), p);
776 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
779 return check_attr_test (loc, orexp, attr);
782 break;
784 case ATTR_FLAG:
785 break;
787 case CONST_INT:
788 /* Either TRUE or FALSE. */
789 if (XWINT (exp, 0))
790 return true_rtx;
791 else
792 return false_rtx;
794 case IOR:
795 case AND:
796 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
797 XEXP (exp, 1) = check_attr_test (loc, XEXP (exp, 1), attr);
798 break;
800 case NOT:
801 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
802 break;
804 case MATCH_TEST:
805 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
806 ATTR_IND_SIMPLIFIED_P (exp) = 1;
807 break;
809 case MATCH_OPERAND:
810 if (attr->is_const)
811 fatal_at (loc, "invalid operator `%s' in definition of constant"
812 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
813 attr->name);
814 /* These cases can't be simplified. */
815 ATTR_IND_SIMPLIFIED_P (exp) = 1;
816 break;
818 case LE: case LT: case GT: case GE:
819 case LEU: case LTU: case GTU: case GEU:
820 case NE: case EQ:
821 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
822 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
823 exp = attr_rtx (GET_CODE (exp),
824 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
825 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
826 /* These cases can't be simplified. */
827 ATTR_IND_SIMPLIFIED_P (exp) = 1;
828 break;
830 case SYMBOL_REF:
831 if (attr->is_const)
833 /* These cases are valid for constant attributes, but can't be
834 simplified. */
835 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
836 ATTR_IND_SIMPLIFIED_P (exp) = 1;
837 break;
839 /* FALLTHRU */
840 default:
841 fatal_at (loc, "invalid operator `%s' in definition of attribute"
842 " `%s'", GET_RTX_NAME (GET_CODE (exp)), attr->name);
845 return exp;
848 /* Given an expression EXP, ensure that it is validly formed and that
849 all named attribute values are valid for ATTR. Issue an error if not.
850 LOC is the location of the .md construct that contains EXP.
852 Return a perhaps modified replacement expression for the value. */
854 static rtx
855 check_attr_value (file_location loc, rtx exp, class attr_desc *attr)
857 struct attr_value *av;
858 const char *p;
859 int i;
861 switch (GET_CODE (exp))
863 case CONST_INT:
864 if (!attr->is_numeric)
866 error_at (loc,
867 "CONST_INT not valid for non-numeric attribute `%s'",
868 attr->name);
869 break;
872 if (INTVAL (exp) < 0)
874 error_at (loc,
875 "negative numeric value specified for attribute `%s'",
876 attr->name);
877 break;
879 break;
881 case CONST_STRING:
882 if (! strcmp (XSTR (exp, 0), "*"))
883 break;
885 if (attr->is_numeric)
887 p = XSTR (exp, 0);
888 for (; *p; p++)
889 if (! ISDIGIT (*p))
891 error_at (loc,
892 "non-numeric value specified for numeric"
893 " attribute `%s'", attr->name);
894 break;
896 break;
899 for (av = attr->first_value; av; av = av->next)
900 if (GET_CODE (av->value) == CONST_STRING
901 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
902 break;
904 if (av == NULL)
905 error_at (loc, "unknown value `%s' for attribute `%s'",
906 XSTR (exp, 0), attr->name);
907 break;
909 case IF_THEN_ELSE:
910 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
911 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
912 XEXP (exp, 2) = check_attr_value (loc, XEXP (exp, 2), attr);
913 break;
915 case PLUS:
916 case MINUS:
917 case MULT:
918 case DIV:
919 case MOD:
920 if (!attr->is_numeric)
922 error_at (loc, "invalid operation `%s' for non-numeric"
923 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
924 attr->name);
925 break;
927 /* Fall through. */
929 case IOR:
930 case AND:
931 XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
932 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
933 break;
935 case FFS:
936 case CLZ:
937 case CTZ:
938 case POPCOUNT:
939 case PARITY:
940 case BSWAP:
941 XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
942 break;
944 case COND:
945 if (XVECLEN (exp, 0) % 2 != 0)
947 error_at (loc, "first operand of COND must have even length");
948 break;
951 for (i = 0; i < XVECLEN (exp, 0); i += 2)
953 XVECEXP (exp, 0, i) = check_attr_test (attr->loc,
954 XVECEXP (exp, 0, i),
955 attr);
956 XVECEXP (exp, 0, i + 1)
957 = check_attr_value (loc, XVECEXP (exp, 0, i + 1), attr);
960 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
961 break;
963 case ATTR:
965 class attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
966 if (attr2 == NULL)
967 error_at (loc, "unknown attribute `%s' in ATTR",
968 XSTR (exp, 0));
969 else if (attr->is_const && ! attr2->is_const)
970 error_at (attr->loc,
971 "constant attribute `%s' cannot refer to non-constant"
972 " attribute `%s'", attr->name, attr2->name);
973 else if (attr->is_numeric != attr2->is_numeric)
974 error_at (loc,
975 "numeric attribute mismatch calling `%s' from `%s'",
976 attr2->name, attr->name);
978 break;
980 case SYMBOL_REF:
981 /* A constant SYMBOL_REF is valid as a constant attribute test and
982 is expanded later by make_canonical into a COND. In a non-constant
983 attribute test, it is left be. */
984 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
986 default:
987 error_at (loc, "invalid operator `%s' in definition of attribute `%s'",
988 GET_RTX_NAME (GET_CODE (exp)), attr->name);
989 break;
992 return exp;
995 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
996 It becomes a COND with each test being (eq_attr "alternative" "n") */
998 static rtx
999 convert_set_attr_alternative (rtx exp, class insn_def *id)
1001 int num_alt = id->num_alternatives;
1002 rtx condexp;
1003 int i;
1005 if (XVECLEN (exp, 1) != num_alt)
1007 error_at (id->loc, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1008 " was %d expected %d", XVECLEN (exp, 1), num_alt);
1009 return NULL_RTX;
1012 /* Make a COND with all tests but the last. Select the last value via the
1013 default. */
1014 condexp = rtx_alloc (COND);
1015 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1017 for (i = 0; i < num_alt - 1; i++)
1019 const char *p;
1020 p = attr_numeral (i);
1022 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1023 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1026 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1028 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1031 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1032 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1034 static rtx
1035 convert_set_attr (rtx exp, class insn_def *id)
1037 rtx newexp;
1038 const char *name_ptr;
1039 char *p;
1040 int n;
1042 /* See how many alternative specified. */
1043 n = n_comma_elts (XSTR (exp, 1));
1044 if (n == 1)
1045 return attr_rtx (SET,
1046 attr_rtx (ATTR, XSTR (exp, 0)),
1047 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1049 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1050 XSTR (newexp, 0) = XSTR (exp, 0);
1051 XVEC (newexp, 1) = rtvec_alloc (n);
1053 /* Process each comma-separated name. */
1054 name_ptr = XSTR (exp, 1);
1055 n = 0;
1056 while ((p = next_comma_elt (&name_ptr)) != NULL)
1057 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1059 return convert_set_attr_alternative (newexp, id);
1062 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1063 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1064 expressions. */
1066 static void
1067 check_defs (void)
1069 class insn_def *id;
1070 class attr_desc *attr;
1071 int i;
1072 rtx value;
1074 for (id = defs; id; id = id->next)
1076 if (XVEC (id->def, id->vec_idx) == NULL)
1077 continue;
1079 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1081 value = XVECEXP (id->def, id->vec_idx, i);
1082 switch (GET_CODE (value))
1084 case SET:
1085 if (GET_CODE (XEXP (value, 0)) != ATTR)
1087 error_at (id->loc, "bad attribute set");
1088 value = NULL_RTX;
1090 break;
1092 case SET_ATTR_ALTERNATIVE:
1093 value = convert_set_attr_alternative (value, id);
1094 break;
1096 case SET_ATTR:
1097 value = convert_set_attr (value, id);
1098 break;
1100 default:
1101 error_at (id->loc, "invalid attribute code %s",
1102 GET_RTX_NAME (GET_CODE (value)));
1103 value = NULL_RTX;
1105 if (value == NULL_RTX)
1106 continue;
1108 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1110 error_at (id->loc, "unknown attribute %s",
1111 XSTR (XEXP (value, 0), 0));
1112 continue;
1115 XVECEXP (id->def, id->vec_idx, i) = value;
1116 XEXP (value, 1) = check_attr_value (id->loc, XEXP (value, 1), attr);
1121 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1122 expressions by converting them into a COND. This removes cases from this
1123 program. Also, replace an attribute value of "*" with the default attribute
1124 value. LOC is the location to use for error reporting. */
1126 static rtx
1127 make_canonical (file_location loc, class attr_desc *attr, rtx exp)
1129 int i;
1130 rtx newexp;
1132 switch (GET_CODE (exp))
1134 case CONST_INT:
1135 exp = make_numeric_value (INTVAL (exp));
1136 break;
1138 case CONST_STRING:
1139 if (! strcmp (XSTR (exp, 0), "*"))
1141 if (attr->default_val == 0)
1142 fatal_at (loc, "(attr_value \"*\") used in invalid context");
1143 exp = attr->default_val->value;
1145 else
1146 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1148 break;
1150 case SYMBOL_REF:
1151 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1152 break;
1153 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1154 This makes the COND something that won't be considered an arbitrary
1155 expression by walk_attr_value. */
1156 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1157 exp = check_attr_value (loc, exp, attr);
1158 break;
1160 case IF_THEN_ELSE:
1161 newexp = rtx_alloc (COND);
1162 XVEC (newexp, 0) = rtvec_alloc (2);
1163 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1164 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1166 XEXP (newexp, 1) = XEXP (exp, 2);
1168 exp = newexp;
1169 /* Fall through to COND case since this is now a COND. */
1170 gcc_fallthrough ();
1172 case COND:
1174 int allsame = 1;
1175 rtx defval;
1177 /* First, check for degenerate COND. */
1178 if (XVECLEN (exp, 0) == 0)
1179 return make_canonical (loc, attr, XEXP (exp, 1));
1180 defval = XEXP (exp, 1) = make_canonical (loc, attr, XEXP (exp, 1));
1182 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1184 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1185 XVECEXP (exp, 0, i + 1)
1186 = make_canonical (loc, attr, XVECEXP (exp, 0, i + 1));
1187 if (! attr_equal_p (XVECEXP (exp, 0, i + 1), defval))
1188 allsame = 0;
1190 if (allsame)
1191 return defval;
1193 break;
1195 default:
1196 break;
1199 return exp;
1202 static rtx
1203 copy_boolean (rtx exp)
1205 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1206 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1207 copy_boolean (XEXP (exp, 1)));
1208 else if (GET_CODE (exp) == NOT)
1209 return attr_rtx (NOT, copy_boolean (XEXP (exp, 0)));
1210 if (GET_CODE (exp) == MATCH_OPERAND)
1212 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1213 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1215 else if (GET_CODE (exp) == EQ_ATTR)
1217 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1218 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1221 return exp;
1224 /* Given a value and an attribute description, return a `struct attr_value *'
1225 that represents that value. This is either an existing structure, if the
1226 value has been previously encountered, or a newly-created structure.
1228 `insn_code' is the code of an insn whose attribute has the specified
1229 value (-2 if not processing an insn). We ensure that all insns for
1230 a given value have the same number of alternatives if the value checks
1231 alternatives. LOC is the location to use for error reporting. */
1233 static struct attr_value *
1234 get_attr_value (file_location loc, rtx value, class attr_desc *attr,
1235 int insn_code)
1237 struct attr_value *av;
1238 alternative_mask num_alt = 0;
1240 value = make_canonical (loc, attr, value);
1241 if (compares_alternatives_p (value))
1243 if (insn_code < 0 || insn_alternatives == NULL)
1244 fatal_at (loc, "(eq_attr \"alternatives\" ...) used in non-insn"
1245 " context");
1246 else
1247 num_alt = insn_alternatives[insn_code];
1250 for (av = attr->first_value; av; av = av->next)
1251 if (attr_equal_p (value, av->value)
1252 && (num_alt == 0 || av->first_insn == NULL
1253 || insn_alternatives[av->first_insn->def->insn_code]))
1254 return av;
1256 av = oballoc (struct attr_value);
1257 av->value = value;
1258 av->next = attr->first_value;
1259 attr->first_value = av;
1260 av->first_insn = NULL;
1261 av->num_insns = 0;
1262 av->has_asm_insn = 0;
1264 return av;
1267 /* After all DEFINE_DELAYs have been read in, create internal attributes
1268 to generate the required routines.
1270 First, we compute the number of delay slots for each insn (as a COND of
1271 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1272 delay type is specified, we compute a similar function giving the
1273 DEFINE_DELAY ordinal for each insn.
1275 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1276 tells whether a given insn can be in that delay slot.
1278 Normal attribute filling and optimization expands these to contain the
1279 information needed to handle delay slots. */
1281 static void
1282 expand_delays (void)
1284 class delay_desc *delay;
1285 rtx condexp;
1286 rtx newexp;
1287 int i;
1288 char *p;
1290 /* First, generate data for `num_delay_slots' function. */
1292 condexp = rtx_alloc (COND);
1293 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1294 XEXP (condexp, 1) = make_numeric_value (0);
1296 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1298 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1299 XVECEXP (condexp, 0, i + 1)
1300 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1303 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1305 /* If more than one delay type, do the same for computing the delay type. */
1306 if (num_delays > 1)
1308 condexp = rtx_alloc (COND);
1309 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1310 XEXP (condexp, 1) = make_numeric_value (0);
1312 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1314 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1315 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1318 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1321 /* For each delay possibility and delay slot, compute an eligibility
1322 attribute for non-annulled insns and for each type of annulled (annul
1323 if true and annul if false). */
1324 for (delay = delays; delay; delay = delay->next)
1326 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1328 condexp = XVECEXP (delay->def, 1, i);
1329 if (condexp == 0)
1330 condexp = false_rtx;
1331 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1332 make_numeric_value (1), make_numeric_value (0));
1334 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1335 "*delay_%d_%d", delay->num, i / 3);
1336 make_internal_attr (p, newexp, ATTR_SPECIAL);
1338 if (have_annul_true)
1340 condexp = XVECEXP (delay->def, 1, i + 1);
1341 if (condexp == 0) condexp = false_rtx;
1342 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1343 make_numeric_value (1),
1344 make_numeric_value (0));
1345 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1346 "*annul_true_%d_%d", delay->num, i / 3);
1347 make_internal_attr (p, newexp, ATTR_SPECIAL);
1350 if (have_annul_false)
1352 condexp = XVECEXP (delay->def, 1, i + 2);
1353 if (condexp == 0) condexp = false_rtx;
1354 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1355 make_numeric_value (1),
1356 make_numeric_value (0));
1357 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1358 "*annul_false_%d_%d", delay->num, i / 3);
1359 make_internal_attr (p, newexp, ATTR_SPECIAL);
1365 /* Once all attributes and insns have been read and checked, we construct for
1366 each attribute value a list of all the insns that have that value for
1367 the attribute. */
1369 static void
1370 fill_attr (class attr_desc *attr)
1372 struct attr_value *av;
1373 struct insn_ent *ie;
1374 class insn_def *id;
1375 int i;
1376 rtx value;
1378 /* Don't fill constant attributes. The value is independent of
1379 any particular insn. */
1380 if (attr->is_const)
1381 return;
1383 for (id = defs; id; id = id->next)
1385 /* If no value is specified for this insn for this attribute, use the
1386 default. */
1387 value = NULL;
1388 if (XVEC (id->def, id->vec_idx))
1389 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1390 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1391 attr->name))
1392 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1394 if (value == NULL)
1395 av = attr->default_val;
1396 else
1397 av = get_attr_value (id->loc, value, attr, id->insn_code);
1399 ie = oballoc (struct insn_ent);
1400 ie->def = id;
1401 insert_insn_ent (av, ie);
1405 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1406 test that checks relative positions of insns (uses MATCH_DUP or PC).
1407 If so, replace it with what is obtained by passing the expression to
1408 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1409 recursively on each value (including the default value). Otherwise,
1410 return the value returned by NO_ADDRESS_FN applied to EXP. */
1412 static rtx
1413 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1414 rtx (*address_fn) (rtx))
1416 int i;
1417 rtx newexp;
1419 if (GET_CODE (exp) == COND)
1421 /* See if any tests use addresses. */
1422 address_used = 0;
1423 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1424 walk_attr_value (XVECEXP (exp, 0, i));
1426 if (address_used)
1427 return (*address_fn) (exp);
1429 /* Make a new copy of this COND, replacing each element. */
1430 newexp = rtx_alloc (COND);
1431 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1432 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1434 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1435 XVECEXP (newexp, 0, i + 1)
1436 = substitute_address (XVECEXP (exp, 0, i + 1),
1437 no_address_fn, address_fn);
1440 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1441 no_address_fn, address_fn);
1443 return newexp;
1446 else if (GET_CODE (exp) == IF_THEN_ELSE)
1448 address_used = 0;
1449 walk_attr_value (XEXP (exp, 0));
1450 if (address_used)
1451 return (*address_fn) (exp);
1453 return attr_rtx (IF_THEN_ELSE,
1454 substitute_address (XEXP (exp, 0),
1455 no_address_fn, address_fn),
1456 substitute_address (XEXP (exp, 1),
1457 no_address_fn, address_fn),
1458 substitute_address (XEXP (exp, 2),
1459 no_address_fn, address_fn));
1462 return (*no_address_fn) (exp);
1465 /* Make new attributes from the `length' attribute. The following are made,
1466 each corresponding to a function called from `shorten_branches' or
1467 `get_attr_length':
1469 *insn_default_length This is the length of the insn to be returned
1470 by `get_attr_length' before `shorten_branches'
1471 has been called. In each case where the length
1472 depends on relative addresses, the largest
1473 possible is used. This routine is also used
1474 to compute the initial size of the insn.
1476 *insn_variable_length_p This returns 1 if the insn's length depends
1477 on relative addresses, zero otherwise.
1479 *insn_current_length This is only called when it is known that the
1480 insn has a variable length and returns the
1481 current length, based on relative addresses.
1484 static void
1485 make_length_attrs (void)
1487 static const char *new_names[] =
1489 "*insn_default_length",
1490 "*insn_min_length",
1491 "*insn_variable_length_p",
1492 "*insn_current_length"
1494 static rtx (*const no_address_fn[]) (rtx)
1495 = {identity_fn,identity_fn, zero_fn, zero_fn};
1496 static rtx (*const address_fn[]) (rtx)
1497 = {max_fn, min_fn, one_fn, identity_fn};
1498 size_t i;
1499 class attr_desc *length_attr, *new_attr;
1500 struct attr_value *av, *new_av;
1501 struct insn_ent *ie, *new_ie;
1503 /* See if length attribute is defined. If so, it must be numeric. Make
1504 it special so we don't output anything for it. */
1505 length_attr = find_attr (&length_str, 0);
1506 if (length_attr == 0)
1507 return;
1509 if (! length_attr->is_numeric)
1510 fatal_at (length_attr->loc, "length attribute must be numeric");
1512 length_attr->is_const = 0;
1513 length_attr->is_special = 1;
1515 /* Make each new attribute, in turn. */
1516 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1518 make_internal_attr (new_names[i],
1519 substitute_address (length_attr->default_val->value,
1520 no_address_fn[i], address_fn[i]),
1521 ATTR_NONE);
1522 new_attr = find_attr (&new_names[i], 0);
1523 for (av = length_attr->first_value; av; av = av->next)
1524 for (ie = av->first_insn; ie; ie = ie->next)
1526 new_av = get_attr_value (ie->def->loc,
1527 substitute_address (av->value,
1528 no_address_fn[i],
1529 address_fn[i]),
1530 new_attr, ie->def->insn_code);
1531 new_ie = oballoc (struct insn_ent);
1532 new_ie->def = ie->def;
1533 insert_insn_ent (new_av, new_ie);
1538 /* Utility functions called from above routine. */
1540 static rtx
1541 identity_fn (rtx exp)
1543 return exp;
1546 static rtx
1547 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1549 return make_numeric_value (0);
1552 static rtx
1553 one_fn (rtx exp ATTRIBUTE_UNUSED)
1555 return make_numeric_value (1);
1558 static rtx
1559 max_fn (rtx exp)
1561 return make_numeric_value (max_attr_value (exp));
1564 static rtx
1565 min_fn (rtx exp)
1567 return make_numeric_value (min_attr_value (exp));
1570 static void
1571 write_length_unit_log (FILE *outf)
1573 class attr_desc *length_attr = find_attr (&length_str, 0);
1574 struct attr_value *av;
1575 struct insn_ent *ie;
1576 unsigned int length_unit_log, length_or;
1578 if (length_attr)
1580 length_or = attr_value_alignment (length_attr->default_val->value);
1581 for (av = length_attr->first_value; av; av = av->next)
1582 for (ie = av->first_insn; ie; ie = ie->next)
1583 length_or |= attr_value_alignment (av->value);
1585 length_or = ~length_or;
1586 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1587 length_unit_log++;
1589 else
1590 length_unit_log = 0;
1592 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1595 /* Compute approximate cost of the expression. Used to decide whether
1596 expression is cheap enough for inline. */
1597 static int
1598 attr_rtx_cost (rtx x)
1600 int cost = 1;
1601 enum rtx_code code;
1602 if (!x)
1603 return 0;
1604 code = GET_CODE (x);
1605 switch (code)
1607 case MATCH_OPERAND:
1608 if (XSTR (x, 1)[0])
1609 return 10;
1610 else
1611 return 1;
1613 case EQ_ATTR_ALT:
1614 return 1;
1616 case EQ_ATTR:
1617 /* Alternatives don't result into function call. */
1618 if (!strcmp_check (XSTR (x, 0), alternative_name))
1619 return 1;
1620 else
1621 return 5;
1622 default:
1624 int i, j;
1625 const char *fmt = GET_RTX_FORMAT (code);
1626 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1628 switch (fmt[i])
1630 case 'V':
1631 case 'E':
1632 for (j = 0; j < XVECLEN (x, i); j++)
1633 cost += attr_rtx_cost (XVECEXP (x, i, j));
1634 break;
1635 case 'e':
1636 cost += attr_rtx_cost (XEXP (x, i));
1637 break;
1641 break;
1643 return cost;
1646 /* Take a COND expression and see if any of the conditions in it can be
1647 simplified. If any are known true or known false for the particular insn
1648 code, the COND can be further simplified.
1650 Also call ourselves on any COND operations that are values of this COND.
1652 We do not modify EXP; rather, we make and return a new rtx. */
1654 static rtx
1655 simplify_cond (rtx exp, int insn_code, int insn_index)
1657 int i, j;
1658 /* We store the desired contents here,
1659 then build a new expression if they don't match EXP. */
1660 rtx defval = XEXP (exp, 1);
1661 rtx new_defval = XEXP (exp, 1);
1662 int len = XVECLEN (exp, 0);
1663 rtx *tests = XNEWVEC (rtx, len);
1664 int allsame = 1;
1665 rtx ret;
1667 /* This lets us free all storage allocated below, if appropriate. */
1668 obstack_finish (rtl_obstack);
1670 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1672 /* See if default value needs simplification. */
1673 if (GET_CODE (defval) == COND)
1674 new_defval = simplify_cond (defval, insn_code, insn_index);
1676 /* Simplify the subexpressions, and see what tests we can get rid of. */
1678 for (i = 0; i < len; i += 2)
1680 rtx newtest, newval;
1682 /* Simplify this test. */
1683 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1684 tests[i] = newtest;
1686 newval = tests[i + 1];
1687 /* See if this value may need simplification. */
1688 if (GET_CODE (newval) == COND)
1689 newval = simplify_cond (newval, insn_code, insn_index);
1691 /* Look for ways to delete or combine this test. */
1692 if (newtest == true_rtx)
1694 /* If test is true, make this value the default
1695 and discard this + any following tests. */
1696 len = i;
1697 defval = tests[i + 1];
1698 new_defval = newval;
1701 else if (newtest == false_rtx)
1703 /* If test is false, discard it and its value. */
1704 for (j = i; j < len - 2; j++)
1705 tests[j] = tests[j + 2];
1706 i -= 2;
1707 len -= 2;
1710 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1712 /* If this value and the value for the prev test are the same,
1713 merge the tests. */
1715 tests[i - 2]
1716 = insert_right_side (IOR, tests[i - 2], newtest,
1717 insn_code, insn_index);
1719 /* Delete this test/value. */
1720 for (j = i; j < len - 2; j++)
1721 tests[j] = tests[j + 2];
1722 len -= 2;
1723 i -= 2;
1726 else
1727 tests[i + 1] = newval;
1730 /* If the last test in a COND has the same value
1731 as the default value, that test isn't needed. */
1733 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1734 len -= 2;
1736 /* See if we changed anything. */
1737 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1738 allsame = 0;
1739 else
1740 for (i = 0; i < len; i++)
1741 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1743 allsame = 0;
1744 break;
1747 if (len == 0)
1749 if (GET_CODE (defval) == COND)
1750 ret = simplify_cond (defval, insn_code, insn_index);
1751 else
1752 ret = defval;
1754 else if (allsame)
1755 ret = exp;
1756 else
1758 rtx newexp = rtx_alloc (COND);
1760 XVEC (newexp, 0) = rtvec_alloc (len);
1761 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1762 XEXP (newexp, 1) = new_defval;
1763 ret = newexp;
1765 free (tests);
1766 return ret;
1769 /* Remove an insn entry from an attribute value. */
1771 static void
1772 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1774 struct insn_ent *previe;
1776 if (av->first_insn == ie)
1777 av->first_insn = ie->next;
1778 else
1780 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1782 previe->next = ie->next;
1785 av->num_insns--;
1786 if (ie->def->insn_code == -1)
1787 av->has_asm_insn = 0;
1789 num_insn_ents--;
1792 /* Insert an insn entry in an attribute value list. */
1794 static void
1795 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1797 ie->next = av->first_insn;
1798 av->first_insn = ie;
1799 av->num_insns++;
1800 if (ie->def->insn_code == -1)
1801 av->has_asm_insn = 1;
1803 num_insn_ents++;
1806 /* This is a utility routine to take an expression that is a tree of either
1807 AND or IOR expressions and insert a new term. The new term will be
1808 inserted at the right side of the first node whose code does not match
1809 the root. A new node will be created with the root's code. Its left
1810 side will be the old right side and its right side will be the new
1811 term.
1813 If the `term' is itself a tree, all its leaves will be inserted. */
1815 static rtx
1816 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1818 rtx newexp;
1820 /* Avoid consing in some special cases. */
1821 if (code == AND && term == true_rtx)
1822 return exp;
1823 if (code == AND && term == false_rtx)
1824 return false_rtx;
1825 if (code == AND && exp == true_rtx)
1826 return term;
1827 if (code == AND && exp == false_rtx)
1828 return false_rtx;
1829 if (code == IOR && term == true_rtx)
1830 return true_rtx;
1831 if (code == IOR && term == false_rtx)
1832 return exp;
1833 if (code == IOR && exp == true_rtx)
1834 return true_rtx;
1835 if (code == IOR && exp == false_rtx)
1836 return term;
1837 if (attr_equal_p (exp, term))
1838 return exp;
1840 if (GET_CODE (term) == code)
1842 exp = insert_right_side (code, exp, XEXP (term, 0),
1843 insn_code, insn_index);
1844 exp = insert_right_side (code, exp, XEXP (term, 1),
1845 insn_code, insn_index);
1847 return exp;
1850 if (GET_CODE (exp) == code)
1852 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1853 term, insn_code, insn_index);
1854 if (new_rtx != XEXP (exp, 1))
1855 /* Make a copy of this expression and call recursively. */
1856 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1857 else
1858 newexp = exp;
1860 else
1862 /* Insert the new term. */
1863 newexp = attr_rtx (code, exp, term);
1866 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1869 /* If we have an expression which AND's a bunch of
1870 (not (eq_attrq "alternative" "n"))
1871 terms, we may have covered all or all but one of the possible alternatives.
1872 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1874 This routine is passed an expression and either AND or IOR. It returns a
1875 bitmask indicating which alternatives are mentioned within EXP. */
1877 static alternative_mask
1878 compute_alternative_mask (rtx exp, enum rtx_code code)
1880 const char *string;
1881 if (GET_CODE (exp) == code)
1882 return compute_alternative_mask (XEXP (exp, 0), code)
1883 | compute_alternative_mask (XEXP (exp, 1), code);
1885 else if (code == AND && GET_CODE (exp) == NOT
1886 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1887 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1888 string = XSTR (XEXP (exp, 0), 1);
1890 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1891 && XSTR (exp, 0) == alternative_name)
1892 string = XSTR (exp, 1);
1894 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1896 if (code == AND && XWINT (exp, 1))
1897 return XWINT (exp, 0);
1899 if (code == IOR && !XWINT (exp, 1))
1900 return XWINT (exp, 0);
1902 return 0;
1904 else
1905 return 0;
1907 if (string[1] == 0)
1908 return ((alternative_mask) 1) << (string[0] - '0');
1909 return ((alternative_mask) 1) << atoi (string);
1912 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1913 attribute with the value represented by that bit. */
1915 static rtx
1916 make_alternative_compare (alternative_mask mask)
1918 return mk_attr_alt (mask);
1921 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1922 of "attr" for this insn code. From that value, we can compute a test
1923 showing when the EQ_ATTR will be true. This routine performs that
1924 computation. If a test condition involves an address, we leave the EQ_ATTR
1925 intact because addresses are only valid for the `length' attribute.
1927 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1928 it refers. VALUE is the value of that attribute for the insn
1929 corresponding to INSN_CODE and INSN_INDEX. */
1931 static rtx
1932 evaluate_eq_attr (rtx exp, class attr_desc *attr, rtx value,
1933 int insn_code, int insn_index)
1935 rtx orexp, andexp;
1936 rtx right;
1937 rtx newexp;
1938 int i;
1940 while (GET_CODE (value) == ATTR)
1942 struct attr_value *av = NULL;
1944 attr = find_attr (&XSTR (value, 0), 0);
1946 if (insn_code_values)
1948 struct attr_value_list *iv;
1949 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
1950 if (iv->attr == attr)
1952 av = iv->av;
1953 break;
1956 else
1958 struct insn_ent *ie;
1959 for (av = attr->first_value; av; av = av->next)
1960 for (ie = av->first_insn; ie; ie = ie->next)
1961 if (ie->def->insn_code == insn_code)
1962 goto got_av;
1964 if (av)
1966 got_av:
1967 value = av->value;
1971 switch (GET_CODE (value))
1973 case CONST_STRING:
1974 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
1975 newexp = true_rtx;
1976 else
1977 newexp = false_rtx;
1978 break;
1980 case SYMBOL_REF:
1982 const char *prefix;
1983 char *string, *p;
1985 gcc_assert (GET_CODE (exp) == EQ_ATTR);
1986 prefix = attr->enum_name ? attr->enum_name : attr->name;
1987 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
1988 for (p = string; *p; p++)
1989 *p = TOUPPER (*p);
1991 newexp = attr_rtx (EQ, value,
1992 attr_rtx (SYMBOL_REF,
1993 DEF_ATTR_STRING (string)));
1994 break;
1997 case COND:
1998 /* We construct an IOR of all the cases for which the
1999 requested attribute value is present. Since we start with
2000 FALSE, if it is not present, FALSE will be returned.
2002 Each case is the AND of the NOT's of the previous conditions with the
2003 current condition; in the default case the current condition is TRUE.
2005 For each possible COND value, call ourselves recursively.
2007 The extra TRUE and FALSE expressions will be eliminated by another
2008 call to the simplification routine. */
2010 orexp = false_rtx;
2011 andexp = true_rtx;
2013 for (i = 0; i < XVECLEN (value, 0); i += 2)
2015 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2016 insn_code, insn_index);
2018 right = insert_right_side (AND, andexp, this_cond,
2019 insn_code, insn_index);
2020 right = insert_right_side (AND, right,
2021 evaluate_eq_attr (exp, attr,
2022 XVECEXP (value, 0,
2023 i + 1),
2024 insn_code, insn_index),
2025 insn_code, insn_index);
2026 orexp = insert_right_side (IOR, orexp, right,
2027 insn_code, insn_index);
2029 /* Add this condition into the AND expression. */
2030 newexp = attr_rtx (NOT, this_cond);
2031 andexp = insert_right_side (AND, andexp, newexp,
2032 insn_code, insn_index);
2035 /* Handle the default case. */
2036 right = insert_right_side (AND, andexp,
2037 evaluate_eq_attr (exp, attr, XEXP (value, 1),
2038 insn_code, insn_index),
2039 insn_code, insn_index);
2040 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2041 break;
2043 default:
2044 gcc_unreachable ();
2047 /* If uses an address, must return original expression. But set the
2048 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2050 address_used = 0;
2051 walk_attr_value (newexp);
2053 if (address_used)
2055 if (! ATTR_IND_SIMPLIFIED_P (exp))
2056 return copy_rtx_unchanging (exp);
2057 return exp;
2059 else
2060 return newexp;
2063 /* This routine is called when an AND of a term with a tree of AND's is
2064 encountered. If the term or its complement is present in the tree, it
2065 can be replaced with TRUE or FALSE, respectively.
2067 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2068 be true and hence are complementary.
2070 There is one special case: If we see
2071 (and (not (eq_attr "att" "v1"))
2072 (eq_attr "att" "v2"))
2073 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2074 replace the term, not anything in the AND tree. So we pass a pointer to
2075 the term. */
2077 static rtx
2078 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2080 rtx left, right;
2081 rtx newexp;
2082 rtx temp;
2083 int left_eliminates_term, right_eliminates_term;
2085 if (GET_CODE (exp) == AND)
2087 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2088 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2089 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2091 newexp = attr_rtx (AND, left, right);
2093 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2097 else if (GET_CODE (exp) == IOR)
2099 /* For the IOR case, we do the same as above, except that we can
2100 only eliminate `term' if both sides of the IOR would do so. */
2101 temp = *pterm;
2102 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2103 left_eliminates_term = (temp == true_rtx);
2105 temp = *pterm;
2106 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2107 right_eliminates_term = (temp == true_rtx);
2109 if (left_eliminates_term && right_eliminates_term)
2110 *pterm = true_rtx;
2112 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2114 newexp = attr_rtx (IOR, left, right);
2116 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2120 /* Check for simplifications. Do some extra checking here since this
2121 routine is called so many times. */
2123 if (exp == *pterm)
2124 return true_rtx;
2126 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2127 return false_rtx;
2129 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2130 return false_rtx;
2132 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2134 if (attr_alt_subset_p (*pterm, exp))
2135 return true_rtx;
2137 if (attr_alt_subset_of_compl_p (*pterm, exp))
2138 return false_rtx;
2140 if (attr_alt_subset_p (exp, *pterm))
2141 *pterm = true_rtx;
2143 return exp;
2146 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2148 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2149 return exp;
2151 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2152 return true_rtx;
2153 else
2154 return false_rtx;
2157 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2158 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2160 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2161 return exp;
2163 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2164 return false_rtx;
2165 else
2166 return true_rtx;
2169 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2170 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2172 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2173 return exp;
2175 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2176 return false_rtx;
2177 else
2178 *pterm = true_rtx;
2181 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2183 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2184 return true_rtx;
2187 else if (GET_CODE (exp) == NOT)
2189 if (attr_equal_p (XEXP (exp, 0), *pterm))
2190 return false_rtx;
2193 else if (GET_CODE (*pterm) == NOT)
2195 if (attr_equal_p (XEXP (*pterm, 0), exp))
2196 return false_rtx;
2199 else if (attr_equal_p (exp, *pterm))
2200 return true_rtx;
2202 return exp;
2205 /* Similar to `simplify_and_tree', but for IOR trees. */
2207 static rtx
2208 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2210 rtx left, right;
2211 rtx newexp;
2212 rtx temp;
2213 int left_eliminates_term, right_eliminates_term;
2215 if (GET_CODE (exp) == IOR)
2217 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2218 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2219 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2221 newexp = attr_rtx (GET_CODE (exp), left, right);
2223 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2227 else if (GET_CODE (exp) == AND)
2229 /* For the AND case, we do the same as above, except that we can
2230 only eliminate `term' if both sides of the AND would do so. */
2231 temp = *pterm;
2232 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2233 left_eliminates_term = (temp == false_rtx);
2235 temp = *pterm;
2236 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2237 right_eliminates_term = (temp == false_rtx);
2239 if (left_eliminates_term && right_eliminates_term)
2240 *pterm = false_rtx;
2242 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2244 newexp = attr_rtx (GET_CODE (exp), left, right);
2246 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2250 if (attr_equal_p (exp, *pterm))
2251 return false_rtx;
2253 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2254 return true_rtx;
2256 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2257 return true_rtx;
2259 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2260 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2261 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2262 *pterm = false_rtx;
2264 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2265 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2266 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2267 return false_rtx;
2269 return exp;
2272 /* Simplify test expression and use temporary obstack in order to avoid
2273 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2274 and avoid unnecessary copying if possible. */
2276 static rtx
2277 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2279 rtx x;
2280 struct obstack *old;
2281 if (ATTR_IND_SIMPLIFIED_P (exp))
2282 return exp;
2283 old = rtl_obstack;
2284 rtl_obstack = temp_obstack;
2285 x = simplify_test_exp (exp, insn_code, insn_index);
2286 rtl_obstack = old;
2287 return x;
2290 /* Returns true if S1 is a subset of S2. */
2292 static bool
2293 attr_alt_subset_p (rtx s1, rtx s2)
2295 switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
2297 case (0 << 1) | 0:
2298 return !(XWINT (s1, 0) &~ XWINT (s2, 0));
2300 case (0 << 1) | 1:
2301 return !(XWINT (s1, 0) & XWINT (s2, 0));
2303 case (1 << 1) | 0:
2304 return false;
2306 case (1 << 1) | 1:
2307 return !(XWINT (s2, 0) &~ XWINT (s1, 0));
2309 default:
2310 gcc_unreachable ();
2314 /* Returns true if S1 is a subset of complement of S2. */
2316 static bool
2317 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2319 switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
2321 case (0 << 1) | 0:
2322 return !(XWINT (s1, 0) & XWINT (s2, 0));
2324 case (0 << 1) | 1:
2325 return !(XWINT (s1, 0) & ~XWINT (s2, 0));
2327 case (1 << 1) | 0:
2328 return !(XWINT (s2, 0) &~ XWINT (s1, 0));
2330 case (1 << 1) | 1:
2331 return false;
2333 default:
2334 gcc_unreachable ();
2338 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2340 static rtx
2341 attr_alt_intersection (rtx s1, rtx s2)
2343 alternative_mask result;
2345 switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
2347 case (0 << 1) | 0:
2348 result = XWINT (s1, 0) & XWINT (s2, 0);
2349 break;
2350 case (0 << 1) | 1:
2351 result = XWINT (s1, 0) & ~XWINT (s2, 0);
2352 break;
2353 case (1 << 1) | 0:
2354 result = XWINT (s2, 0) & ~XWINT (s1, 0);
2355 break;
2356 case (1 << 1) | 1:
2357 result = XWINT (s1, 0) | XWINT (s2, 0);
2358 break;
2359 default:
2360 gcc_unreachable ();
2363 return attr_rtx (EQ_ATTR_ALT, result, XWINT (s1, 1) & XWINT (s2, 1));
2366 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2368 static rtx
2369 attr_alt_union (rtx s1, rtx s2)
2371 alternative_mask result;
2373 switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
2375 case (0 << 1) | 0:
2376 result = XWINT (s1, 0) | XWINT (s2, 0);
2377 break;
2378 case (0 << 1) | 1:
2379 result = XWINT (s2, 0) & ~XWINT (s1, 0);
2380 break;
2381 case (1 << 1) | 0:
2382 result = XWINT (s1, 0) & ~XWINT (s2, 0);
2383 break;
2384 case (1 << 1) | 1:
2385 result = XWINT (s1, 0) & XWINT (s2, 0);
2386 break;
2387 default:
2388 gcc_unreachable ();
2391 return attr_rtx (EQ_ATTR_ALT, result, XWINT (s1, 1) | XWINT (s2, 1));
2394 /* Return EQ_ATTR_ALT expression representing complement of S. */
2396 static rtx
2397 attr_alt_complement (rtx s)
2399 return attr_rtx (EQ_ATTR_ALT, XWINT (s, 0),
2400 HOST_WIDE_INT_1 - XWINT (s, 1));
2403 /* Return EQ_ATTR_ALT expression representing set containing elements set
2404 in E. */
2406 static rtx
2407 mk_attr_alt (alternative_mask e)
2409 return attr_rtx (EQ_ATTR_ALT, (HOST_WIDE_INT) e, HOST_WIDE_INT_0);
2412 /* Given an expression, see if it can be simplified for a particular insn
2413 code based on the values of other attributes being tested. This can
2414 eliminate nested get_attr_... calls.
2416 Note that if an endless recursion is specified in the patterns, the
2417 optimization will loop. However, it will do so in precisely the cases where
2418 an infinite recursion loop could occur during compilation. It's better that
2419 it occurs here! */
2421 static rtx
2422 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2424 rtx left, right;
2425 class attr_desc *attr;
2426 struct attr_value *av;
2427 struct insn_ent *ie;
2428 struct attr_value_list *iv;
2429 alternative_mask i;
2430 rtx newexp = exp;
2431 bool left_alt, right_alt;
2433 /* Don't re-simplify something we already simplified. */
2434 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2435 return exp;
2437 switch (GET_CODE (exp))
2439 case AND:
2440 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2441 if (left == false_rtx)
2442 return false_rtx;
2443 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2444 if (right == false_rtx)
2445 return false_rtx;
2447 if (GET_CODE (left) == EQ_ATTR_ALT
2448 && GET_CODE (right) == EQ_ATTR_ALT)
2450 exp = attr_alt_intersection (left, right);
2451 return simplify_test_exp (exp, insn_code, insn_index);
2454 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2455 present on both sides, apply the distributive law since this will
2456 yield simplifications. */
2457 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2458 && compute_alternative_mask (left, IOR)
2459 && compute_alternative_mask (right, IOR))
2461 if (GET_CODE (left) == IOR)
2462 std::swap (left, right);
2464 newexp = attr_rtx (IOR,
2465 attr_rtx (AND, left, XEXP (right, 0)),
2466 attr_rtx (AND, left, XEXP (right, 1)));
2468 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2471 /* Try with the term on both sides. */
2472 right = simplify_and_tree (right, &left, insn_code, insn_index);
2473 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2474 left = simplify_and_tree (left, &right, insn_code, insn_index);
2476 if (left == false_rtx || right == false_rtx)
2477 return false_rtx;
2478 else if (left == true_rtx)
2480 return right;
2482 else if (right == true_rtx)
2484 return left;
2486 /* See if all or all but one of the insn's alternatives are specified
2487 in this tree. Optimize if so. */
2489 if (GET_CODE (left) == NOT)
2490 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2491 && XSTR (XEXP (left, 0), 0) == alternative_name);
2492 else
2493 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2494 && XWINT (left, 1));
2496 if (GET_CODE (right) == NOT)
2497 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2498 && XSTR (XEXP (right, 0), 0) == alternative_name);
2499 else
2500 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2501 && XWINT (right, 1));
2503 if (insn_code >= 0
2504 && (GET_CODE (left) == AND
2505 || left_alt
2506 || GET_CODE (right) == AND
2507 || right_alt))
2509 i = compute_alternative_mask (exp, AND);
2510 if (i & ~insn_alternatives[insn_code])
2511 fatal ("invalid alternative specified for pattern number %d",
2512 insn_index);
2514 /* If all alternatives are excluded, this is false. */
2515 i ^= insn_alternatives[insn_code];
2516 if (i == 0)
2517 return false_rtx;
2518 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2520 /* If just one excluded, AND a comparison with that one to the
2521 front of the tree. The others will be eliminated by
2522 optimization. We do not want to do this if the insn has one
2523 alternative and we have tested none of them! */
2524 left = make_alternative_compare (i);
2525 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2526 newexp = attr_rtx (AND, left, right);
2528 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2532 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2534 newexp = attr_rtx (AND, left, right);
2535 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2537 break;
2539 case IOR:
2540 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2541 if (left == true_rtx)
2542 return true_rtx;
2543 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2544 if (right == true_rtx)
2545 return true_rtx;
2547 if (GET_CODE (left) == EQ_ATTR_ALT
2548 && GET_CODE (right) == EQ_ATTR_ALT)
2550 exp = attr_alt_union (left, right);
2551 return simplify_test_exp (exp, insn_code, insn_index);
2554 right = simplify_or_tree (right, &left, insn_code, insn_index);
2555 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2556 left = simplify_or_tree (left, &right, insn_code, insn_index);
2558 if (right == true_rtx || left == true_rtx)
2559 return true_rtx;
2560 else if (left == false_rtx)
2562 return right;
2564 else if (right == false_rtx)
2566 return left;
2569 /* Test for simple cases where the distributive law is useful. I.e.,
2570 convert (ior (and (x) (y))
2571 (and (x) (z)))
2572 to (and (x)
2573 (ior (y) (z)))
2576 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2577 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2579 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2581 left = XEXP (left, 0);
2582 right = newexp;
2583 newexp = attr_rtx (AND, left, right);
2584 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2587 /* Similarly,
2588 convert (ior (and (y) (x))
2589 (and (z) (x)))
2590 to (and (ior (y) (z))
2591 (x))
2592 Note that we want the common term to stay at the end.
2595 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2596 && attr_equal_p (XEXP (left, 1), XEXP (right, 1)))
2598 newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0));
2600 left = newexp;
2601 right = XEXP (right, 1);
2602 newexp = attr_rtx (AND, left, right);
2603 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2606 /* See if all or all but one of the insn's alternatives are specified
2607 in this tree. Optimize if so. */
2609 else if (insn_code >= 0
2610 && (GET_CODE (left) == IOR
2611 || (GET_CODE (left) == EQ_ATTR_ALT
2612 && !XWINT (left, 1))
2613 || (GET_CODE (left) == EQ_ATTR
2614 && XSTR (left, 0) == alternative_name)
2615 || GET_CODE (right) == IOR
2616 || (GET_CODE (right) == EQ_ATTR_ALT
2617 && !XWINT (right, 1))
2618 || (GET_CODE (right) == EQ_ATTR
2619 && XSTR (right, 0) == alternative_name)))
2621 i = compute_alternative_mask (exp, IOR);
2622 if (i & ~insn_alternatives[insn_code])
2623 fatal ("invalid alternative specified for pattern number %d",
2624 insn_index);
2626 /* If all alternatives are included, this is true. */
2627 i ^= insn_alternatives[insn_code];
2628 if (i == 0)
2629 return true_rtx;
2630 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2632 /* If just one excluded, IOR a comparison with that one to the
2633 front of the tree. The others will be eliminated by
2634 optimization. We do not want to do this if the insn has one
2635 alternative and we have tested none of them! */
2636 left = make_alternative_compare (i);
2637 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2638 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2640 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2644 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2646 newexp = attr_rtx (IOR, left, right);
2647 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2649 break;
2651 case NOT:
2652 if (GET_CODE (XEXP (exp, 0)) == NOT)
2654 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2655 insn_code, insn_index);
2656 return left;
2659 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2660 if (GET_CODE (left) == NOT)
2661 return XEXP (left, 0);
2663 if (left == false_rtx)
2664 return true_rtx;
2665 if (left == true_rtx)
2666 return false_rtx;
2668 if (GET_CODE (left) == EQ_ATTR_ALT)
2670 exp = attr_alt_complement (left);
2671 return simplify_test_exp (exp, insn_code, insn_index);
2674 /* Try to apply De`Morgan's laws. */
2675 if (GET_CODE (left) == IOR)
2677 newexp = attr_rtx (AND,
2678 attr_rtx (NOT, XEXP (left, 0)),
2679 attr_rtx (NOT, XEXP (left, 1)));
2681 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2683 else if (GET_CODE (left) == AND)
2685 newexp = attr_rtx (IOR,
2686 attr_rtx (NOT, XEXP (left, 0)),
2687 attr_rtx (NOT, XEXP (left, 1)));
2689 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2691 else if (left != XEXP (exp, 0))
2693 newexp = attr_rtx (NOT, left);
2695 break;
2697 case EQ_ATTR_ALT:
2698 if (!XWINT (exp, 0))
2699 return XWINT (exp, 1) ? true_rtx : false_rtx;
2700 break;
2702 case EQ_ATTR:
2703 if (XSTR (exp, 0) == alternative_name)
2705 newexp = mk_attr_alt (((alternative_mask) 1)
2706 << atoi (XSTR (exp, 1)));
2707 break;
2710 /* Look at the value for this insn code in the specified attribute.
2711 We normally can replace this comparison with the condition that
2712 would give this insn the values being tested for. */
2713 if (insn_code >= 0
2714 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2716 rtx x;
2718 av = NULL;
2719 if (insn_code_values)
2721 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2722 if (iv->attr == attr)
2724 av = iv->av;
2725 break;
2728 else
2730 for (av = attr->first_value; av; av = av->next)
2731 for (ie = av->first_insn; ie; ie = ie->next)
2732 if (ie->def->insn_code == insn_code)
2733 goto got_av;
2736 if (av)
2738 got_av:
2739 x = evaluate_eq_attr (exp, attr, av->value,
2740 insn_code, insn_index);
2741 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2742 if (attr_rtx_cost (x) < 7)
2743 return x;
2746 break;
2748 default:
2749 break;
2752 /* We have already simplified this expression. Simplifying it again
2753 won't buy anything unless we weren't given a valid insn code
2754 to process (i.e., we are canonicalizing something.). */
2755 if (insn_code != -2
2756 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2757 return copy_rtx_unchanging (newexp);
2759 return newexp;
2762 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2763 otherwise return 0. */
2765 static int
2766 tests_attr_p (rtx p, class attr_desc *attr)
2768 const char *fmt;
2769 int i, ie, j, je;
2771 if (GET_CODE (p) == EQ_ATTR)
2773 if (XSTR (p, 0) != attr->name)
2774 return 0;
2775 return 1;
2778 fmt = GET_RTX_FORMAT (GET_CODE (p));
2779 ie = GET_RTX_LENGTH (GET_CODE (p));
2780 for (i = 0; i < ie; i++)
2782 switch (*fmt++)
2784 case 'e':
2785 if (tests_attr_p (XEXP (p, i), attr))
2786 return 1;
2787 break;
2789 case 'E':
2790 je = XVECLEN (p, i);
2791 for (j = 0; j < je; ++j)
2792 if (tests_attr_p (XVECEXP (p, i, j), attr))
2793 return 1;
2794 break;
2798 return 0;
2801 /* Calculate a topological sorting of all attributes so that
2802 all attributes only depend on attributes in front of it.
2803 Place the result in *RET (which is a pointer to an array of
2804 attr_desc pointers), and return the size of that array. */
2806 static int
2807 get_attr_order (class attr_desc ***ret)
2809 int i, j;
2810 int num = 0;
2811 class attr_desc *attr;
2812 class attr_desc **all, **sorted;
2813 char *handled;
2814 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2815 for (attr = attrs[i]; attr; attr = attr->next)
2816 num++;
2817 all = XNEWVEC (class attr_desc *, num);
2818 sorted = XNEWVEC (class attr_desc *, num);
2819 handled = XCNEWVEC (char, num);
2820 num = 0;
2821 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2822 for (attr = attrs[i]; attr; attr = attr->next)
2823 all[num++] = attr;
2825 j = 0;
2826 for (i = 0; i < num; i++)
2827 if (all[i]->is_const)
2828 handled[i] = 1, sorted[j++] = all[i];
2830 /* We have only few attributes hence we can live with the inner
2831 loop being O(n^2), unlike the normal fast variants of topological
2832 sorting. */
2833 while (j < num)
2835 for (i = 0; i < num; i++)
2836 if (!handled[i])
2838 /* Let's see if I depends on anything interesting. */
2839 int k;
2840 for (k = 0; k < num; k++)
2841 if (!handled[k])
2843 struct attr_value *av;
2844 for (av = all[i]->first_value; av; av = av->next)
2845 if (av->num_insns != 0)
2846 if (tests_attr_p (av->value, all[k]))
2847 break;
2849 if (av)
2850 /* Something in I depends on K. */
2851 break;
2853 if (k == num)
2855 /* Nothing in I depended on anything intersting, so
2856 it's done. */
2857 handled[i] = 1;
2858 sorted[j++] = all[i];
2863 if (DEBUG)
2864 for (j = 0; j < num; j++)
2866 class attr_desc *attr2;
2867 struct attr_value *av;
2869 attr = sorted[j];
2870 fprintf (stderr, "%s depends on: ", attr->name);
2871 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
2872 for (attr2 = attrs[i]; attr2; attr2 = attr2->next)
2873 if (!attr2->is_const)
2874 for (av = attr->first_value; av; av = av->next)
2875 if (av->num_insns != 0)
2876 if (tests_attr_p (av->value, attr2))
2878 fprintf (stderr, "%s, ", attr2->name);
2879 break;
2881 fprintf (stderr, "\n");
2884 free (all);
2885 *ret = sorted;
2886 return num;
2889 /* Optimize the attribute lists by seeing if we can determine conditional
2890 values from the known values of other attributes. This will save subroutine
2891 calls during the compilation. NUM_INSN_CODES is the number of unique
2892 instruction codes. */
2894 static void
2895 optimize_attrs (int num_insn_codes)
2897 class attr_desc *attr;
2898 struct attr_value *av;
2899 struct insn_ent *ie;
2900 rtx newexp;
2901 int i;
2902 struct attr_value_list *ivbuf;
2903 struct attr_value_list *iv;
2904 class attr_desc **topsort;
2905 int topnum;
2907 /* For each insn code, make a list of all the insn_ent's for it,
2908 for all values for all attributes. */
2910 if (num_insn_ents == 0)
2911 return;
2913 /* Make 2 extra elements, for "code" values -2 and -1. */
2914 insn_code_values = XCNEWVEC (struct attr_value_list *, num_insn_codes + 2);
2916 /* Offset the table address so we can index by -2 or -1. */
2917 insn_code_values += 2;
2919 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2921 /* Create the chain of insn*attr values such that we see dependend
2922 attributes after their dependencies. As we use a stack via the
2923 next pointers start from the end of the topological order. */
2924 topnum = get_attr_order (&topsort);
2925 for (i = topnum - 1; i >= 0; i--)
2926 for (av = topsort[i]->first_value; av; av = av->next)
2927 for (ie = av->first_insn; ie; ie = ie->next)
2929 iv->attr = topsort[i];
2930 iv->av = av;
2931 iv->ie = ie;
2932 iv->next = insn_code_values[ie->def->insn_code];
2933 insn_code_values[ie->def->insn_code] = iv;
2934 iv++;
2936 free (topsort);
2938 /* Sanity check on num_insn_ents. */
2939 gcc_assert (iv == ivbuf + num_insn_ents);
2941 /* Process one insn code at a time. */
2942 for (i = -2; i < num_insn_codes; i++)
2944 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2945 We use it to mean "already simplified for this insn". */
2946 for (iv = insn_code_values[i]; iv; iv = iv->next)
2947 clear_struct_flag (iv->av->value);
2949 for (iv = insn_code_values[i]; iv; iv = iv->next)
2951 struct obstack *old = rtl_obstack;
2953 attr = iv->attr;
2954 av = iv->av;
2955 ie = iv->ie;
2956 if (GET_CODE (av->value) != COND)
2957 continue;
2959 rtl_obstack = temp_obstack;
2960 newexp = av->value;
2961 while (GET_CODE (newexp) == COND)
2963 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2964 ie->def->insn_index);
2965 if (newexp2 == newexp)
2966 break;
2967 newexp = newexp2;
2970 rtl_obstack = old;
2971 /* If we created a new value for this instruction, and it's
2972 cheaper than the old value, and overall cheap, use that
2973 one as specific value for the current instruction.
2974 The last test is to avoid exploding the get_attr_ function
2975 sizes for no much gain. */
2976 if (newexp != av->value
2977 && attr_rtx_cost (newexp) < attr_rtx_cost (av->value)
2978 && attr_rtx_cost (newexp) < 26
2981 remove_insn_ent (av, ie);
2982 av = get_attr_value (ie->def->loc, newexp, attr,
2983 ie->def->insn_code);
2984 iv->av = av;
2985 insert_insn_ent (av, ie);
2990 free (ivbuf);
2991 free (insn_code_values - 2);
2992 insn_code_values = NULL;
2995 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2997 static void
2998 clear_struct_flag (rtx x)
3000 int i;
3001 int j;
3002 enum rtx_code code;
3003 const char *fmt;
3005 ATTR_CURR_SIMPLIFIED_P (x) = 0;
3006 if (ATTR_IND_SIMPLIFIED_P (x))
3007 return;
3009 code = GET_CODE (x);
3011 switch (code)
3013 case REG:
3014 CASE_CONST_ANY:
3015 case MATCH_TEST:
3016 case SYMBOL_REF:
3017 case CODE_LABEL:
3018 case PC:
3019 case EQ_ATTR:
3020 case ATTR_FLAG:
3021 return;
3023 default:
3024 break;
3027 /* Compare the elements. If any pair of corresponding elements
3028 fail to match, return 0 for the whole things. */
3030 fmt = GET_RTX_FORMAT (code);
3031 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3033 switch (fmt[i])
3035 case 'V':
3036 case 'E':
3037 for (j = 0; j < XVECLEN (x, i); j++)
3038 clear_struct_flag (XVECEXP (x, i, j));
3039 break;
3041 case 'e':
3042 clear_struct_flag (XEXP (x, i));
3043 break;
3048 /* Add attribute value NAME to the beginning of ATTR's list. */
3050 static void
3051 add_attr_value (class attr_desc *attr, const char *name)
3053 struct attr_value *av;
3055 av = oballoc (struct attr_value);
3056 av->value = attr_rtx (CONST_STRING, name);
3057 av->next = attr->first_value;
3058 attr->first_value = av;
3059 av->first_insn = NULL;
3060 av->num_insns = 0;
3061 av->has_asm_insn = 0;
3064 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3066 static void
3067 gen_attr (md_rtx_info *info)
3069 struct enum_type *et;
3070 struct enum_value *ev;
3071 class attr_desc *attr;
3072 const char *name_ptr;
3073 char *p;
3074 rtx def = info->def;
3076 /* Make a new attribute structure. Check for duplicate by looking at
3077 attr->default_val, since it is initialized by this routine. */
3078 attr = find_attr (&XSTR (def, 0), 1);
3079 if (attr->default_val)
3081 error_at (info->loc, "duplicate definition for attribute %s",
3082 attr->name);
3083 message_at (attr->loc, "previous definition");
3084 return;
3086 attr->loc = info->loc;
3088 if (GET_CODE (def) == DEFINE_ENUM_ATTR)
3090 attr->enum_name = XSTR (def, 1);
3091 attr->cxx_type = attr->enum_name;
3092 et = rtx_reader_ptr->lookup_enum_type (XSTR (def, 1));
3093 if (!et || !et->md_p)
3094 error_at (info->loc, "No define_enum called `%s' defined",
3095 attr->name);
3096 if (et)
3097 for (ev = et->values; ev; ev = ev->next)
3098 add_attr_value (attr, ev->name);
3100 else if (*XSTR (def, 1) == '\0')
3102 attr->is_numeric = 1;
3103 attr->cxx_type = "int";
3105 else
3107 attr->cxx_type = concat ("attr_", attr->name, nullptr);
3108 name_ptr = XSTR (def, 1);
3109 while ((p = next_comma_elt (&name_ptr)) != NULL)
3110 add_attr_value (attr, p);
3113 if (GET_CODE (XEXP (def, 2)) == CONST)
3115 attr->is_const = 1;
3116 if (attr->is_numeric)
3117 error_at (info->loc,
3118 "constant attributes may not take numeric values");
3120 /* Get rid of the CONST node. It is allowed only at top-level. */
3121 XEXP (def, 2) = XEXP (XEXP (def, 2), 0);
3124 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3125 error_at (info->loc, "`length' attribute must take numeric values");
3127 /* Set up the default value. */
3128 XEXP (def, 2) = check_attr_value (info->loc, XEXP (def, 2), attr);
3129 attr->default_val = get_attr_value (info->loc, XEXP (def, 2), attr, -2);
3132 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3133 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3134 number of alternatives as this should be checked elsewhere. */
3136 static int
3137 count_alternatives (rtx exp)
3139 int i, j, n;
3140 const char *fmt;
3142 if (GET_CODE (exp) == MATCH_OPERAND)
3143 return n_comma_elts (XSTR (exp, 2));
3145 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3146 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3147 switch (*fmt++)
3149 case 'e':
3150 case 'u':
3151 n = count_alternatives (XEXP (exp, i));
3152 if (n)
3153 return n;
3154 break;
3156 case 'E':
3157 case 'V':
3158 if (XVEC (exp, i) != NULL)
3159 for (j = 0; j < XVECLEN (exp, i); j++)
3161 n = count_alternatives (XVECEXP (exp, i, j));
3162 if (n)
3163 return n;
3167 return 0;
3170 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3171 `alternative' attribute. */
3173 static int
3174 compares_alternatives_p (rtx exp)
3176 int i, j;
3177 const char *fmt;
3179 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3180 return 1;
3182 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3183 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3184 switch (*fmt++)
3186 case 'e':
3187 case 'u':
3188 if (compares_alternatives_p (XEXP (exp, i)))
3189 return 1;
3190 break;
3192 case 'E':
3193 for (j = 0; j < XVECLEN (exp, i); j++)
3194 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3195 return 1;
3196 break;
3199 return 0;
3202 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3204 static void
3205 gen_insn (md_rtx_info *info)
3207 class insn_def *id;
3208 rtx def = info->def;
3210 id = oballoc (class insn_def);
3211 id->next = defs;
3212 defs = id;
3213 id->def = def;
3214 id->loc = info->loc;
3216 switch (GET_CODE (def))
3218 case DEFINE_INSN:
3219 id->insn_code = info->index;
3220 id->insn_index = insn_index_number;
3221 id->num_alternatives = count_alternatives (def);
3222 if (id->num_alternatives == 0)
3223 id->num_alternatives = 1;
3224 id->vec_idx = 4;
3225 break;
3227 case DEFINE_PEEPHOLE:
3228 id->insn_code = info->index;
3229 id->insn_index = insn_index_number;
3230 id->num_alternatives = count_alternatives (def);
3231 if (id->num_alternatives == 0)
3232 id->num_alternatives = 1;
3233 id->vec_idx = 3;
3234 break;
3236 case DEFINE_ASM_ATTRIBUTES:
3237 id->insn_code = -1;
3238 id->insn_index = -1;
3239 id->num_alternatives = 1;
3240 id->vec_idx = 0;
3241 got_define_asm_attributes = 1;
3242 break;
3244 default:
3245 gcc_unreachable ();
3249 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3250 true or annul false is specified, and make a `struct delay_desc'. */
3252 static void
3253 gen_delay (md_rtx_info *info)
3255 class delay_desc *delay;
3256 int i;
3258 rtx def = info->def;
3259 if (XVECLEN (def, 1) % 3 != 0)
3261 error_at (info->loc, "number of elements in DEFINE_DELAY must"
3262 " be multiple of three");
3263 return;
3266 for (i = 0; i < XVECLEN (def, 1); i += 3)
3268 if (XVECEXP (def, 1, i + 1))
3269 have_annul_true = 1;
3270 if (XVECEXP (def, 1, i + 2))
3271 have_annul_false = 1;
3274 delay = oballoc (class delay_desc);
3275 delay->def = def;
3276 delay->num = ++num_delays;
3277 delay->next = delays;
3278 delay->loc = info->loc;
3279 delays = delay;
3282 /* Names of attributes that could be possibly cached. */
3283 static const char *cached_attrs[32];
3284 /* Number of such attributes. */
3285 static int cached_attr_count;
3286 /* Bitmasks of possibly cached attributes. */
3287 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3288 static unsigned int attrs_to_cache;
3289 static unsigned int attrs_cached_inside, attrs_cached_after;
3291 /* Finds non-const attributes that could be possibly cached.
3292 When create is TRUE, fills in cached_attrs array.
3293 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3294 bitmasks. */
3296 static void
3297 find_attrs_to_cache (rtx exp, bool create)
3299 int i;
3300 const char *name;
3301 class attr_desc *attr;
3303 if (exp == NULL)
3304 return;
3306 switch (GET_CODE (exp))
3308 case NOT:
3309 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3310 find_attrs_to_cache (XEXP (exp, 0), create);
3311 return;
3313 case EQ_ATTR:
3314 name = XSTR (exp, 0);
3315 if (name == alternative_name)
3316 return;
3317 for (i = 0; i < cached_attr_count; i++)
3318 if (name == cached_attrs[i])
3320 if ((attrs_seen_once & (1U << i)) != 0)
3321 attrs_seen_more_than_once |= (1U << i);
3322 else
3323 attrs_seen_once |= (1U << i);
3324 return;
3326 if (!create)
3327 return;
3328 attr = find_attr (&name, 0);
3329 gcc_assert (attr);
3330 if (attr->is_const)
3331 return;
3332 if (cached_attr_count == 32)
3333 return;
3334 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3335 attrs_seen_once |= (1U << cached_attr_count);
3336 cached_attr_count++;
3337 return;
3339 case AND:
3340 case IOR:
3341 find_attrs_to_cache (XEXP (exp, 0), create);
3342 find_attrs_to_cache (XEXP (exp, 1), create);
3343 return;
3345 case COND:
3346 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3347 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3348 return;
3350 default:
3351 return;
3355 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3356 We use AND and IOR both for logical and bit-wise operations, so
3357 interpret them as logical unless they are inside a comparison expression.
3359 An outermost pair of parentheses is emitted around this C expression unless
3360 EMIT_PARENS is false. */
3362 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3363 #define FLG_BITWISE 1
3364 /* Set if cached attribute will be known initialized in else block after
3365 this condition. This is true for LHS of toplevel && and || and
3366 even for RHS of ||, but not for RHS of &&. */
3367 #define FLG_AFTER 2
3368 /* Set if cached attribute will be known initialized in then block after
3369 this condition. This is true for LHS of toplevel && and || and
3370 even for RHS of &&, but not for RHS of ||. */
3371 #define FLG_INSIDE 4
3372 /* Cleared when an operand of &&. */
3373 #define FLG_OUTSIDE_AND 8
3375 static unsigned int
3376 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
3377 bool emit_parens = true)
3379 int comparison_operator = 0;
3380 RTX_CODE code;
3381 class attr_desc *attr;
3383 if (emit_parens)
3384 fprintf (outf, "(");
3386 code = GET_CODE (exp);
3387 switch (code)
3389 /* Binary operators. */
3390 case GEU: case GTU:
3391 case LEU: case LTU:
3392 fprintf (outf, "(unsigned) ");
3393 /* Fall through. */
3395 case EQ: case NE:
3396 case GE: case GT:
3397 case LE: case LT:
3398 comparison_operator = FLG_BITWISE;
3399 /* FALLTHRU */
3401 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3402 case AND: case IOR: case XOR:
3403 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3404 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3406 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3407 write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3408 flags | comparison_operator);
3410 else
3412 if (code == AND)
3413 flags &= ~FLG_OUTSIDE_AND;
3414 if (GET_CODE (XEXP (exp, 0)) == code
3415 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3416 || (GET_CODE (XEXP (exp, 0)) == NOT
3417 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3418 attrs_cached
3419 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3420 else
3421 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3423 switch (code)
3425 case EQ:
3426 fprintf (outf, " == ");
3427 break;
3428 case NE:
3429 fprintf (outf, " != ");
3430 break;
3431 case GE:
3432 fprintf (outf, " >= ");
3433 break;
3434 case GT:
3435 fprintf (outf, " > ");
3436 break;
3437 case GEU:
3438 fprintf (outf, " >= (unsigned) ");
3439 break;
3440 case GTU:
3441 fprintf (outf, " > (unsigned) ");
3442 break;
3443 case LE:
3444 fprintf (outf, " <= ");
3445 break;
3446 case LT:
3447 fprintf (outf, " < ");
3448 break;
3449 case LEU:
3450 fprintf (outf, " <= (unsigned) ");
3451 break;
3452 case LTU:
3453 fprintf (outf, " < (unsigned) ");
3454 break;
3455 case PLUS:
3456 fprintf (outf, " + ");
3457 break;
3458 case MINUS:
3459 fprintf (outf, " - ");
3460 break;
3461 case MULT:
3462 fprintf (outf, " * ");
3463 break;
3464 case DIV:
3465 fprintf (outf, " / ");
3466 break;
3467 case MOD:
3468 fprintf (outf, " %% ");
3469 break;
3470 case AND:
3471 if (flags & FLG_BITWISE)
3472 fprintf (outf, " & ");
3473 else
3474 fprintf (outf, " && ");
3475 break;
3476 case IOR:
3477 if (flags & FLG_BITWISE)
3478 fprintf (outf, " | ");
3479 else
3480 fprintf (outf, " || ");
3481 break;
3482 case XOR:
3483 fprintf (outf, " ^ ");
3484 break;
3485 case ASHIFT:
3486 fprintf (outf, " << ");
3487 break;
3488 case LSHIFTRT:
3489 case ASHIFTRT:
3490 fprintf (outf, " >> ");
3491 break;
3492 default:
3493 gcc_unreachable ();
3496 if (code == AND)
3498 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3499 cached_x is only known to be initialized in then block. */
3500 flags &= ~FLG_AFTER;
3502 else if (code == IOR)
3504 if (flags & FLG_OUTSIDE_AND)
3505 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3506 cached_x is only known to be initialized in else block
3507 and else if conditions. */
3508 flags &= ~FLG_INSIDE;
3509 else
3510 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3511 && something_else)
3512 cached_x is not know to be initialized anywhere. */
3513 flags &= ~(FLG_AFTER | FLG_INSIDE);
3515 if ((code == AND || code == IOR)
3516 && (GET_CODE (XEXP (exp, 1)) == code
3517 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3518 || (GET_CODE (XEXP (exp, 1)) == NOT
3519 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3521 bool need_parens = true;
3523 /* No need to emit parentheses around the right-hand operand if we are
3524 continuing a chain of && or || (or & or |). */
3525 if (GET_CODE (XEXP (exp, 1)) == code)
3526 need_parens = false;
3528 attrs_cached
3529 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags,
3530 need_parens);
3532 else
3533 write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3534 flags | comparison_operator);
3535 break;
3537 case NOT:
3538 /* Special-case (not (eq_attrq "alternative" "x")) */
3539 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3541 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3543 fprintf (outf, "which_alternative != %s",
3544 XSTR (XEXP (exp, 0), 1));
3545 break;
3548 fprintf (outf, "! ");
3549 attrs_cached =
3550 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3551 break;
3554 /* Otherwise, fall through to normal unary operator. */
3555 gcc_fallthrough ();
3557 /* Unary operators. */
3558 case ABS: case NEG:
3559 switch (code)
3561 case NOT:
3562 if (flags & FLG_BITWISE)
3563 fprintf (outf, "~ ");
3564 else
3565 fprintf (outf, "! ");
3566 break;
3567 case ABS:
3568 fprintf (outf, "abs ");
3569 break;
3570 case NEG:
3571 fprintf (outf, "-");
3572 break;
3573 default:
3574 gcc_unreachable ();
3577 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3578 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3579 break;
3581 case EQ_ATTR_ALT:
3583 alternative_mask set = XWINT (exp, 0);
3584 int bit = 0;
3586 if (flags & FLG_BITWISE)
3587 fatal ("EQ_ATTR_ALT not valid inside comparison");
3589 if (!set)
3590 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3592 if (!(set & (set - 1)))
3594 if (!(set & 0xffffffff))
3596 bit += 32;
3597 set >>= 32;
3599 if (!(set & 0xffff))
3601 bit += 16;
3602 set >>= 16;
3604 if (!(set & 0xff))
3606 bit += 8;
3607 set >>= 8;
3609 if (!(set & 0xf))
3611 bit += 4;
3612 set >>= 4;
3614 if (!(set & 0x3))
3616 bit += 2;
3617 set >>= 2;
3619 if (!(set & 1))
3620 bit++;
3622 fprintf (outf, "which_alternative %s= %d",
3623 XWINT (exp, 1) ? "!" : "=", bit);
3625 else
3627 fprintf (outf, "%s((1ULL << which_alternative) & %#" PRIx64
3628 "ULL)",
3629 XWINT (exp, 1) ? "!" : "", set);
3632 break;
3634 /* Comparison test of an attribute with a value. Most of these will
3635 have been removed by optimization. Handle "alternative"
3636 specially and give error if EQ_ATTR present inside a comparison. */
3637 case EQ_ATTR:
3638 if (flags & FLG_BITWISE)
3639 fatal ("EQ_ATTR not valid inside comparison");
3641 if (XSTR (exp, 0) == alternative_name)
3643 fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3644 break;
3647 attr = find_attr (&XSTR (exp, 0), 0);
3648 gcc_assert (attr);
3650 /* Now is the time to expand the value of a constant attribute. */
3651 if (attr->is_const)
3653 write_test_expr (outf,
3654 evaluate_eq_attr (exp, attr,
3655 attr->default_val->value,
3656 -2, -2),
3657 attrs_cached, 0);
3659 else
3661 int i;
3662 for (i = 0; i < cached_attr_count; i++)
3663 if (attr->name == cached_attrs[i])
3664 break;
3665 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3666 fprintf (outf, "cached_%s", attr->name);
3667 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3669 fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3670 attr->name, attr->name);
3671 if (flags & FLG_AFTER)
3672 attrs_cached_after |= (1U << i);
3673 if (flags & FLG_INSIDE)
3674 attrs_cached_inside |= (1U << i);
3675 attrs_cached |= (1U << i);
3677 else
3678 fprintf (outf, "get_attr_%s (insn)", attr->name);
3679 fprintf (outf, " == ");
3680 write_attr_valueq (outf, attr, XSTR (exp, 1));
3682 break;
3684 /* Comparison test of flags for define_delays. */
3685 case ATTR_FLAG:
3686 if (flags & FLG_BITWISE)
3687 fatal ("ATTR_FLAG not valid inside comparison");
3688 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3689 break;
3691 /* See if an operand matches a predicate. */
3692 case MATCH_OPERAND:
3693 /* If only a mode is given, just ensure the mode matches the operand.
3694 If neither a mode nor predicate is given, error. */
3695 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3697 if (GET_MODE (exp) == VOIDmode)
3698 fatal ("null MATCH_OPERAND specified as test");
3699 else
3700 fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3701 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3703 else
3704 fprintf (outf, "%s (operands[%d], %smode)",
3705 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3706 break;
3708 /* Constant integer. */
3709 case CONST_INT:
3710 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3711 break;
3713 case MATCH_TEST:
3714 rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
3715 if (flags & FLG_BITWISE)
3716 fprintf (outf, " != 0");
3717 break;
3719 /* A random C expression. */
3720 case SYMBOL_REF:
3721 rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
3722 break;
3724 /* The address of the branch target. */
3725 case MATCH_DUP:
3726 fprintf (outf,
3727 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3728 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3729 break;
3731 case PC:
3732 /* The address of the current insn. We implement this actually as the
3733 address of the current insn for backward branches, but the last
3734 address of the next insn for forward branches, and both with
3735 adjustments that account for the worst-case possible stretching of
3736 intervening alignments between this insn and its destination. */
3737 fprintf (outf, "insn_current_reference_address (insn)");
3738 break;
3740 case CONST_STRING:
3741 fprintf (outf, "%s", XSTR (exp, 0));
3742 break;
3744 case IF_THEN_ELSE:
3745 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3746 fprintf (outf, " ? ");
3747 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3748 fprintf (outf, " : ");
3749 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3750 break;
3752 default:
3753 fatal ("bad RTX code `%s' in attribute calculation\n",
3754 GET_RTX_NAME (code));
3757 if (emit_parens)
3758 fprintf (outf, ")");
3760 return attrs_cached;
3763 /* Given an attribute value expression, return the maximum value that
3764 might be evaluated. Return INT_MAX if the value can't be
3765 calculated by this function. */
3767 static int
3768 max_attr_value (rtx exp)
3770 int current_max;
3771 int i, n;
3773 switch (GET_CODE (exp))
3775 case CONST_STRING:
3776 current_max = atoi (XSTR (exp, 0));
3777 break;
3779 case CONST_INT:
3780 current_max = INTVAL (exp);
3781 break;
3783 case PLUS:
3784 current_max = max_attr_value (XEXP (exp, 0));
3785 if (current_max != INT_MAX)
3787 n = current_max;
3788 current_max = max_attr_value (XEXP (exp, 1));
3789 if (current_max != INT_MAX)
3790 current_max += n;
3792 break;
3794 case MINUS:
3795 current_max = max_attr_value (XEXP (exp, 0));
3796 if (current_max != INT_MAX)
3798 n = current_max;
3799 current_max = min_attr_value (XEXP (exp, 1));
3800 if (current_max != INT_MAX)
3801 current_max = n - current_max;
3803 break;
3805 case MULT:
3806 current_max = max_attr_value (XEXP (exp, 0));
3807 if (current_max != INT_MAX)
3809 n = current_max;
3810 current_max = max_attr_value (XEXP (exp, 1));
3811 if (current_max != INT_MAX)
3812 current_max *= n;
3814 break;
3816 case COND:
3817 current_max = max_attr_value (XEXP (exp, 1));
3818 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3820 n = max_attr_value (XVECEXP (exp, 0, i + 1));
3821 if (n > current_max)
3822 current_max = n;
3824 break;
3826 case IF_THEN_ELSE:
3827 current_max = max_attr_value (XEXP (exp, 1));
3828 n = max_attr_value (XEXP (exp, 2));
3829 if (n > current_max)
3830 current_max = n;
3831 break;
3833 default:
3834 current_max = INT_MAX;
3835 break;
3838 return current_max;
3841 /* Given an attribute value expression, return the minimum value that
3842 might be evaluated. Return INT_MAX if the value can't be
3843 calculated by this function. Note that when this function can
3844 calculate one value inside IF_THEN_ELSE or some but not all values
3845 inside COND, then it returns the minimum among those values it can
3846 calculate. */
3848 static int
3849 min_attr_value (rtx exp)
3851 int current_min;
3852 int i, n;
3854 switch (GET_CODE (exp))
3856 case CONST_STRING:
3857 current_min = atoi (XSTR (exp, 0));
3858 break;
3860 case CONST_INT:
3861 current_min = INTVAL (exp);
3862 break;
3864 case PLUS:
3865 current_min = min_attr_value (XEXP (exp, 0));
3866 if (current_min != INT_MAX)
3868 n = current_min;
3869 current_min = min_attr_value (XEXP (exp, 1));
3870 if (current_min != INT_MAX)
3871 current_min += n;
3873 break;
3875 case MINUS:
3876 current_min = min_attr_value (XEXP (exp, 0));
3877 if (current_min != INT_MAX)
3879 n = current_min;
3880 current_min = max_attr_value (XEXP (exp, 1));
3881 if (current_min != INT_MAX)
3882 current_min = n - current_min;
3884 break;
3886 case MULT:
3887 current_min = min_attr_value (XEXP (exp, 0));
3888 if (current_min != INT_MAX)
3890 n = current_min;
3891 current_min = min_attr_value (XEXP (exp, 1));
3892 if (current_min != INT_MAX)
3893 current_min *= n;
3895 break;
3897 case COND:
3898 current_min = min_attr_value (XEXP (exp, 1));
3899 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3901 n = min_attr_value (XVECEXP (exp, 0, i + 1));
3902 if (n < current_min)
3903 current_min = n;
3905 break;
3907 case IF_THEN_ELSE:
3908 current_min = min_attr_value (XEXP (exp, 1));
3909 n = min_attr_value (XEXP (exp, 2));
3910 if (n < current_min)
3911 current_min = n;
3912 break;
3914 default:
3915 current_min = INT_MAX;
3916 break;
3919 return current_min;
3922 /* Given an attribute value expression, return the alignment of values.
3923 Return 0 if EXP is known to be zero, and 1 if the value can't be
3924 calculated by this function. */
3926 static unsigned int
3927 attr_value_alignment (rtx exp)
3929 unsigned int current_or;
3930 int i;
3932 switch (GET_CODE (exp))
3934 case CONST_STRING:
3935 current_or = atoi (XSTR (exp, 0));
3936 break;
3938 case CONST_INT:
3939 current_or = INTVAL (exp);
3940 break;
3942 case PLUS:
3943 case MINUS:
3944 current_or = attr_value_alignment (XEXP (exp, 0));
3945 current_or |= attr_value_alignment (XEXP (exp, 1));
3946 break;
3948 case MULT:
3949 current_or = attr_value_alignment (XEXP (exp, 0));
3950 current_or *= attr_value_alignment (XEXP (exp, 1));
3951 break;
3953 case COND:
3954 current_or = attr_value_alignment (XEXP (exp, 1));
3955 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3956 current_or |= attr_value_alignment (XVECEXP (exp, 0, i + 1));
3957 break;
3959 case IF_THEN_ELSE:
3960 current_or = attr_value_alignment (XEXP (exp, 1));
3961 current_or |= attr_value_alignment (XEXP (exp, 2));
3962 break;
3964 default:
3965 current_or = 1;
3966 break;
3969 return current_or & -current_or;
3972 /* Scan an attribute value, possibly a conditional, and record what actions
3973 will be required to do any conditional tests in it.
3975 Specifically, set
3976 `must_extract' if we need to extract the insn operands
3977 `must_constrain' if we must compute `which_alternative'
3978 `address_used' if an address expression was used
3979 `length_used' if an (eq_attr "length" ...) was used
3982 static void
3983 walk_attr_value (rtx exp)
3985 int i, j;
3986 const char *fmt;
3987 RTX_CODE code;
3989 if (exp == NULL)
3990 return;
3992 code = GET_CODE (exp);
3993 switch (code)
3995 case SYMBOL_REF:
3996 if (! ATTR_IND_SIMPLIFIED_P (exp))
3997 /* Since this is an arbitrary expression, it can look at anything.
3998 However, constant expressions do not depend on any particular
3999 insn. */
4000 must_extract = must_constrain = 1;
4001 return;
4003 case MATCH_OPERAND:
4004 must_extract = 1;
4005 return;
4007 case MATCH_TEST:
4008 case EQ_ATTR_ALT:
4009 must_extract = must_constrain = 1;
4010 break;
4012 case EQ_ATTR:
4013 if (XSTR (exp, 0) == alternative_name)
4014 must_extract = must_constrain = 1;
4015 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
4016 length_used = 1;
4017 return;
4019 case MATCH_DUP:
4020 must_extract = 1;
4021 address_used = 1;
4022 return;
4024 case PC:
4025 address_used = 1;
4026 return;
4028 case ATTR_FLAG:
4029 return;
4031 default:
4032 break;
4035 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4036 switch (*fmt++)
4038 case 'e':
4039 case 'u':
4040 walk_attr_value (XEXP (exp, i));
4041 break;
4043 case 'E':
4044 if (XVEC (exp, i) != NULL)
4045 for (j = 0; j < XVECLEN (exp, i); j++)
4046 walk_attr_value (XVECEXP (exp, i, j));
4047 break;
4051 /* Write out a function to obtain the attribute for a given INSN. */
4053 static void
4054 write_attr_get (FILE *outf, class attr_desc *attr)
4056 struct attr_value *av, *common_av;
4057 int i, j;
4059 /* Find the most used attribute value. Handle that as the `default' of the
4060 switch we will generate. */
4061 common_av = find_most_used (attr);
4063 /* Write out start of function, then all values with explicit `case' lines,
4064 then a `default', then the value with the most uses. */
4065 fprintf (outf, "%s\n", attr->cxx_type);
4067 /* If the attribute name starts with a star, the remainder is the name of
4068 the subroutine to use, instead of `get_attr_...'. */
4069 if (attr->name[0] == '*')
4070 fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4071 else if (attr->is_const == 0)
4072 fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
4073 else
4075 fprintf (outf, "get_attr_%s (void)\n", attr->name);
4076 fprintf (outf, "{\n");
4078 for (av = attr->first_value; av; av = av->next)
4079 if (av->num_insns == 1)
4080 write_attr_set (outf, attr, 2, av->value, "return", ";",
4081 true_rtx, av->first_insn->def->insn_code,
4082 av->first_insn->def->insn_index, 0);
4083 else if (av->num_insns != 0)
4084 write_attr_set (outf, attr, 2, av->value, "return", ";",
4085 true_rtx, -2, 0, 0);
4087 fprintf (outf, "}\n\n");
4088 return;
4091 fprintf (outf, "{\n");
4093 /* Find attributes that are worth caching in the conditions. */
4094 cached_attr_count = 0;
4095 attrs_seen_more_than_once = 0;
4096 for (av = attr->first_value; av; av = av->next)
4098 attrs_seen_once = 0;
4099 find_attrs_to_cache (av->value, true);
4101 /* Remove those that aren't worth caching from the array. */
4102 for (i = 0, j = 0; i < cached_attr_count; i++)
4103 if ((attrs_seen_more_than_once & (1U << i)) != 0)
4105 const char *name = cached_attrs[i];
4106 class attr_desc *cached_attr;
4107 if (i != j)
4108 cached_attrs[j] = name;
4109 cached_attr = find_attr (&name, 0);
4110 gcc_assert (cached_attr && cached_attr->is_const == 0);
4111 fprintf (outf, " %s cached_%s ATTRIBUTE_UNUSED;\n",
4112 cached_attr->cxx_type, name);
4113 j++;
4115 cached_attr_count = j;
4116 if (cached_attr_count)
4117 fprintf (outf, "\n");
4119 fprintf (outf, " switch (recog_memoized (insn))\n");
4120 fprintf (outf, " {\n");
4122 for (av = attr->first_value; av; av = av->next)
4123 if (av != common_av)
4124 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4126 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4127 fprintf (outf, " }\n}\n\n");
4128 cached_attr_count = 0;
4131 /* Given an AND tree of known true terms (because we are inside an `if' with
4132 that as the condition or are in an `else' clause) and an expression,
4133 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4134 the bulk of the work. */
4136 static rtx
4137 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4139 rtx term;
4141 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4143 if (GET_CODE (known_true) == AND)
4145 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4146 insn_code, insn_index);
4147 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4148 insn_code, insn_index);
4150 else
4152 term = known_true;
4153 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4156 return exp;
4159 /* Write out a series of tests and assignment statements to perform tests and
4160 sets of an attribute value. We are passed an indentation amount and prefix
4161 and suffix strings to write around each attribute value (e.g., "return"
4162 and ";"). */
4164 static void
4165 write_attr_set (FILE *outf, class attr_desc *attr, int indent, rtx value,
4166 const char *prefix, const char *suffix, rtx known_true,
4167 int insn_code, int insn_index, unsigned int attrs_cached)
4169 if (GET_CODE (value) == COND)
4171 /* Assume the default value will be the default of the COND unless we
4172 find an always true expression. */
4173 rtx default_val = XEXP (value, 1);
4174 rtx our_known_true = known_true;
4175 rtx newexp;
4176 int first_if = 1;
4177 int i;
4179 if (cached_attr_count)
4181 attrs_seen_once = 0;
4182 attrs_seen_more_than_once = 0;
4183 for (i = 0; i < XVECLEN (value, 0); i += 2)
4184 find_attrs_to_cache (XVECEXP (value, 0, i), false);
4185 attrs_to_cache |= attrs_seen_more_than_once;
4188 for (i = 0; i < XVECLEN (value, 0); i += 2)
4190 rtx testexp;
4191 rtx inner_true;
4193 /* Reset our_known_true after some time to not accumulate
4194 too much cruft (slowing down genattrtab). */
4195 if ((i & 31) == 0)
4196 our_known_true = known_true;
4197 testexp = eliminate_known_true (our_known_true,
4198 XVECEXP (value, 0, i),
4199 insn_code, insn_index);
4200 newexp = attr_rtx (NOT, testexp);
4201 newexp = insert_right_side (AND, our_known_true, newexp,
4202 insn_code, insn_index);
4204 /* If the test expression is always true or if the next `known_true'
4205 expression is always false, this is the last case, so break
4206 out and let this value be the `else' case. */
4207 if (testexp == true_rtx || newexp == false_rtx)
4209 default_val = XVECEXP (value, 0, i + 1);
4210 break;
4213 /* Compute the expression to pass to our recursive call as being
4214 known true. */
4215 inner_true = insert_right_side (AND, our_known_true,
4216 testexp, insn_code, insn_index);
4218 /* If this is always false, skip it. */
4219 if (inner_true == false_rtx)
4220 continue;
4222 attrs_cached_inside = attrs_cached;
4223 attrs_cached_after = attrs_cached;
4224 write_indent (outf, indent);
4225 fprintf (outf, "%sif ", first_if ? "" : "else ");
4226 first_if = 0;
4227 write_test_expr (outf, testexp, attrs_cached,
4228 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4229 attrs_cached = attrs_cached_after;
4230 fprintf (outf, "\n");
4231 write_indent (outf, indent + 2);
4232 fprintf (outf, "{\n");
4234 write_attr_set (outf, attr, indent + 4,
4235 XVECEXP (value, 0, i + 1), prefix, suffix,
4236 inner_true, insn_code, insn_index,
4237 attrs_cached_inside);
4238 write_indent (outf, indent + 2);
4239 fprintf (outf, "}\n");
4240 our_known_true = newexp;
4243 if (! first_if)
4245 write_indent (outf, indent);
4246 fprintf (outf, "else\n");
4247 write_indent (outf, indent + 2);
4248 fprintf (outf, "{\n");
4251 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4252 prefix, suffix, our_known_true, insn_code, insn_index,
4253 attrs_cached);
4255 if (! first_if)
4257 write_indent (outf, indent + 2);
4258 fprintf (outf, "}\n");
4261 else
4263 write_indent (outf, indent);
4264 fprintf (outf, "%s ", prefix);
4265 write_attr_value (outf, attr, value);
4266 fprintf (outf, "%s\n", suffix);
4270 /* Write a series of case statements for every instruction in list IE.
4271 INDENT is the amount of indentation to write before each case. */
4273 static void
4274 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4276 for (; ie != 0; ie = ie->next)
4277 if (ie->def->insn_code != -1)
4279 write_indent (outf, indent);
4280 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4281 fprintf (outf, "case %d: /* define_peephole, %s:%d */\n",
4282 ie->def->insn_code, ie->def->loc.filename,
4283 ie->def->loc.lineno);
4284 else
4285 fprintf (outf, "case %d: /* %s */\n",
4286 ie->def->insn_code, XSTR (ie->def->def, 0));
4290 /* Write out the computation for one attribute value. */
4292 static void
4293 write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
4294 int write_case_lines, const char *prefix, const char *suffix,
4295 int indent, rtx known_true)
4297 if (av->num_insns == 0)
4298 return;
4300 if (av->has_asm_insn)
4302 write_indent (outf, indent);
4303 fprintf (outf, "case -1:\n");
4304 write_indent (outf, indent + 2);
4305 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4306 write_indent (outf, indent + 2);
4307 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
4308 write_indent (outf, indent + 2);
4309 fprintf (outf, " fatal_insn_not_found (insn);\n");
4310 write_indent (outf, indent + 2);
4311 fprintf (outf, "/* FALLTHRU */\n");
4314 if (write_case_lines)
4315 write_insn_cases (outf, av->first_insn, indent);
4316 else
4318 write_indent (outf, indent);
4319 fprintf (outf, "default:\n");
4322 /* See what we have to do to output this value. */
4323 must_extract = must_constrain = address_used = 0;
4324 walk_attr_value (av->value);
4326 if (must_constrain)
4328 write_indent (outf, indent + 2);
4329 fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4331 else if (must_extract)
4333 write_indent (outf, indent + 2);
4334 fprintf (outf, "extract_insn_cached (insn);\n");
4337 attrs_to_cache = 0;
4338 if (av->num_insns == 1)
4339 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4340 known_true, av->first_insn->def->insn_code,
4341 av->first_insn->def->insn_index, 0);
4342 else
4343 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4344 known_true, -2, 0, 0);
4346 if (!startswith (prefix, "return"))
4348 write_indent (outf, indent + 2);
4349 fprintf (outf, "break;\n");
4351 fprintf (outf, "\n");
4354 /* Utilities to write in various forms. */
4356 static void
4357 write_attr_valueq (FILE *outf, class attr_desc *attr, const char *s)
4359 if (attr->is_numeric)
4361 int num = atoi (s);
4363 fprintf (outf, "%d", num);
4365 if (num > 9 || num < 0)
4366 fprintf (outf, " /* %#x */", num);
4368 else
4370 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4371 fprintf (outf, "_");
4372 write_upcase (outf, s);
4376 static void
4377 write_attr_value (FILE *outf, class attr_desc *attr, rtx value)
4379 int op;
4381 switch (GET_CODE (value))
4383 case CONST_STRING:
4384 write_attr_valueq (outf, attr, XSTR (value, 0));
4385 break;
4387 case CONST_INT:
4388 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4389 break;
4391 case SYMBOL_REF:
4392 rtx_reader_ptr->fprint_c_condition (outf, XSTR (value, 0));
4393 break;
4395 case ATTR:
4397 class attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4398 fprintf (outf, "(%s) get_attr_%s (%s)", attr->cxx_type, attr2->name,
4399 (attr2->is_const ? "" : "insn"));
4401 break;
4403 case PLUS:
4404 op = '+';
4405 goto do_operator;
4406 case MINUS:
4407 op = '-';
4408 goto do_operator;
4409 case MULT:
4410 op = '*';
4411 goto do_operator;
4412 case DIV:
4413 op = '/';
4414 goto do_operator;
4415 case MOD:
4416 op = '%';
4417 goto do_operator;
4419 do_operator:
4420 fprintf (outf, "(");
4421 write_attr_value (outf, attr, XEXP (value, 0));
4422 fprintf (outf, " %c ", op);
4423 write_attr_value (outf, attr, XEXP (value, 1));
4424 fprintf (outf, ")");
4425 break;
4427 case IF_THEN_ELSE:
4428 fprintf (outf, "(");
4429 write_test_expr (outf, XEXP (value, 0), 0, 0, false);
4430 fprintf (outf, " ? ");
4431 write_attr_value (outf, attr, XEXP (value, 1));
4432 fprintf (outf, " : ");
4433 write_attr_value (outf, attr, XEXP (value, 2));
4434 fprintf (outf, ")");
4435 break;
4437 default:
4438 gcc_unreachable ();
4442 static void
4443 write_upcase (FILE *outf, const char *str)
4445 while (*str)
4447 /* The argument of TOUPPER should not have side effects. */
4448 fputc (TOUPPER (*str), outf);
4449 str++;
4453 static void
4454 write_indent (FILE *outf, int indent)
4456 for (; indent > 8; indent -= 8)
4457 fprintf (outf, "\t");
4459 for (; indent; indent--)
4460 fprintf (outf, " ");
4463 /* If the target does not have annul-true or annul-false delay slots, this
4464 function will create a dummy eligible_for function on OUTF which always
4465 returns false. KIND will be annul_true or annul_false. */
4467 static void
4468 write_dummy_eligible_delay (FILE *outf, const char *kind)
4470 /* Write function prelude. */
4472 fprintf (outf, "int\n");
4473 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4474 " int slot ATTRIBUTE_UNUSED,\n"
4475 " rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4476 " int flags ATTRIBUTE_UNUSED)\n",
4477 kind);
4478 fprintf (outf, "{\n");
4479 fprintf (outf, " return 0;\n");
4480 fprintf (outf, "}\n\n");
4483 /* Write a subroutine that is given an insn that requires a delay slot, a
4484 delay slot ordinal, and a candidate insn. It returns nonzero if the
4485 candidate can be placed in the specified delay slot of the insn.
4487 We can write as many as three subroutines. `eligible_for_delay'
4488 handles normal delay slots, `eligible_for_annul_true' indicates that
4489 the specified insn can be annulled if the branch is true, and likewise
4490 for `eligible_for_annul_false'.
4492 KIND is a string distinguishing these three cases ("delay", "annul_true",
4493 or "annul_false"). */
4495 static void
4496 write_eligible_delay (FILE *outf, const char *kind)
4498 class delay_desc *delay;
4499 int max_slots;
4500 char str[50];
4501 const char *pstr;
4502 class attr_desc *attr;
4503 struct attr_value *av, *common_av;
4504 int i;
4506 /* Compute the maximum number of delay slots required. We use the delay
4507 ordinal times this number plus one, plus the slot number as an index into
4508 the appropriate predicate to test. */
4510 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4511 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4512 max_slots = XVECLEN (delay->def, 1) / 3;
4514 /* Write function prelude. */
4516 fprintf (outf, "int\n");
4517 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4518 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4519 kind);
4520 fprintf (outf, "{\n");
4521 fprintf (outf, " rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4522 fprintf (outf, "\n");
4523 fprintf (outf, " if (num_delay_slots (delay_insn) == 0)\n");
4524 fprintf (outf, " return 0;");
4525 fprintf (outf, "\n");
4526 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
4527 fprintf (outf, "\n");
4528 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4529 converts a compound instruction into a loop. */
4530 fprintf (outf, " if (!INSN_P (candidate_insn))\n");
4531 fprintf (outf, " return 0;\n");
4532 fprintf (outf, "\n");
4534 /* If more than one delay type, find out which type the delay insn is. */
4536 if (num_delays > 1)
4538 attr = find_attr (&delay_type_str, 0);
4539 gcc_assert (attr);
4540 common_av = find_most_used (attr);
4542 fprintf (outf, " insn = delay_insn;\n");
4543 fprintf (outf, " switch (recog_memoized (insn))\n");
4544 fprintf (outf, " {\n");
4546 sprintf (str, " * %d;\n break;", max_slots);
4547 for (av = attr->first_value; av; av = av->next)
4548 if (av != common_av)
4549 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4551 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4552 fprintf (outf, " }\n\n");
4554 /* Ensure matched. Otherwise, shouldn't have been called. */
4555 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
4558 /* If just one type of delay slot, write simple switch. */
4559 if (num_delays == 1 && max_slots == 1)
4561 fprintf (outf, " insn = candidate_insn;\n");
4562 fprintf (outf, " switch (recog_memoized (insn))\n");
4563 fprintf (outf, " {\n");
4565 attr = find_attr (&delay_1_0_str, 0);
4566 gcc_assert (attr);
4567 common_av = find_most_used (attr);
4569 for (av = attr->first_value; av; av = av->next)
4570 if (av != common_av)
4571 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4573 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4574 fprintf (outf, " }\n");
4577 else
4579 /* Write a nested CASE. The first indicates which condition we need to
4580 test, and the inner CASE tests the condition. */
4581 fprintf (outf, " insn = candidate_insn;\n");
4582 fprintf (outf, " switch (slot)\n");
4583 fprintf (outf, " {\n");
4585 for (delay = delays; delay; delay = delay->next)
4586 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4588 fprintf (outf, " case %d:\n",
4589 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4590 fprintf (outf, " switch (recog_memoized (insn))\n");
4591 fprintf (outf, "\t{\n");
4593 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4594 pstr = str;
4595 attr = find_attr (&pstr, 0);
4596 gcc_assert (attr);
4597 common_av = find_most_used (attr);
4599 for (av = attr->first_value; av; av = av->next)
4600 if (av != common_av)
4601 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4603 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4604 fprintf (outf, " }\n");
4607 fprintf (outf, " default:\n");
4608 fprintf (outf, " gcc_unreachable ();\n");
4609 fprintf (outf, " }\n");
4612 fprintf (outf, "}\n\n");
4615 /* This page contains miscellaneous utility routines. */
4617 /* Given a pointer to a (char *), return a malloc'ed string containing the
4618 next comma-separated element. Advance the pointer to after the string
4619 scanned, or the end-of-string. Return NULL if at end of string. */
4621 static char *
4622 next_comma_elt (const char **pstr)
4624 const char *start;
4626 start = scan_comma_elt (pstr);
4628 if (start == NULL)
4629 return NULL;
4631 return attr_string (start, *pstr - start);
4634 /* Return a `class attr_desc' pointer for a given named attribute. If CREATE
4635 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4636 replaced by a pointer to a canonical copy of the string. */
4638 static class attr_desc *
4639 find_attr (const char **name_p, int create)
4641 class attr_desc *attr;
4642 int index;
4643 const char *name = *name_p;
4645 /* Before we resort to using `strcmp', see if the string address matches
4646 anywhere. In most cases, it should have been canonicalized to do so. */
4647 if (name == alternative_name)
4648 return NULL;
4650 index = name[0] & (MAX_ATTRS_INDEX - 1);
4651 for (attr = attrs[index]; attr; attr = attr->next)
4652 if (name == attr->name)
4653 return attr;
4655 /* Otherwise, do it the slow way. */
4656 for (attr = attrs[index]; attr; attr = attr->next)
4657 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4659 *name_p = attr->name;
4660 return attr;
4663 if (! create)
4664 return NULL;
4666 attr = oballoc (class attr_desc);
4667 attr->name = DEF_ATTR_STRING (name);
4668 attr->enum_name = nullptr;
4669 attr->cxx_type = nullptr;
4670 attr->first_value = attr->default_val = NULL;
4671 attr->is_numeric = attr->is_const = attr->is_special = 0;
4672 attr->next = attrs[index];
4673 attrs[index] = attr;
4675 *name_p = attr->name;
4677 return attr;
4680 /* Create internal attribute with the given default value. */
4682 static void
4683 make_internal_attr (const char *name, rtx value, int special)
4685 class attr_desc *attr;
4687 attr = find_attr (&name, 1);
4688 gcc_assert (!attr->default_val);
4690 attr->cxx_type = "int";
4691 attr->is_numeric = 1;
4692 attr->is_const = 0;
4693 attr->is_special = (special & ATTR_SPECIAL) != 0;
4694 attr->default_val = get_attr_value (file_location ("<internal>", 0, 0),
4695 value, attr, -2);
4698 /* Find the most used value of an attribute. */
4700 static struct attr_value *
4701 find_most_used (class attr_desc *attr)
4703 struct attr_value *av;
4704 struct attr_value *most_used;
4705 int nuses;
4707 most_used = NULL;
4708 nuses = -1;
4710 for (av = attr->first_value; av; av = av->next)
4711 if (av->num_insns > nuses)
4712 nuses = av->num_insns, most_used = av;
4714 return most_used;
4717 /* Return (attr_value "n") */
4719 static rtx
4720 make_numeric_value (int n)
4722 static rtx int_values[20];
4723 rtx exp;
4724 char *p;
4726 gcc_assert (n >= 0);
4728 if (n < 20 && int_values[n])
4729 return int_values[n];
4731 p = attr_printf (MAX_DIGITS, "%d", n);
4732 exp = attr_rtx (CONST_STRING, p);
4734 if (n < 20)
4735 int_values[n] = exp;
4737 return exp;
4740 static rtx
4741 copy_rtx_unchanging (rtx orig)
4743 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4744 return orig;
4746 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4747 return orig;
4750 /* Determine if an insn has a constant number of delay slots, i.e., the
4751 number of delay slots is not a function of the length of the insn. */
4753 static void
4754 write_const_num_delay_slots (FILE *outf)
4756 class attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4757 struct attr_value *av;
4759 if (attr)
4761 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4762 fprintf (outf, "{\n");
4763 fprintf (outf, " switch (recog_memoized (insn))\n");
4764 fprintf (outf, " {\n");
4766 for (av = attr->first_value; av; av = av->next)
4768 length_used = 0;
4769 walk_attr_value (av->value);
4770 if (length_used)
4771 write_insn_cases (outf, av->first_insn, 4);
4774 fprintf (outf, " default:\n");
4775 fprintf (outf, " return 1;\n");
4776 fprintf (outf, " }\n}\n\n");
4780 /* Synthetic attributes used by insn-automata.cc and the scheduler.
4781 These are primarily concerned with (define_insn_reservation)
4782 patterns. */
4784 struct insn_reserv
4786 struct insn_reserv *next;
4788 const char *name;
4789 int default_latency;
4790 rtx condexp;
4792 /* Sequence number of this insn. */
4793 int insn_num;
4795 /* Whether a (define_bypass) construct names this insn in its
4796 output list. */
4797 bool bypassed;
4800 static struct insn_reserv *all_insn_reservs = 0;
4801 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4802 static size_t n_insn_reservs;
4804 /* Store information from a DEFINE_INSN_RESERVATION for future
4805 attribute generation. */
4806 static void
4807 gen_insn_reserv (md_rtx_info *info)
4809 struct insn_reserv *decl = oballoc (struct insn_reserv);
4810 rtx def = info->def;
4812 class attr_desc attr = { };
4814 attr.name = DEF_ATTR_STRING (XSTR (def, 0));
4815 attr.loc = info->loc;
4817 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4818 decl->default_latency = XINT (def, 1);
4819 decl->condexp = check_attr_test (info->loc, XEXP (def, 2), &attr);
4820 decl->insn_num = n_insn_reservs;
4821 decl->bypassed = false;
4822 decl->next = 0;
4824 *last_insn_reserv_p = decl;
4825 last_insn_reserv_p = &decl->next;
4826 n_insn_reservs++;
4829 /* Store information from a DEFINE_BYPASS for future attribute
4830 generation. The only thing we care about is the list of output
4831 insns, which will later be used to tag reservation structures with
4832 a 'bypassed' bit. */
4834 struct bypass_list
4836 struct bypass_list *next;
4837 const char *pattern;
4840 static struct bypass_list *all_bypasses;
4841 static size_t n_bypasses;
4842 static size_t n_bypassed;
4844 static void
4845 gen_bypass_1 (const char *s, size_t len)
4847 struct bypass_list *b;
4849 if (len == 0)
4850 return;
4852 s = attr_string (s, len);
4853 for (b = all_bypasses; b; b = b->next)
4854 if (s == b->pattern)
4855 return; /* already got that one */
4857 b = oballoc (struct bypass_list);
4858 b->pattern = s;
4859 b->next = all_bypasses;
4860 all_bypasses = b;
4861 n_bypasses++;
4864 static void
4865 gen_bypass (md_rtx_info *info)
4867 const char *p, *base;
4869 rtx def = info->def;
4870 for (p = base = XSTR (def, 1); *p; p++)
4871 if (*p == ',')
4873 gen_bypass_1 (base, p - base);
4875 p++;
4876 while (ISSPACE (*p));
4877 base = p;
4879 gen_bypass_1 (base, p - base);
4882 /* Find and mark all of the bypassed insns. */
4883 static void
4884 process_bypasses (void)
4886 struct bypass_list *b;
4887 struct insn_reserv *r;
4889 n_bypassed = 0;
4891 /* The reservation list is likely to be much longer than the bypass
4892 list. */
4893 for (r = all_insn_reservs; r; r = r->next)
4894 for (b = all_bypasses; b; b = b->next)
4895 if (fnmatch (b->pattern, r->name, 0) == 0)
4897 n_bypassed++;
4898 r->bypassed = true;
4899 break;
4903 /* Check that attribute NAME is used in define_insn_reservation condition
4904 EXP. Return true if it is. */
4905 static bool
4906 check_tune_attr (const char *name, rtx exp)
4908 switch (GET_CODE (exp))
4910 case AND:
4911 if (check_tune_attr (name, XEXP (exp, 0)))
4912 return true;
4913 return check_tune_attr (name, XEXP (exp, 1));
4915 case IOR:
4916 return (check_tune_attr (name, XEXP (exp, 0))
4917 && check_tune_attr (name, XEXP (exp, 1)));
4919 case EQ_ATTR:
4920 return XSTR (exp, 0) == name;
4922 default:
4923 return false;
4927 /* Try to find a const attribute (usually cpu or tune) that is used
4928 in all define_insn_reservation conditions. */
4929 static class attr_desc *
4930 find_tune_attr (rtx exp)
4932 class attr_desc *attr;
4934 switch (GET_CODE (exp))
4936 case AND:
4937 case IOR:
4938 attr = find_tune_attr (XEXP (exp, 0));
4939 if (attr)
4940 return attr;
4941 return find_tune_attr (XEXP (exp, 1));
4943 case EQ_ATTR:
4944 if (XSTR (exp, 0) == alternative_name)
4945 return NULL;
4947 attr = find_attr (&XSTR (exp, 0), 0);
4948 gcc_assert (attr);
4950 if (attr->is_const && !attr->is_special)
4952 struct insn_reserv *decl;
4954 for (decl = all_insn_reservs; decl; decl = decl->next)
4955 if (! check_tune_attr (attr->name, decl->condexp))
4956 return NULL;
4957 return attr;
4959 return NULL;
4961 default:
4962 return NULL;
4966 /* Create all of the attributes that describe automaton properties.
4967 Write the DFA and latency function prototypes to the files that
4968 need to have them, and write the init_sched_attrs(). */
4970 static void
4971 make_automaton_attrs (void)
4973 int i;
4974 struct insn_reserv *decl;
4975 rtx code_exp, lats_exp, byps_exp;
4976 class attr_desc *tune_attr;
4978 if (n_insn_reservs == 0)
4979 return;
4981 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4982 if (tune_attr != NULL)
4984 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4985 struct attr_value *val;
4986 bool first = true;
4988 gcc_assert (tune_attr->is_const
4989 && !tune_attr->is_special
4990 && !tune_attr->is_numeric);
4992 /* Write the prototypes for all DFA functions. */
4993 for (val = tune_attr->first_value; val; val = val->next)
4995 if (val == tune_attr->default_val)
4996 continue;
4997 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4998 fprintf (dfa_file,
4999 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
5000 XSTR (val->value, 0));
5002 fprintf (dfa_file, "\n");
5004 /* Write the prototypes for all latency functions. */
5005 for (val = tune_attr->first_value; val; val = val->next)
5007 if (val == tune_attr->default_val)
5008 continue;
5009 gcc_assert (GET_CODE (val->value) == CONST_STRING);
5010 fprintf (latency_file,
5011 "extern int insn_default_latency_%s (rtx_insn *);\n",
5012 XSTR (val->value, 0));
5014 fprintf (latency_file, "\n");
5016 /* Write the prototypes for all automaton functions. */
5017 for (val = tune_attr->first_value; val; val = val->next)
5019 if (val == tune_attr->default_val)
5020 continue;
5021 gcc_assert (GET_CODE (val->value) == CONST_STRING);
5022 fprintf (attr_file,
5023 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
5024 "extern int insn_default_latency_%s (rtx_insn *);\n",
5025 XSTR (val->value, 0), XSTR (val->value, 0));
5027 fprintf (attr_file, "\n");
5028 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
5029 fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n");
5030 fprintf (attr_file, "\n");
5031 fprintf (attr_file, "void\n");
5032 fprintf (attr_file, "init_sched_attrs (void)\n");
5033 fprintf (attr_file, "{\n");
5035 for (val = tune_attr->first_value; val; val = val->next)
5037 int j;
5038 char *name;
5039 rtx test = attr_eq (tune_attr->name, XSTR (val->value, 0));
5041 if (val == tune_attr->default_val)
5042 continue;
5043 for (decl = all_insn_reservs, i = 0;
5044 decl;
5045 decl = decl->next)
5047 rtx ctest = test;
5048 rtx condexp
5049 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
5050 if (condexp == false_rtx)
5051 continue;
5052 if (condexp == true_rtx)
5053 break;
5054 condexps[i] = condexp;
5055 condexps[i + 1] = make_numeric_value (decl->insn_num);
5056 condexps[i + 2] = make_numeric_value (decl->default_latency);
5057 i += 3;
5060 code_exp = rtx_alloc (COND);
5061 lats_exp = rtx_alloc (COND);
5063 j = i / 3 * 2;
5064 XVEC (code_exp, 0) = rtvec_alloc (j);
5065 XVEC (lats_exp, 0) = rtvec_alloc (j);
5067 if (decl)
5069 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
5070 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
5072 else
5074 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5075 XEXP (lats_exp, 1) = make_numeric_value (0);
5078 while (i > 0)
5080 i -= 3;
5081 j -= 2;
5082 XVECEXP (code_exp, 0, j) = condexps[i];
5083 XVECEXP (lats_exp, 0, j) = condexps[i];
5085 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
5086 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5089 name = XNEWVEC (char,
5090 sizeof ("*internal_dfa_insn_code_")
5091 + strlen (XSTR (val->value, 0)));
5092 strcpy (name, "*internal_dfa_insn_code_");
5093 strcat (name, XSTR (val->value, 0));
5094 make_internal_attr (name, code_exp, ATTR_NONE);
5095 strcpy (name, "*insn_default_latency_");
5096 strcat (name, XSTR (val->value, 0));
5097 make_internal_attr (name, lats_exp, ATTR_NONE);
5098 XDELETEVEC (name);
5100 if (first)
5102 fprintf (attr_file, " if (");
5103 first = false;
5105 else
5106 fprintf (attr_file, " else if (");
5107 write_test_expr (attr_file, test, 0, 0);
5108 fprintf (attr_file, ")\n");
5109 fprintf (attr_file, " {\n");
5110 fprintf (attr_file, " internal_dfa_insn_code\n");
5111 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
5112 XSTR (val->value, 0));
5113 fprintf (attr_file, " insn_default_latency\n");
5114 fprintf (attr_file, " = insn_default_latency_%s;\n",
5115 XSTR (val->value, 0));
5116 fprintf (attr_file, " }\n");
5119 fprintf (attr_file, " else\n");
5120 fprintf (attr_file, " gcc_unreachable ();\n");
5121 fprintf (attr_file, "}\n");
5122 fprintf (attr_file, "\n");
5124 XDELETEVEC (condexps);
5126 else
5128 code_exp = rtx_alloc (COND);
5129 lats_exp = rtx_alloc (COND);
5131 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5132 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5134 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5135 XEXP (lats_exp, 1) = make_numeric_value (0);
5137 for (decl = all_insn_reservs, i = 0;
5138 decl;
5139 decl = decl->next, i += 2)
5141 XVECEXP (code_exp, 0, i) = decl->condexp;
5142 XVECEXP (lats_exp, 0, i) = decl->condexp;
5144 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5145 XVECEXP (lats_exp, 0, i+1)
5146 = make_numeric_value (decl->default_latency);
5148 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5149 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
5152 if (n_bypasses == 0)
5153 byps_exp = make_numeric_value (0);
5154 else
5156 process_bypasses ();
5158 byps_exp = rtx_alloc (COND);
5159 XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2);
5160 XEXP (byps_exp, 1) = make_numeric_value (0);
5161 for (decl = all_insn_reservs, i = 0;
5162 decl;
5163 decl = decl->next)
5164 if (decl->bypassed)
5166 XVECEXP (byps_exp, 0, i) = decl->condexp;
5167 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5168 i += 2;
5172 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5175 static void
5176 write_header (FILE *outf)
5178 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5179 " from the machine description file `md'. */\n\n");
5181 fprintf (outf, "#define IN_TARGET_CODE 1\n");
5182 fprintf (outf, "#include \"config.h\"\n");
5183 fprintf (outf, "#include \"system.h\"\n");
5184 fprintf (outf, "#include \"coretypes.h\"\n");
5185 fprintf (outf, "#include \"backend.h\"\n");
5186 fprintf (outf, "#include \"predict.h\"\n");
5187 fprintf (outf, "#include \"tree.h\"\n");
5188 fprintf (outf, "#include \"rtl.h\"\n");
5189 fprintf (outf, "#include \"alias.h\"\n");
5190 fprintf (outf, "#include \"options.h\"\n");
5191 fprintf (outf, "#include \"varasm.h\"\n");
5192 fprintf (outf, "#include \"stor-layout.h\"\n");
5193 fprintf (outf, "#include \"calls.h\"\n");
5194 fprintf (outf, "#include \"insn-attr.h\"\n");
5195 fprintf (outf, "#include \"memmodel.h\"\n");
5196 fprintf (outf, "#include \"tm_p.h\"\n");
5197 fprintf (outf, "#include \"insn-config.h\"\n");
5198 fprintf (outf, "#include \"recog.h\"\n");
5199 fprintf (outf, "#include \"regs.h\"\n");
5200 fprintf (outf, "#include \"real.h\"\n");
5201 fprintf (outf, "#include \"output.h\"\n");
5202 fprintf (outf, "#include \"toplev.h\"\n");
5203 fprintf (outf, "#include \"flags.h\"\n");
5204 fprintf (outf, "#include \"emit-rtl.h\"\n");
5205 fprintf (outf, "\n");
5206 fprintf (outf, "#define operands recog_data.operand\n\n");
5209 static FILE *
5210 open_outfile (const char *file_name)
5212 FILE *outf;
5213 outf = fopen (file_name, "w");
5214 if (! outf)
5215 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5216 write_header (outf);
5217 return outf;
5220 static bool
5221 handle_arg (const char *arg)
5223 switch (arg[1])
5225 case 'A':
5226 attr_file_name = &arg[2];
5227 return true;
5228 case 'D':
5229 dfa_file_name = &arg[2];
5230 return true;
5231 case 'L':
5232 latency_file_name = &arg[2];
5233 return true;
5234 default:
5235 return false;
5240 main (int argc, const char **argv)
5242 class attr_desc *attr;
5243 class insn_def *id;
5244 int i;
5246 progname = "genattrtab";
5248 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5249 return FATAL_EXIT_CODE;
5251 attr_file = open_outfile (attr_file_name);
5252 dfa_file = open_outfile (dfa_file_name);
5253 latency_file = open_outfile (latency_file_name);
5255 obstack_init (hash_obstack);
5256 obstack_init (temp_obstack);
5258 /* Set up true and false rtx's */
5259 true_rtx = rtx_alloc (CONST_INT);
5260 XWINT (true_rtx, 0) = 1;
5261 false_rtx = rtx_alloc (CONST_INT);
5262 XWINT (false_rtx, 0) = 0;
5263 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5264 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5266 alternative_name = DEF_ATTR_STRING ("alternative");
5267 length_str = DEF_ATTR_STRING ("length");
5268 delay_type_str = DEF_ATTR_STRING ("*delay_type");
5269 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5270 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5272 /* Read the machine description. */
5274 md_rtx_info info;
5275 while (read_md_rtx (&info))
5277 switch (GET_CODE (info.def))
5279 case DEFINE_INSN:
5280 case DEFINE_PEEPHOLE:
5281 case DEFINE_ASM_ATTRIBUTES:
5282 gen_insn (&info);
5283 break;
5285 case DEFINE_ATTR:
5286 case DEFINE_ENUM_ATTR:
5287 gen_attr (&info);
5288 break;
5290 case DEFINE_DELAY:
5291 gen_delay (&info);
5292 break;
5294 case DEFINE_INSN_RESERVATION:
5295 gen_insn_reserv (&info);
5296 break;
5298 case DEFINE_BYPASS:
5299 gen_bypass (&info);
5300 break;
5302 default:
5303 break;
5305 if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
5306 insn_index_number++;
5309 if (have_error)
5310 return FATAL_EXIT_CODE;
5312 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5313 if (! got_define_asm_attributes)
5315 md_rtx_info info;
5316 info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5317 XVEC (info.def, 0) = rtvec_alloc (0);
5318 info.loc = file_location ("<internal>", 0, 0);
5319 info.index = -1;
5320 gen_insn (&info);
5323 /* Expand DEFINE_DELAY information into new attribute. */
5324 expand_delays ();
5326 /* Make `insn_alternatives'. */
5327 int num_insn_codes = get_num_insn_codes ();
5328 insn_alternatives = oballocvec (alternative_mask, num_insn_codes);
5329 for (id = defs; id; id = id->next)
5330 if (id->insn_code >= 0)
5331 insn_alternatives[id->insn_code]
5332 = (((alternative_mask) 1) << id->num_alternatives) - 1;
5334 /* Make `insn_n_alternatives'. */
5335 insn_n_alternatives = oballocvec (int, num_insn_codes);
5336 for (id = defs; id; id = id->next)
5337 if (id->insn_code >= 0)
5338 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5340 /* Construct extra attributes for automata. */
5341 make_automaton_attrs ();
5343 /* Prepare to write out attribute subroutines by checking everything stored
5344 away and building the attribute cases. */
5346 check_defs ();
5348 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5349 for (attr = attrs[i]; attr; attr = attr->next)
5350 attr->default_val->value
5351 = check_attr_value (attr->loc, attr->default_val->value, attr);
5353 if (have_error)
5354 return FATAL_EXIT_CODE;
5356 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5357 for (attr = attrs[i]; attr; attr = attr->next)
5358 fill_attr (attr);
5360 /* Construct extra attributes for `length'. */
5361 make_length_attrs ();
5363 /* Perform any possible optimizations to speed up compilation. */
5364 optimize_attrs (num_insn_codes);
5366 /* Now write out all the `gen_attr_...' routines. Do these before the
5367 special routines so that they get defined before they are used. */
5369 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5370 for (attr = attrs[i]; attr; attr = attr->next)
5372 FILE *outf;
5374 if (startswith(attr->name, "*internal_dfa_insn_code"))
5375 outf = dfa_file;
5376 else if (startswith (attr->name, "*insn_default_latency"))
5377 outf = latency_file;
5378 else
5379 outf = attr_file;
5381 if (! attr->is_special && ! attr->is_const)
5382 write_attr_get (outf, attr);
5385 /* Write out delay eligibility information, if DEFINE_DELAY present.
5386 (The function to compute the number of delay slots will be written
5387 below.) */
5388 write_eligible_delay (attr_file, "delay");
5389 if (have_annul_true)
5390 write_eligible_delay (attr_file, "annul_true");
5391 else
5392 write_dummy_eligible_delay (attr_file, "annul_true");
5393 if (have_annul_false)
5394 write_eligible_delay (attr_file, "annul_false");
5395 else
5396 write_dummy_eligible_delay (attr_file, "annul_false");
5398 /* Write out constant delay slot info. */
5399 write_const_num_delay_slots (attr_file);
5401 write_length_unit_log (attr_file);
5403 if (fclose (attr_file) != 0)
5404 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5405 if (fclose (dfa_file) != 0)
5406 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5407 if (fclose (latency_file) != 0)
5408 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5410 return SUCCESS_EXIT_CODE;