libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / genattrtab.cc
blob2a51549ddd438c4ccec5763f25717c03acbca9f5
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991-2024 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 'w': /* A wide integer? */
555 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
556 break;
558 case 's': /* A string? */
559 XSTR (rt_val, i) = va_arg (p, char *);
560 break;
562 case 'e': /* An expression? */
563 case 'u': /* An insn? Same except when printing. */
564 XEXP (rt_val, i) = va_arg (p, rtx);
565 break;
567 case 'E': /* An RTX vector? */
568 XVEC (rt_val, i) = va_arg (p, rtvec);
569 break;
571 default:
572 /* Don't need to handle 'p' for attributes. */
573 gcc_unreachable ();
576 return rt_val;
579 rtl_obstack = old_obstack;
580 attr_hash_add_rtx (hashcode, rt_val);
581 ATTR_PERMANENT_P (rt_val) = permanent_p;
582 return rt_val;
585 static rtx
586 attr_rtx (enum rtx_code code, ...)
588 rtx result;
589 va_list p;
591 va_start (p, code);
592 result = attr_rtx_1 (code, p);
593 va_end (p);
594 return result;
597 /* Create a new string printed with the printf line arguments into a space
598 of at most LEN bytes:
600 rtx attr_printf (len, format, [arg1, ..., argn]) */
602 static char *
603 attr_printf (unsigned int len, const char *fmt, ...)
605 char str[256];
606 va_list p;
608 va_start (p, fmt);
610 gcc_assert (len < sizeof str); /* Leave room for \0. */
612 vsprintf (str, fmt, p);
613 va_end (p);
615 return DEF_ATTR_STRING (str);
618 static rtx
619 attr_eq (const char *name, const char *value)
621 return attr_rtx (EQ_ATTR, name, value);
624 static const char *
625 attr_numeral (int n)
627 return XSTR (make_numeric_value (n), 0);
630 /* Return a permanent (possibly shared) copy of a string STR (not assumed
631 to be null terminated) with LEN bytes. */
633 static char *
634 attr_string (const char *str, int len)
636 struct attr_hash *h;
637 unsigned int hashcode;
638 int i;
639 char *new_str;
641 /* Compute the hash code. */
642 hashcode = (len + 1) * 613U + (unsigned) str[0];
643 for (i = 1; i < len; i += 2)
644 hashcode = ((hashcode * 613) + (unsigned) str[i]);
645 if ((int) hashcode < 0)
646 hashcode = -hashcode;
648 /* Search the table for the string. */
649 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
650 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
651 && !strncmp (h->u.str, str, len))
652 return h->u.str; /* <-- return if found. */
654 /* Not found; create a permanent copy and add it to the hash table. */
655 new_str = XOBNEWVAR (hash_obstack, char, len + 1);
656 memcpy (new_str, str, len);
657 new_str[len] = '\0';
658 attr_hash_add_string (hashcode, new_str);
659 rtx_reader_ptr->copy_md_ptr_loc (new_str, str);
661 return new_str; /* Return the new string. */
664 /* Check two rtx's for equality of contents,
665 taking advantage of the fact that if both are hashed
666 then they can't be equal unless they are the same object. */
668 static int
669 attr_equal_p (rtx x, rtx y)
671 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
672 && rtx_equal_p (x, y)));
675 /* Given a test expression EXP for attribute ATTR, ensure it is validly
676 formed. LOC is the location of the .md construct that contains EXP.
678 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
679 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
680 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
682 Update the string address in EQ_ATTR expression to be the same used
683 in the attribute (or `alternative_name') to speed up subsequent
684 `find_attr' calls and eliminate most `strcmp' calls.
686 Return the new expression, if any. */
688 static rtx
689 check_attr_test (file_location loc, rtx exp, attr_desc *attr)
691 struct attr_value *av;
692 const char *name_ptr, *p;
693 rtx orexp, newexp;
695 switch (GET_CODE (exp))
697 case EQ_ATTR:
698 /* Handle negation test. */
699 if (XSTR (exp, 1)[0] == '!')
700 return check_attr_test (loc,
701 attr_rtx (NOT,
702 attr_eq (XSTR (exp, 0),
703 &XSTR (exp, 1)[1])),
704 attr);
706 else if (n_comma_elts (XSTR (exp, 1)) == 1)
708 attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
709 if (attr2 == NULL)
711 if (! strcmp (XSTR (exp, 0), "alternative"))
712 return mk_attr_alt (((alternative_mask) 1)
713 << atoi (XSTR (exp, 1)));
714 else
715 fatal_at (loc, "unknown attribute `%s' in definition of"
716 " attribute `%s'", XSTR (exp, 0), attr->name);
719 if (attr->is_const && ! attr2->is_const)
720 fatal_at (loc, "constant attribute `%s' cannot test non-constant"
721 " attribute `%s'", attr->name, attr2->name);
723 /* Copy this just to make it permanent,
724 so expressions using it can be permanent too. */
725 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
727 /* It shouldn't be possible to simplify the value given to a
728 constant attribute, so don't expand this until it's time to
729 write the test expression. */
730 if (attr2->is_const)
731 ATTR_IND_SIMPLIFIED_P (exp) = 1;
733 if (attr2->is_numeric)
735 for (p = XSTR (exp, 1); *p; p++)
736 if (! ISDIGIT (*p))
737 fatal_at (loc, "attribute `%s' takes only numeric values",
738 attr2->name);
740 else
742 for (av = attr2->first_value; av; av = av->next)
743 if (GET_CODE (av->value) == CONST_STRING
744 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
745 break;
747 if (av == NULL)
748 fatal_at (loc, "unknown value `%s' for attribute `%s'",
749 XSTR (exp, 1), attr2->name);
752 else
754 if (! strcmp (XSTR (exp, 0), "alternative"))
756 int set = 0;
758 name_ptr = XSTR (exp, 1);
759 while ((p = next_comma_elt (&name_ptr)) != NULL)
760 set |= ((alternative_mask) 1) << atoi (p);
762 return mk_attr_alt (set);
764 else
766 /* Make an IOR tree of the possible values. */
767 orexp = false_rtx;
768 name_ptr = XSTR (exp, 1);
769 while ((p = next_comma_elt (&name_ptr)) != NULL)
771 newexp = attr_eq (XSTR (exp, 0), p);
772 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
775 return check_attr_test (loc, orexp, attr);
778 break;
780 case ATTR_FLAG:
781 break;
783 case CONST_INT:
784 /* Either TRUE or FALSE. */
785 if (XWINT (exp, 0))
786 return true_rtx;
787 else
788 return false_rtx;
790 case IOR:
791 case AND:
792 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
793 XEXP (exp, 1) = check_attr_test (loc, XEXP (exp, 1), attr);
794 break;
796 case NOT:
797 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
798 break;
800 case MATCH_TEST:
801 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
802 ATTR_IND_SIMPLIFIED_P (exp) = 1;
803 break;
805 case MATCH_OPERAND:
806 if (attr->is_const)
807 fatal_at (loc, "invalid operator `%s' in definition of constant"
808 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
809 attr->name);
810 /* These cases can't be simplified. */
811 ATTR_IND_SIMPLIFIED_P (exp) = 1;
812 break;
814 case LE: case LT: case GT: case GE:
815 case LEU: case LTU: case GTU: case GEU:
816 case NE: case EQ:
817 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
818 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
819 exp = attr_rtx (GET_CODE (exp),
820 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
821 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
822 /* These cases can't be simplified. */
823 ATTR_IND_SIMPLIFIED_P (exp) = 1;
824 break;
826 case SYMBOL_REF:
827 if (attr->is_const)
829 /* These cases are valid for constant attributes, but can't be
830 simplified. */
831 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
832 ATTR_IND_SIMPLIFIED_P (exp) = 1;
833 break;
835 /* FALLTHRU */
836 default:
837 fatal_at (loc, "invalid operator `%s' in definition of attribute"
838 " `%s'", GET_RTX_NAME (GET_CODE (exp)), attr->name);
841 return exp;
844 /* Given an expression EXP, ensure that it is validly formed and that
845 all named attribute values are valid for ATTR. Issue an error if not.
846 LOC is the location of the .md construct that contains EXP.
848 Return a perhaps modified replacement expression for the value. */
850 static rtx
851 check_attr_value (file_location loc, rtx exp, class attr_desc *attr)
853 struct attr_value *av;
854 const char *p;
855 int i;
857 switch (GET_CODE (exp))
859 case CONST_INT:
860 if (!attr->is_numeric)
862 error_at (loc,
863 "CONST_INT not valid for non-numeric attribute `%s'",
864 attr->name);
865 break;
868 if (INTVAL (exp) < 0)
870 error_at (loc,
871 "negative numeric value specified for attribute `%s'",
872 attr->name);
873 break;
875 break;
877 case CONST_STRING:
878 if (! strcmp (XSTR (exp, 0), "*"))
879 break;
881 if (attr->is_numeric)
883 p = XSTR (exp, 0);
884 for (; *p; p++)
885 if (! ISDIGIT (*p))
887 error_at (loc,
888 "non-numeric value specified for numeric"
889 " attribute `%s'", attr->name);
890 break;
892 break;
895 for (av = attr->first_value; av; av = av->next)
896 if (GET_CODE (av->value) == CONST_STRING
897 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
898 break;
900 if (av == NULL)
901 error_at (loc, "unknown value `%s' for attribute `%s'",
902 XSTR (exp, 0), attr->name);
903 break;
905 case IF_THEN_ELSE:
906 XEXP (exp, 0) = check_attr_test (loc, XEXP (exp, 0), attr);
907 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
908 XEXP (exp, 2) = check_attr_value (loc, XEXP (exp, 2), attr);
909 break;
911 case PLUS:
912 case MINUS:
913 case MULT:
914 case DIV:
915 case MOD:
916 if (!attr->is_numeric)
918 error_at (loc, "invalid operation `%s' for non-numeric"
919 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp)),
920 attr->name);
921 break;
923 /* Fall through. */
925 case IOR:
926 case AND:
927 XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
928 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
929 break;
931 case FFS:
932 case CLZ:
933 case CTZ:
934 case POPCOUNT:
935 case PARITY:
936 case BSWAP:
937 XEXP (exp, 0) = check_attr_value (loc, XEXP (exp, 0), attr);
938 break;
940 case COND:
941 if (XVECLEN (exp, 0) % 2 != 0)
943 error_at (loc, "first operand of COND must have even length");
944 break;
947 for (i = 0; i < XVECLEN (exp, 0); i += 2)
949 XVECEXP (exp, 0, i) = check_attr_test (attr->loc,
950 XVECEXP (exp, 0, i),
951 attr);
952 XVECEXP (exp, 0, i + 1)
953 = check_attr_value (loc, XVECEXP (exp, 0, i + 1), attr);
956 XEXP (exp, 1) = check_attr_value (loc, XEXP (exp, 1), attr);
957 break;
959 case ATTR:
961 class attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
962 if (attr2 == NULL)
963 error_at (loc, "unknown attribute `%s' in ATTR",
964 XSTR (exp, 0));
965 else if (attr->is_const && ! attr2->is_const)
966 error_at (attr->loc,
967 "constant attribute `%s' cannot refer to non-constant"
968 " attribute `%s'", attr->name, attr2->name);
969 else if (attr->is_numeric != attr2->is_numeric)
970 error_at (loc,
971 "numeric attribute mismatch calling `%s' from `%s'",
972 attr2->name, attr->name);
974 break;
976 case SYMBOL_REF:
977 /* A constant SYMBOL_REF is valid as a constant attribute test and
978 is expanded later by make_canonical into a COND. In a non-constant
979 attribute test, it is left be. */
980 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
982 default:
983 error_at (loc, "invalid operator `%s' in definition of attribute `%s'",
984 GET_RTX_NAME (GET_CODE (exp)), attr->name);
985 break;
988 return exp;
991 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
992 It becomes a COND with each test being (eq_attr "alternative" "n") */
994 static rtx
995 convert_set_attr_alternative (rtx exp, class insn_def *id)
997 int num_alt = id->num_alternatives;
998 rtx condexp;
999 int i;
1001 if (XVECLEN (exp, 1) != num_alt)
1003 error_at (id->loc, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1004 " was %d expected %d", XVECLEN (exp, 1), num_alt);
1005 return NULL_RTX;
1008 /* Make a COND with all tests but the last. Select the last value via the
1009 default. */
1010 condexp = rtx_alloc (COND);
1011 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1013 for (i = 0; i < num_alt - 1; i++)
1015 const char *p;
1016 p = attr_numeral (i);
1018 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1019 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1022 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1024 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1027 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1028 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1030 static rtx
1031 convert_set_attr (rtx exp, class insn_def *id)
1033 rtx newexp;
1034 const char *name_ptr;
1035 char *p;
1036 int n;
1038 /* See how many alternative specified. */
1039 n = n_comma_elts (XSTR (exp, 1));
1040 if (n == 1)
1041 return attr_rtx (SET,
1042 attr_rtx (ATTR, XSTR (exp, 0)),
1043 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1045 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1046 XSTR (newexp, 0) = XSTR (exp, 0);
1047 XVEC (newexp, 1) = rtvec_alloc (n);
1049 /* Process each comma-separated name. */
1050 name_ptr = XSTR (exp, 1);
1051 n = 0;
1052 while ((p = next_comma_elt (&name_ptr)) != NULL)
1053 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1055 return convert_set_attr_alternative (newexp, id);
1058 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1059 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1060 expressions. */
1062 static void
1063 check_defs (void)
1065 class insn_def *id;
1066 class attr_desc *attr;
1067 int i;
1068 rtx value;
1070 for (id = defs; id; id = id->next)
1072 if (XVEC (id->def, id->vec_idx) == NULL)
1073 continue;
1075 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1077 value = XVECEXP (id->def, id->vec_idx, i);
1078 switch (GET_CODE (value))
1080 case SET:
1081 if (GET_CODE (XEXP (value, 0)) != ATTR)
1083 error_at (id->loc, "bad attribute set");
1084 value = NULL_RTX;
1086 break;
1088 case SET_ATTR_ALTERNATIVE:
1089 value = convert_set_attr_alternative (value, id);
1090 break;
1092 case SET_ATTR:
1093 value = convert_set_attr (value, id);
1094 break;
1096 default:
1097 error_at (id->loc, "invalid attribute code %s",
1098 GET_RTX_NAME (GET_CODE (value)));
1099 value = NULL_RTX;
1101 if (value == NULL_RTX)
1102 continue;
1104 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1106 error_at (id->loc, "unknown attribute %s",
1107 XSTR (XEXP (value, 0), 0));
1108 continue;
1111 XVECEXP (id->def, id->vec_idx, i) = value;
1112 XEXP (value, 1) = check_attr_value (id->loc, XEXP (value, 1), attr);
1117 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1118 expressions by converting them into a COND. This removes cases from this
1119 program. Also, replace an attribute value of "*" with the default attribute
1120 value. LOC is the location to use for error reporting. */
1122 static rtx
1123 make_canonical (file_location loc, class attr_desc *attr, rtx exp)
1125 int i;
1126 rtx newexp;
1128 switch (GET_CODE (exp))
1130 case CONST_INT:
1131 exp = make_numeric_value (INTVAL (exp));
1132 break;
1134 case CONST_STRING:
1135 if (! strcmp (XSTR (exp, 0), "*"))
1137 if (attr->default_val == 0)
1138 fatal_at (loc, "(attr_value \"*\") used in invalid context");
1139 exp = attr->default_val->value;
1141 else
1142 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1144 break;
1146 case SYMBOL_REF:
1147 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1148 break;
1149 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1150 This makes the COND something that won't be considered an arbitrary
1151 expression by walk_attr_value. */
1152 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1153 exp = check_attr_value (loc, exp, attr);
1154 break;
1156 case IF_THEN_ELSE:
1157 newexp = rtx_alloc (COND);
1158 XVEC (newexp, 0) = rtvec_alloc (2);
1159 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1160 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1162 XEXP (newexp, 1) = XEXP (exp, 2);
1164 exp = newexp;
1165 /* Fall through to COND case since this is now a COND. */
1166 gcc_fallthrough ();
1168 case COND:
1170 int allsame = 1;
1171 rtx defval;
1173 /* First, check for degenerate COND. */
1174 if (XVECLEN (exp, 0) == 0)
1175 return make_canonical (loc, attr, XEXP (exp, 1));
1176 defval = XEXP (exp, 1) = make_canonical (loc, attr, XEXP (exp, 1));
1178 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1180 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1181 XVECEXP (exp, 0, i + 1)
1182 = make_canonical (loc, attr, XVECEXP (exp, 0, i + 1));
1183 if (! attr_equal_p (XVECEXP (exp, 0, i + 1), defval))
1184 allsame = 0;
1186 if (allsame)
1187 return defval;
1189 break;
1191 default:
1192 break;
1195 return exp;
1198 static rtx
1199 copy_boolean (rtx exp)
1201 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1202 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1203 copy_boolean (XEXP (exp, 1)));
1204 else if (GET_CODE (exp) == NOT)
1205 return attr_rtx (NOT, copy_boolean (XEXP (exp, 0)));
1206 if (GET_CODE (exp) == MATCH_OPERAND)
1208 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1209 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1211 else if (GET_CODE (exp) == EQ_ATTR)
1213 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1214 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1217 return exp;
1220 /* Given a value and an attribute description, return a `struct attr_value *'
1221 that represents that value. This is either an existing structure, if the
1222 value has been previously encountered, or a newly-created structure.
1224 `insn_code' is the code of an insn whose attribute has the specified
1225 value (-2 if not processing an insn). We ensure that all insns for
1226 a given value have the same number of alternatives if the value checks
1227 alternatives. LOC is the location to use for error reporting. */
1229 static struct attr_value *
1230 get_attr_value (file_location loc, rtx value, class attr_desc *attr,
1231 int insn_code)
1233 struct attr_value *av;
1234 alternative_mask num_alt = 0;
1236 value = make_canonical (loc, attr, value);
1237 if (compares_alternatives_p (value))
1239 if (insn_code < 0 || insn_alternatives == NULL)
1240 fatal_at (loc, "(eq_attr \"alternatives\" ...) used in non-insn"
1241 " context");
1242 else
1243 num_alt = insn_alternatives[insn_code];
1246 for (av = attr->first_value; av; av = av->next)
1247 if (attr_equal_p (value, av->value)
1248 && (num_alt == 0 || av->first_insn == NULL
1249 || insn_alternatives[av->first_insn->def->insn_code]))
1250 return av;
1252 av = oballoc (struct attr_value);
1253 av->value = value;
1254 av->next = attr->first_value;
1255 attr->first_value = av;
1256 av->first_insn = NULL;
1257 av->num_insns = 0;
1258 av->has_asm_insn = 0;
1260 return av;
1263 /* After all DEFINE_DELAYs have been read in, create internal attributes
1264 to generate the required routines.
1266 First, we compute the number of delay slots for each insn (as a COND of
1267 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1268 delay type is specified, we compute a similar function giving the
1269 DEFINE_DELAY ordinal for each insn.
1271 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1272 tells whether a given insn can be in that delay slot.
1274 Normal attribute filling and optimization expands these to contain the
1275 information needed to handle delay slots. */
1277 static void
1278 expand_delays (void)
1280 class delay_desc *delay;
1281 rtx condexp;
1282 rtx newexp;
1283 int i;
1284 char *p;
1286 /* First, generate data for `num_delay_slots' function. */
1288 condexp = rtx_alloc (COND);
1289 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1290 XEXP (condexp, 1) = make_numeric_value (0);
1292 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1294 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1295 XVECEXP (condexp, 0, i + 1)
1296 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1299 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1301 /* If more than one delay type, do the same for computing the delay type. */
1302 if (num_delays > 1)
1304 condexp = rtx_alloc (COND);
1305 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1306 XEXP (condexp, 1) = make_numeric_value (0);
1308 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1310 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1311 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1314 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1317 /* For each delay possibility and delay slot, compute an eligibility
1318 attribute for non-annulled insns and for each type of annulled (annul
1319 if true and annul if false). */
1320 for (delay = delays; delay; delay = delay->next)
1322 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1324 condexp = XVECEXP (delay->def, 1, i);
1325 if (condexp == 0)
1326 condexp = false_rtx;
1327 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1328 make_numeric_value (1), make_numeric_value (0));
1330 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1331 "*delay_%d_%d", delay->num, i / 3);
1332 make_internal_attr (p, newexp, ATTR_SPECIAL);
1334 if (have_annul_true)
1336 condexp = XVECEXP (delay->def, 1, i + 1);
1337 if (condexp == 0) condexp = false_rtx;
1338 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1339 make_numeric_value (1),
1340 make_numeric_value (0));
1341 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1342 "*annul_true_%d_%d", delay->num, i / 3);
1343 make_internal_attr (p, newexp, ATTR_SPECIAL);
1346 if (have_annul_false)
1348 condexp = XVECEXP (delay->def, 1, i + 2);
1349 if (condexp == 0) condexp = false_rtx;
1350 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1351 make_numeric_value (1),
1352 make_numeric_value (0));
1353 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1354 "*annul_false_%d_%d", delay->num, i / 3);
1355 make_internal_attr (p, newexp, ATTR_SPECIAL);
1361 /* Once all attributes and insns have been read and checked, we construct for
1362 each attribute value a list of all the insns that have that value for
1363 the attribute. */
1365 static void
1366 fill_attr (class attr_desc *attr)
1368 struct attr_value *av;
1369 struct insn_ent *ie;
1370 class insn_def *id;
1371 int i;
1372 rtx value;
1374 /* Don't fill constant attributes. The value is independent of
1375 any particular insn. */
1376 if (attr->is_const)
1377 return;
1379 for (id = defs; id; id = id->next)
1381 /* If no value is specified for this insn for this attribute, use the
1382 default. */
1383 value = NULL;
1384 if (XVEC (id->def, id->vec_idx))
1385 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1386 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1387 attr->name))
1388 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1390 if (value == NULL)
1391 av = attr->default_val;
1392 else
1393 av = get_attr_value (id->loc, value, attr, id->insn_code);
1395 ie = oballoc (struct insn_ent);
1396 ie->def = id;
1397 insert_insn_ent (av, ie);
1401 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1402 test that checks relative positions of insns (uses MATCH_DUP or PC).
1403 If so, replace it with what is obtained by passing the expression to
1404 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1405 recursively on each value (including the default value). Otherwise,
1406 return the value returned by NO_ADDRESS_FN applied to EXP. */
1408 static rtx
1409 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1410 rtx (*address_fn) (rtx))
1412 int i;
1413 rtx newexp;
1415 if (GET_CODE (exp) == COND)
1417 /* See if any tests use addresses. */
1418 address_used = 0;
1419 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1420 walk_attr_value (XVECEXP (exp, 0, i));
1422 if (address_used)
1423 return (*address_fn) (exp);
1425 /* Make a new copy of this COND, replacing each element. */
1426 newexp = rtx_alloc (COND);
1427 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1428 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1430 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1431 XVECEXP (newexp, 0, i + 1)
1432 = substitute_address (XVECEXP (exp, 0, i + 1),
1433 no_address_fn, address_fn);
1436 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1437 no_address_fn, address_fn);
1439 return newexp;
1442 else if (GET_CODE (exp) == IF_THEN_ELSE)
1444 address_used = 0;
1445 walk_attr_value (XEXP (exp, 0));
1446 if (address_used)
1447 return (*address_fn) (exp);
1449 return attr_rtx (IF_THEN_ELSE,
1450 substitute_address (XEXP (exp, 0),
1451 no_address_fn, address_fn),
1452 substitute_address (XEXP (exp, 1),
1453 no_address_fn, address_fn),
1454 substitute_address (XEXP (exp, 2),
1455 no_address_fn, address_fn));
1458 return (*no_address_fn) (exp);
1461 /* Make new attributes from the `length' attribute. The following are made,
1462 each corresponding to a function called from `shorten_branches' or
1463 `get_attr_length':
1465 *insn_default_length This is the length of the insn to be returned
1466 by `get_attr_length' before `shorten_branches'
1467 has been called. In each case where the length
1468 depends on relative addresses, the largest
1469 possible is used. This routine is also used
1470 to compute the initial size of the insn.
1472 *insn_variable_length_p This returns 1 if the insn's length depends
1473 on relative addresses, zero otherwise.
1475 *insn_current_length This is only called when it is known that the
1476 insn has a variable length and returns the
1477 current length, based on relative addresses.
1480 static void
1481 make_length_attrs (void)
1483 static const char *new_names[] =
1485 "*insn_default_length",
1486 "*insn_min_length",
1487 "*insn_variable_length_p",
1488 "*insn_current_length"
1490 static rtx (*const no_address_fn[]) (rtx)
1491 = {identity_fn,identity_fn, zero_fn, zero_fn};
1492 static rtx (*const address_fn[]) (rtx)
1493 = {max_fn, min_fn, one_fn, identity_fn};
1494 size_t i;
1495 class attr_desc *length_attr, *new_attr;
1496 struct attr_value *av, *new_av;
1497 struct insn_ent *ie, *new_ie;
1499 /* See if length attribute is defined. If so, it must be numeric. Make
1500 it special so we don't output anything for it. */
1501 length_attr = find_attr (&length_str, 0);
1502 if (length_attr == 0)
1503 return;
1505 if (! length_attr->is_numeric)
1506 fatal_at (length_attr->loc, "length attribute must be numeric");
1508 length_attr->is_const = 0;
1509 length_attr->is_special = 1;
1511 /* Make each new attribute, in turn. */
1512 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1514 make_internal_attr (new_names[i],
1515 substitute_address (length_attr->default_val->value,
1516 no_address_fn[i], address_fn[i]),
1517 ATTR_NONE);
1518 new_attr = find_attr (&new_names[i], 0);
1519 for (av = length_attr->first_value; av; av = av->next)
1520 for (ie = av->first_insn; ie; ie = ie->next)
1522 new_av = get_attr_value (ie->def->loc,
1523 substitute_address (av->value,
1524 no_address_fn[i],
1525 address_fn[i]),
1526 new_attr, ie->def->insn_code);
1527 new_ie = oballoc (struct insn_ent);
1528 new_ie->def = ie->def;
1529 insert_insn_ent (new_av, new_ie);
1534 /* Utility functions called from above routine. */
1536 static rtx
1537 identity_fn (rtx exp)
1539 return exp;
1542 static rtx
1543 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1545 return make_numeric_value (0);
1548 static rtx
1549 one_fn (rtx exp ATTRIBUTE_UNUSED)
1551 return make_numeric_value (1);
1554 static rtx
1555 max_fn (rtx exp)
1557 return make_numeric_value (max_attr_value (exp));
1560 static rtx
1561 min_fn (rtx exp)
1563 return make_numeric_value (min_attr_value (exp));
1566 static void
1567 write_length_unit_log (FILE *outf)
1569 class attr_desc *length_attr = find_attr (&length_str, 0);
1570 struct attr_value *av;
1571 struct insn_ent *ie;
1572 unsigned int length_unit_log, length_or;
1574 if (length_attr)
1576 length_or = attr_value_alignment (length_attr->default_val->value);
1577 for (av = length_attr->first_value; av; av = av->next)
1578 for (ie = av->first_insn; ie; ie = ie->next)
1579 length_or |= attr_value_alignment (av->value);
1581 length_or = ~length_or;
1582 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1583 length_unit_log++;
1585 else
1586 length_unit_log = 0;
1588 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1591 /* Compute approximate cost of the expression. Used to decide whether
1592 expression is cheap enough for inline. */
1593 static int
1594 attr_rtx_cost (rtx x)
1596 int cost = 1;
1597 enum rtx_code code;
1598 if (!x)
1599 return 0;
1600 code = GET_CODE (x);
1601 switch (code)
1603 case MATCH_OPERAND:
1604 if (XSTR (x, 1)[0])
1605 return 10;
1606 else
1607 return 1;
1609 case EQ_ATTR_ALT:
1610 return 1;
1612 case EQ_ATTR:
1613 /* Alternatives don't result into function call. */
1614 if (!strcmp_check (XSTR (x, 0), alternative_name))
1615 return 1;
1616 else
1617 return 5;
1618 default:
1620 int i, j;
1621 const char *fmt = GET_RTX_FORMAT (code);
1622 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1624 switch (fmt[i])
1626 case 'V':
1627 case 'E':
1628 for (j = 0; j < XVECLEN (x, i); j++)
1629 cost += attr_rtx_cost (XVECEXP (x, i, j));
1630 break;
1631 case 'e':
1632 cost += attr_rtx_cost (XEXP (x, i));
1633 break;
1637 break;
1639 return cost;
1642 /* Take a COND expression and see if any of the conditions in it can be
1643 simplified. If any are known true or known false for the particular insn
1644 code, the COND can be further simplified.
1646 Also call ourselves on any COND operations that are values of this COND.
1648 We do not modify EXP; rather, we make and return a new rtx. */
1650 static rtx
1651 simplify_cond (rtx exp, int insn_code, int insn_index)
1653 int i, j;
1654 /* We store the desired contents here,
1655 then build a new expression if they don't match EXP. */
1656 rtx defval = XEXP (exp, 1);
1657 rtx new_defval = XEXP (exp, 1);
1658 int len = XVECLEN (exp, 0);
1659 rtx *tests = XNEWVEC (rtx, len);
1660 int allsame = 1;
1661 rtx ret;
1663 /* This lets us free all storage allocated below, if appropriate. */
1664 obstack_finish (rtl_obstack);
1666 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1668 /* See if default value needs simplification. */
1669 if (GET_CODE (defval) == COND)
1670 new_defval = simplify_cond (defval, insn_code, insn_index);
1672 /* Simplify the subexpressions, and see what tests we can get rid of. */
1674 for (i = 0; i < len; i += 2)
1676 rtx newtest, newval;
1678 /* Simplify this test. */
1679 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1680 tests[i] = newtest;
1682 newval = tests[i + 1];
1683 /* See if this value may need simplification. */
1684 if (GET_CODE (newval) == COND)
1685 newval = simplify_cond (newval, insn_code, insn_index);
1687 /* Look for ways to delete or combine this test. */
1688 if (newtest == true_rtx)
1690 /* If test is true, make this value the default
1691 and discard this + any following tests. */
1692 len = i;
1693 defval = tests[i + 1];
1694 new_defval = newval;
1697 else if (newtest == false_rtx)
1699 /* If test is false, discard it and its value. */
1700 for (j = i; j < len - 2; j++)
1701 tests[j] = tests[j + 2];
1702 i -= 2;
1703 len -= 2;
1706 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1708 /* If this value and the value for the prev test are the same,
1709 merge the tests. */
1711 tests[i - 2]
1712 = insert_right_side (IOR, tests[i - 2], newtest,
1713 insn_code, insn_index);
1715 /* Delete this test/value. */
1716 for (j = i; j < len - 2; j++)
1717 tests[j] = tests[j + 2];
1718 len -= 2;
1719 i -= 2;
1722 else
1723 tests[i + 1] = newval;
1726 /* If the last test in a COND has the same value
1727 as the default value, that test isn't needed. */
1729 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1730 len -= 2;
1732 /* See if we changed anything. */
1733 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1734 allsame = 0;
1735 else
1736 for (i = 0; i < len; i++)
1737 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1739 allsame = 0;
1740 break;
1743 if (len == 0)
1745 if (GET_CODE (defval) == COND)
1746 ret = simplify_cond (defval, insn_code, insn_index);
1747 else
1748 ret = defval;
1750 else if (allsame)
1751 ret = exp;
1752 else
1754 rtx newexp = rtx_alloc (COND);
1756 XVEC (newexp, 0) = rtvec_alloc (len);
1757 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1758 XEXP (newexp, 1) = new_defval;
1759 ret = newexp;
1761 free (tests);
1762 return ret;
1765 /* Remove an insn entry from an attribute value. */
1767 static void
1768 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1770 struct insn_ent *previe;
1772 if (av->first_insn == ie)
1773 av->first_insn = ie->next;
1774 else
1776 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1778 previe->next = ie->next;
1781 av->num_insns--;
1782 if (ie->def->insn_code == -1)
1783 av->has_asm_insn = 0;
1785 num_insn_ents--;
1788 /* Insert an insn entry in an attribute value list. */
1790 static void
1791 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1793 ie->next = av->first_insn;
1794 av->first_insn = ie;
1795 av->num_insns++;
1796 if (ie->def->insn_code == -1)
1797 av->has_asm_insn = 1;
1799 num_insn_ents++;
1802 /* This is a utility routine to take an expression that is a tree of either
1803 AND or IOR expressions and insert a new term. The new term will be
1804 inserted at the right side of the first node whose code does not match
1805 the root. A new node will be created with the root's code. Its left
1806 side will be the old right side and its right side will be the new
1807 term.
1809 If the `term' is itself a tree, all its leaves will be inserted. */
1811 static rtx
1812 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1814 rtx newexp;
1816 /* Avoid consing in some special cases. */
1817 if (code == AND && term == true_rtx)
1818 return exp;
1819 if (code == AND && term == false_rtx)
1820 return false_rtx;
1821 if (code == AND && exp == true_rtx)
1822 return term;
1823 if (code == AND && exp == false_rtx)
1824 return false_rtx;
1825 if (code == IOR && term == true_rtx)
1826 return true_rtx;
1827 if (code == IOR && term == false_rtx)
1828 return exp;
1829 if (code == IOR && exp == true_rtx)
1830 return true_rtx;
1831 if (code == IOR && exp == false_rtx)
1832 return term;
1833 if (attr_equal_p (exp, term))
1834 return exp;
1836 if (GET_CODE (term) == code)
1838 exp = insert_right_side (code, exp, XEXP (term, 0),
1839 insn_code, insn_index);
1840 exp = insert_right_side (code, exp, XEXP (term, 1),
1841 insn_code, insn_index);
1843 return exp;
1846 if (GET_CODE (exp) == code)
1848 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1849 term, insn_code, insn_index);
1850 if (new_rtx != XEXP (exp, 1))
1851 /* Make a copy of this expression and call recursively. */
1852 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1853 else
1854 newexp = exp;
1856 else
1858 /* Insert the new term. */
1859 newexp = attr_rtx (code, exp, term);
1862 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1865 /* If we have an expression which AND's a bunch of
1866 (not (eq_attrq "alternative" "n"))
1867 terms, we may have covered all or all but one of the possible alternatives.
1868 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1870 This routine is passed an expression and either AND or IOR. It returns a
1871 bitmask indicating which alternatives are mentioned within EXP. */
1873 static alternative_mask
1874 compute_alternative_mask (rtx exp, enum rtx_code code)
1876 const char *string;
1877 if (GET_CODE (exp) == code)
1878 return compute_alternative_mask (XEXP (exp, 0), code)
1879 | compute_alternative_mask (XEXP (exp, 1), code);
1881 else if (code == AND && GET_CODE (exp) == NOT
1882 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1883 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1884 string = XSTR (XEXP (exp, 0), 1);
1886 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1887 && XSTR (exp, 0) == alternative_name)
1888 string = XSTR (exp, 1);
1890 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1892 if (code == AND && XWINT (exp, 1))
1893 return XWINT (exp, 0);
1895 if (code == IOR && !XWINT (exp, 1))
1896 return XWINT (exp, 0);
1898 return 0;
1900 else
1901 return 0;
1903 if (string[1] == 0)
1904 return ((alternative_mask) 1) << (string[0] - '0');
1905 return ((alternative_mask) 1) << atoi (string);
1908 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1909 attribute with the value represented by that bit. */
1911 static rtx
1912 make_alternative_compare (alternative_mask mask)
1914 return mk_attr_alt (mask);
1917 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1918 of "attr" for this insn code. From that value, we can compute a test
1919 showing when the EQ_ATTR will be true. This routine performs that
1920 computation. If a test condition involves an address, we leave the EQ_ATTR
1921 intact because addresses are only valid for the `length' attribute.
1923 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1924 it refers. VALUE is the value of that attribute for the insn
1925 corresponding to INSN_CODE and INSN_INDEX. */
1927 static rtx
1928 evaluate_eq_attr (rtx exp, class attr_desc *attr, rtx value,
1929 int insn_code, int insn_index)
1931 rtx orexp, andexp;
1932 rtx right;
1933 rtx newexp;
1934 int i;
1936 while (GET_CODE (value) == ATTR)
1938 struct attr_value *av = NULL;
1940 attr = find_attr (&XSTR (value, 0), 0);
1942 if (insn_code_values)
1944 struct attr_value_list *iv;
1945 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
1946 if (iv->attr == attr)
1948 av = iv->av;
1949 break;
1952 else
1954 struct insn_ent *ie;
1955 for (av = attr->first_value; av; av = av->next)
1956 for (ie = av->first_insn; ie; ie = ie->next)
1957 if (ie->def->insn_code == insn_code)
1958 goto got_av;
1960 if (av)
1962 got_av:
1963 value = av->value;
1967 switch (GET_CODE (value))
1969 case CONST_STRING:
1970 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
1971 newexp = true_rtx;
1972 else
1973 newexp = false_rtx;
1974 break;
1976 case SYMBOL_REF:
1978 const char *prefix;
1979 char *string, *p;
1981 gcc_assert (GET_CODE (exp) == EQ_ATTR);
1982 prefix = attr->enum_name ? attr->enum_name : attr->name;
1983 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
1984 for (p = string; *p; p++)
1985 *p = TOUPPER (*p);
1987 newexp = attr_rtx (EQ, value,
1988 attr_rtx (SYMBOL_REF,
1989 DEF_ATTR_STRING (string)));
1990 break;
1993 case COND:
1994 /* We construct an IOR of all the cases for which the
1995 requested attribute value is present. Since we start with
1996 FALSE, if it is not present, FALSE will be returned.
1998 Each case is the AND of the NOT's of the previous conditions with the
1999 current condition; in the default case the current condition is TRUE.
2001 For each possible COND value, call ourselves recursively.
2003 The extra TRUE and FALSE expressions will be eliminated by another
2004 call to the simplification routine. */
2006 orexp = false_rtx;
2007 andexp = true_rtx;
2009 for (i = 0; i < XVECLEN (value, 0); i += 2)
2011 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2012 insn_code, insn_index);
2014 right = insert_right_side (AND, andexp, this_cond,
2015 insn_code, insn_index);
2016 right = insert_right_side (AND, right,
2017 evaluate_eq_attr (exp, attr,
2018 XVECEXP (value, 0,
2019 i + 1),
2020 insn_code, insn_index),
2021 insn_code, insn_index);
2022 orexp = insert_right_side (IOR, orexp, right,
2023 insn_code, insn_index);
2025 /* Add this condition into the AND expression. */
2026 newexp = attr_rtx (NOT, this_cond);
2027 andexp = insert_right_side (AND, andexp, newexp,
2028 insn_code, insn_index);
2031 /* Handle the default case. */
2032 right = insert_right_side (AND, andexp,
2033 evaluate_eq_attr (exp, attr, XEXP (value, 1),
2034 insn_code, insn_index),
2035 insn_code, insn_index);
2036 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2037 break;
2039 default:
2040 gcc_unreachable ();
2043 /* If uses an address, must return original expression. But set the
2044 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2046 address_used = 0;
2047 walk_attr_value (newexp);
2049 if (address_used)
2051 if (! ATTR_IND_SIMPLIFIED_P (exp))
2052 return copy_rtx_unchanging (exp);
2053 return exp;
2055 else
2056 return newexp;
2059 /* This routine is called when an AND of a term with a tree of AND's is
2060 encountered. If the term or its complement is present in the tree, it
2061 can be replaced with TRUE or FALSE, respectively.
2063 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2064 be true and hence are complementary.
2066 There is one special case: If we see
2067 (and (not (eq_attr "att" "v1"))
2068 (eq_attr "att" "v2"))
2069 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2070 replace the term, not anything in the AND tree. So we pass a pointer to
2071 the term. */
2073 static rtx
2074 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2076 rtx left, right;
2077 rtx newexp;
2078 rtx temp;
2079 int left_eliminates_term, right_eliminates_term;
2081 if (GET_CODE (exp) == AND)
2083 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2084 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2085 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2087 newexp = attr_rtx (AND, left, right);
2089 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2093 else if (GET_CODE (exp) == IOR)
2095 /* For the IOR case, we do the same as above, except that we can
2096 only eliminate `term' if both sides of the IOR would do so. */
2097 temp = *pterm;
2098 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2099 left_eliminates_term = (temp == true_rtx);
2101 temp = *pterm;
2102 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2103 right_eliminates_term = (temp == true_rtx);
2105 if (left_eliminates_term && right_eliminates_term)
2106 *pterm = true_rtx;
2108 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2110 newexp = attr_rtx (IOR, left, right);
2112 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2116 /* Check for simplifications. Do some extra checking here since this
2117 routine is called so many times. */
2119 if (exp == *pterm)
2120 return true_rtx;
2122 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2123 return false_rtx;
2125 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2126 return false_rtx;
2128 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2130 if (attr_alt_subset_p (*pterm, exp))
2131 return true_rtx;
2133 if (attr_alt_subset_of_compl_p (*pterm, exp))
2134 return false_rtx;
2136 if (attr_alt_subset_p (exp, *pterm))
2137 *pterm = true_rtx;
2139 return exp;
2142 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2144 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2145 return exp;
2147 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2148 return true_rtx;
2149 else
2150 return false_rtx;
2153 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2154 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2156 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2157 return exp;
2159 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2160 return false_rtx;
2161 else
2162 return true_rtx;
2165 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2166 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2168 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2169 return exp;
2171 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2172 return false_rtx;
2173 else
2174 *pterm = true_rtx;
2177 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2179 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2180 return true_rtx;
2183 else if (GET_CODE (exp) == NOT)
2185 if (attr_equal_p (XEXP (exp, 0), *pterm))
2186 return false_rtx;
2189 else if (GET_CODE (*pterm) == NOT)
2191 if (attr_equal_p (XEXP (*pterm, 0), exp))
2192 return false_rtx;
2195 else if (attr_equal_p (exp, *pterm))
2196 return true_rtx;
2198 return exp;
2201 /* Similar to `simplify_and_tree', but for IOR trees. */
2203 static rtx
2204 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2206 rtx left, right;
2207 rtx newexp;
2208 rtx temp;
2209 int left_eliminates_term, right_eliminates_term;
2211 if (GET_CODE (exp) == IOR)
2213 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2214 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2215 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2217 newexp = attr_rtx (GET_CODE (exp), left, right);
2219 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2223 else if (GET_CODE (exp) == AND)
2225 /* For the AND case, we do the same as above, except that we can
2226 only eliminate `term' if both sides of the AND would do so. */
2227 temp = *pterm;
2228 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2229 left_eliminates_term = (temp == false_rtx);
2231 temp = *pterm;
2232 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2233 right_eliminates_term = (temp == false_rtx);
2235 if (left_eliminates_term && right_eliminates_term)
2236 *pterm = false_rtx;
2238 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2240 newexp = attr_rtx (GET_CODE (exp), left, right);
2242 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2246 if (attr_equal_p (exp, *pterm))
2247 return false_rtx;
2249 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2250 return true_rtx;
2252 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2253 return true_rtx;
2255 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2256 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2257 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2258 *pterm = false_rtx;
2260 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2261 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2262 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2263 return false_rtx;
2265 return exp;
2268 /* Simplify test expression and use temporary obstack in order to avoid
2269 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2270 and avoid unnecessary copying if possible. */
2272 static rtx
2273 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2275 rtx x;
2276 struct obstack *old;
2277 if (ATTR_IND_SIMPLIFIED_P (exp))
2278 return exp;
2279 old = rtl_obstack;
2280 rtl_obstack = temp_obstack;
2281 x = simplify_test_exp (exp, insn_code, insn_index);
2282 rtl_obstack = old;
2283 return x;
2286 /* Returns true if S1 is a subset of S2. */
2288 static bool
2289 attr_alt_subset_p (rtx s1, rtx s2)
2291 switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
2293 case (0 << 1) | 0:
2294 return !(XWINT (s1, 0) &~ XWINT (s2, 0));
2296 case (0 << 1) | 1:
2297 return !(XWINT (s1, 0) & XWINT (s2, 0));
2299 case (1 << 1) | 0:
2300 return false;
2302 case (1 << 1) | 1:
2303 return !(XWINT (s2, 0) &~ XWINT (s1, 0));
2305 default:
2306 gcc_unreachable ();
2310 /* Returns true if S1 is a subset of complement of S2. */
2312 static bool
2313 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2315 switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
2317 case (0 << 1) | 0:
2318 return !(XWINT (s1, 0) & XWINT (s2, 0));
2320 case (0 << 1) | 1:
2321 return !(XWINT (s1, 0) & ~XWINT (s2, 0));
2323 case (1 << 1) | 0:
2324 return !(XWINT (s2, 0) &~ XWINT (s1, 0));
2326 case (1 << 1) | 1:
2327 return false;
2329 default:
2330 gcc_unreachable ();
2334 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2336 static rtx
2337 attr_alt_intersection (rtx s1, rtx s2)
2339 alternative_mask result;
2341 switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
2343 case (0 << 1) | 0:
2344 result = XWINT (s1, 0) & XWINT (s2, 0);
2345 break;
2346 case (0 << 1) | 1:
2347 result = XWINT (s1, 0) & ~XWINT (s2, 0);
2348 break;
2349 case (1 << 1) | 0:
2350 result = XWINT (s2, 0) & ~XWINT (s1, 0);
2351 break;
2352 case (1 << 1) | 1:
2353 result = XWINT (s1, 0) | XWINT (s2, 0);
2354 break;
2355 default:
2356 gcc_unreachable ();
2359 return attr_rtx (EQ_ATTR_ALT, result, XWINT (s1, 1) & XWINT (s2, 1));
2362 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2364 static rtx
2365 attr_alt_union (rtx s1, rtx s2)
2367 alternative_mask result;
2369 switch ((XWINT (s1, 1) << 1) | XWINT (s2, 1))
2371 case (0 << 1) | 0:
2372 result = XWINT (s1, 0) | XWINT (s2, 0);
2373 break;
2374 case (0 << 1) | 1:
2375 result = XWINT (s2, 0) & ~XWINT (s1, 0);
2376 break;
2377 case (1 << 1) | 0:
2378 result = XWINT (s1, 0) & ~XWINT (s2, 0);
2379 break;
2380 case (1 << 1) | 1:
2381 result = XWINT (s1, 0) & XWINT (s2, 0);
2382 break;
2383 default:
2384 gcc_unreachable ();
2387 return attr_rtx (EQ_ATTR_ALT, result, XWINT (s1, 1) | XWINT (s2, 1));
2390 /* Return EQ_ATTR_ALT expression representing complement of S. */
2392 static rtx
2393 attr_alt_complement (rtx s)
2395 return attr_rtx (EQ_ATTR_ALT, XWINT (s, 0),
2396 HOST_WIDE_INT_1 - XWINT (s, 1));
2399 /* Return EQ_ATTR_ALT expression representing set containing elements set
2400 in E. */
2402 static rtx
2403 mk_attr_alt (alternative_mask e)
2405 return attr_rtx (EQ_ATTR_ALT, (HOST_WIDE_INT) e, HOST_WIDE_INT_0);
2408 /* Given an expression, see if it can be simplified for a particular insn
2409 code based on the values of other attributes being tested. This can
2410 eliminate nested get_attr_... calls.
2412 Note that if an endless recursion is specified in the patterns, the
2413 optimization will loop. However, it will do so in precisely the cases where
2414 an infinite recursion loop could occur during compilation. It's better that
2415 it occurs here! */
2417 static rtx
2418 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2420 rtx left, right;
2421 class attr_desc *attr;
2422 struct attr_value *av;
2423 struct insn_ent *ie;
2424 struct attr_value_list *iv;
2425 alternative_mask i;
2426 rtx newexp = exp;
2427 bool left_alt, right_alt;
2429 /* Don't re-simplify something we already simplified. */
2430 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2431 return exp;
2433 switch (GET_CODE (exp))
2435 case AND:
2436 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2437 if (left == false_rtx)
2438 return false_rtx;
2439 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2440 if (right == false_rtx)
2441 return false_rtx;
2443 if (GET_CODE (left) == EQ_ATTR_ALT
2444 && GET_CODE (right) == EQ_ATTR_ALT)
2446 exp = attr_alt_intersection (left, right);
2447 return simplify_test_exp (exp, insn_code, insn_index);
2450 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2451 present on both sides, apply the distributive law since this will
2452 yield simplifications. */
2453 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2454 && compute_alternative_mask (left, IOR)
2455 && compute_alternative_mask (right, IOR))
2457 if (GET_CODE (left) == IOR)
2458 std::swap (left, right);
2460 newexp = attr_rtx (IOR,
2461 attr_rtx (AND, left, XEXP (right, 0)),
2462 attr_rtx (AND, left, XEXP (right, 1)));
2464 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2467 /* Try with the term on both sides. */
2468 right = simplify_and_tree (right, &left, insn_code, insn_index);
2469 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2470 left = simplify_and_tree (left, &right, insn_code, insn_index);
2472 if (left == false_rtx || right == false_rtx)
2473 return false_rtx;
2474 else if (left == true_rtx)
2476 return right;
2478 else if (right == true_rtx)
2480 return left;
2482 /* See if all or all but one of the insn's alternatives are specified
2483 in this tree. Optimize if so. */
2485 if (GET_CODE (left) == NOT)
2486 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2487 && XSTR (XEXP (left, 0), 0) == alternative_name);
2488 else
2489 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2490 && XWINT (left, 1));
2492 if (GET_CODE (right) == NOT)
2493 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2494 && XSTR (XEXP (right, 0), 0) == alternative_name);
2495 else
2496 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2497 && XWINT (right, 1));
2499 if (insn_code >= 0
2500 && (GET_CODE (left) == AND
2501 || left_alt
2502 || GET_CODE (right) == AND
2503 || right_alt))
2505 i = compute_alternative_mask (exp, AND);
2506 if (i & ~insn_alternatives[insn_code])
2507 fatal ("invalid alternative specified for pattern number %d",
2508 insn_index);
2510 /* If all alternatives are excluded, this is false. */
2511 i ^= insn_alternatives[insn_code];
2512 if (i == 0)
2513 return false_rtx;
2514 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2516 /* If just one excluded, AND a comparison with that one to the
2517 front of the tree. The others will be eliminated by
2518 optimization. We do not want to do this if the insn has one
2519 alternative and we have tested none of them! */
2520 left = make_alternative_compare (i);
2521 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2522 newexp = attr_rtx (AND, left, right);
2524 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2528 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2530 newexp = attr_rtx (AND, left, right);
2531 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2533 break;
2535 case IOR:
2536 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2537 if (left == true_rtx)
2538 return true_rtx;
2539 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2540 if (right == true_rtx)
2541 return true_rtx;
2543 if (GET_CODE (left) == EQ_ATTR_ALT
2544 && GET_CODE (right) == EQ_ATTR_ALT)
2546 exp = attr_alt_union (left, right);
2547 return simplify_test_exp (exp, insn_code, insn_index);
2550 right = simplify_or_tree (right, &left, insn_code, insn_index);
2551 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2552 left = simplify_or_tree (left, &right, insn_code, insn_index);
2554 if (right == true_rtx || left == true_rtx)
2555 return true_rtx;
2556 else if (left == false_rtx)
2558 return right;
2560 else if (right == false_rtx)
2562 return left;
2565 /* Test for simple cases where the distributive law is useful. I.e.,
2566 convert (ior (and (x) (y))
2567 (and (x) (z)))
2568 to (and (x)
2569 (ior (y) (z)))
2572 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2573 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2575 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2577 left = XEXP (left, 0);
2578 right = newexp;
2579 newexp = attr_rtx (AND, left, right);
2580 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2583 /* Similarly,
2584 convert (ior (and (y) (x))
2585 (and (z) (x)))
2586 to (and (ior (y) (z))
2587 (x))
2588 Note that we want the common term to stay at the end.
2591 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2592 && attr_equal_p (XEXP (left, 1), XEXP (right, 1)))
2594 newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0));
2596 left = newexp;
2597 right = XEXP (right, 1);
2598 newexp = attr_rtx (AND, left, right);
2599 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2602 /* See if all or all but one of the insn's alternatives are specified
2603 in this tree. Optimize if so. */
2605 else if (insn_code >= 0
2606 && (GET_CODE (left) == IOR
2607 || (GET_CODE (left) == EQ_ATTR_ALT
2608 && !XWINT (left, 1))
2609 || (GET_CODE (left) == EQ_ATTR
2610 && XSTR (left, 0) == alternative_name)
2611 || GET_CODE (right) == IOR
2612 || (GET_CODE (right) == EQ_ATTR_ALT
2613 && !XWINT (right, 1))
2614 || (GET_CODE (right) == EQ_ATTR
2615 && XSTR (right, 0) == alternative_name)))
2617 i = compute_alternative_mask (exp, IOR);
2618 if (i & ~insn_alternatives[insn_code])
2619 fatal ("invalid alternative specified for pattern number %d",
2620 insn_index);
2622 /* If all alternatives are included, this is true. */
2623 i ^= insn_alternatives[insn_code];
2624 if (i == 0)
2625 return true_rtx;
2626 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2628 /* If just one excluded, IOR a comparison with that one to the
2629 front of the tree. The others will be eliminated by
2630 optimization. We do not want to do this if the insn has one
2631 alternative and we have tested none of them! */
2632 left = make_alternative_compare (i);
2633 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2634 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2636 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2640 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2642 newexp = attr_rtx (IOR, left, right);
2643 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2645 break;
2647 case NOT:
2648 if (GET_CODE (XEXP (exp, 0)) == NOT)
2650 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2651 insn_code, insn_index);
2652 return left;
2655 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2656 if (GET_CODE (left) == NOT)
2657 return XEXP (left, 0);
2659 if (left == false_rtx)
2660 return true_rtx;
2661 if (left == true_rtx)
2662 return false_rtx;
2664 if (GET_CODE (left) == EQ_ATTR_ALT)
2666 exp = attr_alt_complement (left);
2667 return simplify_test_exp (exp, insn_code, insn_index);
2670 /* Try to apply De`Morgan's laws. */
2671 if (GET_CODE (left) == IOR)
2673 newexp = attr_rtx (AND,
2674 attr_rtx (NOT, XEXP (left, 0)),
2675 attr_rtx (NOT, XEXP (left, 1)));
2677 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2679 else if (GET_CODE (left) == AND)
2681 newexp = attr_rtx (IOR,
2682 attr_rtx (NOT, XEXP (left, 0)),
2683 attr_rtx (NOT, XEXP (left, 1)));
2685 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2687 else if (left != XEXP (exp, 0))
2689 newexp = attr_rtx (NOT, left);
2691 break;
2693 case EQ_ATTR_ALT:
2694 if (!XWINT (exp, 0))
2695 return XWINT (exp, 1) ? true_rtx : false_rtx;
2696 break;
2698 case EQ_ATTR:
2699 if (XSTR (exp, 0) == alternative_name)
2701 newexp = mk_attr_alt (((alternative_mask) 1)
2702 << atoi (XSTR (exp, 1)));
2703 break;
2706 /* Look at the value for this insn code in the specified attribute.
2707 We normally can replace this comparison with the condition that
2708 would give this insn the values being tested for. */
2709 if (insn_code >= 0
2710 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2712 rtx x;
2714 av = NULL;
2715 if (insn_code_values)
2717 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2718 if (iv->attr == attr)
2720 av = iv->av;
2721 break;
2724 else
2726 for (av = attr->first_value; av; av = av->next)
2727 for (ie = av->first_insn; ie; ie = ie->next)
2728 if (ie->def->insn_code == insn_code)
2729 goto got_av;
2732 if (av)
2734 got_av:
2735 x = evaluate_eq_attr (exp, attr, av->value,
2736 insn_code, insn_index);
2737 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2738 if (attr_rtx_cost (x) < 7)
2739 return x;
2742 break;
2744 default:
2745 break;
2748 /* We have already simplified this expression. Simplifying it again
2749 won't buy anything unless we weren't given a valid insn code
2750 to process (i.e., we are canonicalizing something.). */
2751 if (insn_code != -2
2752 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2753 return copy_rtx_unchanging (newexp);
2755 return newexp;
2758 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2759 otherwise return 0. */
2761 static int
2762 tests_attr_p (rtx p, class attr_desc *attr)
2764 const char *fmt;
2765 int i, ie, j, je;
2767 if (GET_CODE (p) == EQ_ATTR)
2769 if (XSTR (p, 0) != attr->name)
2770 return 0;
2771 return 1;
2774 fmt = GET_RTX_FORMAT (GET_CODE (p));
2775 ie = GET_RTX_LENGTH (GET_CODE (p));
2776 for (i = 0; i < ie; i++)
2778 switch (*fmt++)
2780 case 'e':
2781 if (tests_attr_p (XEXP (p, i), attr))
2782 return 1;
2783 break;
2785 case 'E':
2786 je = XVECLEN (p, i);
2787 for (j = 0; j < je; ++j)
2788 if (tests_attr_p (XVECEXP (p, i, j), attr))
2789 return 1;
2790 break;
2794 return 0;
2797 /* Calculate a topological sorting of all attributes so that
2798 all attributes only depend on attributes in front of it.
2799 Place the result in *RET (which is a pointer to an array of
2800 attr_desc pointers), and return the size of that array. */
2802 static int
2803 get_attr_order (class attr_desc ***ret)
2805 int i, j;
2806 int num = 0;
2807 class attr_desc *attr;
2808 class attr_desc **all, **sorted;
2809 char *handled;
2810 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2811 for (attr = attrs[i]; attr; attr = attr->next)
2812 num++;
2813 all = XNEWVEC (class attr_desc *, num);
2814 sorted = XNEWVEC (class attr_desc *, num);
2815 handled = XCNEWVEC (char, num);
2816 num = 0;
2817 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2818 for (attr = attrs[i]; attr; attr = attr->next)
2819 all[num++] = attr;
2821 j = 0;
2822 for (i = 0; i < num; i++)
2823 if (all[i]->is_const)
2824 handled[i] = 1, sorted[j++] = all[i];
2826 /* We have only few attributes hence we can live with the inner
2827 loop being O(n^2), unlike the normal fast variants of topological
2828 sorting. */
2829 while (j < num)
2831 for (i = 0; i < num; i++)
2832 if (!handled[i])
2834 /* Let's see if I depends on anything interesting. */
2835 int k;
2836 for (k = 0; k < num; k++)
2837 if (!handled[k])
2839 struct attr_value *av;
2840 for (av = all[i]->first_value; av; av = av->next)
2841 if (av->num_insns != 0)
2842 if (tests_attr_p (av->value, all[k]))
2843 break;
2845 if (av)
2846 /* Something in I depends on K. */
2847 break;
2849 if (k == num)
2851 /* Nothing in I depended on anything intersting, so
2852 it's done. */
2853 handled[i] = 1;
2854 sorted[j++] = all[i];
2859 if (DEBUG)
2860 for (j = 0; j < num; j++)
2862 class attr_desc *attr2;
2863 struct attr_value *av;
2865 attr = sorted[j];
2866 fprintf (stderr, "%s depends on: ", attr->name);
2867 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
2868 for (attr2 = attrs[i]; attr2; attr2 = attr2->next)
2869 if (!attr2->is_const)
2870 for (av = attr->first_value; av; av = av->next)
2871 if (av->num_insns != 0)
2872 if (tests_attr_p (av->value, attr2))
2874 fprintf (stderr, "%s, ", attr2->name);
2875 break;
2877 fprintf (stderr, "\n");
2880 free (all);
2881 *ret = sorted;
2882 return num;
2885 /* Optimize the attribute lists by seeing if we can determine conditional
2886 values from the known values of other attributes. This will save subroutine
2887 calls during the compilation. NUM_INSN_CODES is the number of unique
2888 instruction codes. */
2890 static void
2891 optimize_attrs (int num_insn_codes)
2893 class attr_desc *attr;
2894 struct attr_value *av;
2895 struct insn_ent *ie;
2896 rtx newexp;
2897 int i;
2898 struct attr_value_list *ivbuf;
2899 struct attr_value_list *iv;
2900 class attr_desc **topsort;
2901 int topnum;
2903 /* For each insn code, make a list of all the insn_ent's for it,
2904 for all values for all attributes. */
2906 if (num_insn_ents == 0)
2907 return;
2909 /* Make 2 extra elements, for "code" values -2 and -1. */
2910 insn_code_values = XCNEWVEC (struct attr_value_list *, num_insn_codes + 2);
2912 /* Offset the table address so we can index by -2 or -1. */
2913 insn_code_values += 2;
2915 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2917 /* Create the chain of insn*attr values such that we see dependend
2918 attributes after their dependencies. As we use a stack via the
2919 next pointers start from the end of the topological order. */
2920 topnum = get_attr_order (&topsort);
2921 for (i = topnum - 1; i >= 0; i--)
2922 for (av = topsort[i]->first_value; av; av = av->next)
2923 for (ie = av->first_insn; ie; ie = ie->next)
2925 iv->attr = topsort[i];
2926 iv->av = av;
2927 iv->ie = ie;
2928 iv->next = insn_code_values[ie->def->insn_code];
2929 insn_code_values[ie->def->insn_code] = iv;
2930 iv++;
2932 free (topsort);
2934 /* Sanity check on num_insn_ents. */
2935 gcc_assert (iv == ivbuf + num_insn_ents);
2937 /* Process one insn code at a time. */
2938 for (i = -2; i < num_insn_codes; i++)
2940 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2941 We use it to mean "already simplified for this insn". */
2942 for (iv = insn_code_values[i]; iv; iv = iv->next)
2943 clear_struct_flag (iv->av->value);
2945 for (iv = insn_code_values[i]; iv; iv = iv->next)
2947 struct obstack *old = rtl_obstack;
2949 attr = iv->attr;
2950 av = iv->av;
2951 ie = iv->ie;
2952 if (GET_CODE (av->value) != COND)
2953 continue;
2955 rtl_obstack = temp_obstack;
2956 newexp = av->value;
2957 while (GET_CODE (newexp) == COND)
2959 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2960 ie->def->insn_index);
2961 if (newexp2 == newexp)
2962 break;
2963 newexp = newexp2;
2966 rtl_obstack = old;
2967 /* If we created a new value for this instruction, and it's
2968 cheaper than the old value, and overall cheap, use that
2969 one as specific value for the current instruction.
2970 The last test is to avoid exploding the get_attr_ function
2971 sizes for no much gain. */
2972 if (newexp != av->value
2973 && attr_rtx_cost (newexp) < attr_rtx_cost (av->value)
2974 && attr_rtx_cost (newexp) < 26
2977 remove_insn_ent (av, ie);
2978 av = get_attr_value (ie->def->loc, newexp, attr,
2979 ie->def->insn_code);
2980 iv->av = av;
2981 insert_insn_ent (av, ie);
2986 free (ivbuf);
2987 free (insn_code_values - 2);
2988 insn_code_values = NULL;
2991 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2993 static void
2994 clear_struct_flag (rtx x)
2996 int i;
2997 int j;
2998 enum rtx_code code;
2999 const char *fmt;
3001 ATTR_CURR_SIMPLIFIED_P (x) = 0;
3002 if (ATTR_IND_SIMPLIFIED_P (x))
3003 return;
3005 code = GET_CODE (x);
3007 switch (code)
3009 case REG:
3010 CASE_CONST_ANY:
3011 case MATCH_TEST:
3012 case SYMBOL_REF:
3013 case CODE_LABEL:
3014 case PC:
3015 case EQ_ATTR:
3016 case ATTR_FLAG:
3017 return;
3019 default:
3020 break;
3023 /* Compare the elements. If any pair of corresponding elements
3024 fail to match, return 0 for the whole things. */
3026 fmt = GET_RTX_FORMAT (code);
3027 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3029 switch (fmt[i])
3031 case 'V':
3032 case 'E':
3033 for (j = 0; j < XVECLEN (x, i); j++)
3034 clear_struct_flag (XVECEXP (x, i, j));
3035 break;
3037 case 'e':
3038 clear_struct_flag (XEXP (x, i));
3039 break;
3044 /* Add attribute value NAME to the beginning of ATTR's list. */
3046 static void
3047 add_attr_value (class attr_desc *attr, const char *name)
3049 struct attr_value *av;
3051 av = oballoc (struct attr_value);
3052 av->value = attr_rtx (CONST_STRING, name);
3053 av->next = attr->first_value;
3054 attr->first_value = av;
3055 av->first_insn = NULL;
3056 av->num_insns = 0;
3057 av->has_asm_insn = 0;
3060 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3062 static void
3063 gen_attr (md_rtx_info *info)
3065 struct enum_type *et;
3066 struct enum_value *ev;
3067 class attr_desc *attr;
3068 const char *name_ptr;
3069 char *p;
3070 rtx def = info->def;
3072 /* Make a new attribute structure. Check for duplicate by looking at
3073 attr->default_val, since it is initialized by this routine. */
3074 attr = find_attr (&XSTR (def, 0), 1);
3075 if (attr->default_val)
3077 error_at (info->loc, "duplicate definition for attribute %s",
3078 attr->name);
3079 message_at (attr->loc, "previous definition");
3080 return;
3082 attr->loc = info->loc;
3084 if (GET_CODE (def) == DEFINE_ENUM_ATTR)
3086 attr->enum_name = XSTR (def, 1);
3087 attr->cxx_type = attr->enum_name;
3088 et = rtx_reader_ptr->lookup_enum_type (XSTR (def, 1));
3089 if (!et || !et->md_p)
3090 error_at (info->loc, "No define_enum called `%s' defined",
3091 attr->name);
3092 if (et)
3093 for (ev = et->values; ev; ev = ev->next)
3094 add_attr_value (attr, ev->name);
3096 else if (*XSTR (def, 1) == '\0')
3098 attr->is_numeric = 1;
3099 attr->cxx_type = "int";
3101 else
3103 attr->cxx_type = concat ("attr_", attr->name, nullptr);
3104 name_ptr = XSTR (def, 1);
3105 while ((p = next_comma_elt (&name_ptr)) != NULL)
3106 add_attr_value (attr, p);
3109 if (GET_CODE (XEXP (def, 2)) == CONST)
3111 attr->is_const = 1;
3112 if (attr->is_numeric)
3113 error_at (info->loc,
3114 "constant attributes may not take numeric values");
3116 /* Get rid of the CONST node. It is allowed only at top-level. */
3117 XEXP (def, 2) = XEXP (XEXP (def, 2), 0);
3120 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3121 error_at (info->loc, "`length' attribute must take numeric values");
3123 /* Set up the default value. */
3124 XEXP (def, 2) = check_attr_value (info->loc, XEXP (def, 2), attr);
3125 attr->default_val = get_attr_value (info->loc, XEXP (def, 2), attr, -2);
3128 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3129 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3130 number of alternatives as this should be checked elsewhere. */
3132 static int
3133 count_alternatives (rtx exp)
3135 int i, j, n;
3136 const char *fmt;
3138 if (GET_CODE (exp) == MATCH_OPERAND)
3139 return n_comma_elts (XSTR (exp, 2));
3141 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3142 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3143 switch (*fmt++)
3145 case 'e':
3146 case 'u':
3147 n = count_alternatives (XEXP (exp, i));
3148 if (n)
3149 return n;
3150 break;
3152 case 'E':
3153 case 'V':
3154 if (XVEC (exp, i) != NULL)
3155 for (j = 0; j < XVECLEN (exp, i); j++)
3157 n = count_alternatives (XVECEXP (exp, i, j));
3158 if (n)
3159 return n;
3163 return 0;
3166 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3167 `alternative' attribute. */
3169 static int
3170 compares_alternatives_p (rtx exp)
3172 int i, j;
3173 const char *fmt;
3175 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3176 return 1;
3178 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3179 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3180 switch (*fmt++)
3182 case 'e':
3183 case 'u':
3184 if (compares_alternatives_p (XEXP (exp, i)))
3185 return 1;
3186 break;
3188 case 'E':
3189 for (j = 0; j < XVECLEN (exp, i); j++)
3190 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3191 return 1;
3192 break;
3195 return 0;
3198 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3200 static void
3201 gen_insn (md_rtx_info *info)
3203 class insn_def *id;
3204 rtx def = info->def;
3206 id = oballoc (class insn_def);
3207 id->next = defs;
3208 defs = id;
3209 id->def = def;
3210 id->loc = info->loc;
3212 switch (GET_CODE (def))
3214 case DEFINE_INSN:
3215 id->insn_code = info->index;
3216 id->insn_index = insn_index_number;
3217 id->num_alternatives = count_alternatives (def);
3218 if (id->num_alternatives == 0)
3219 id->num_alternatives = 1;
3220 id->vec_idx = 4;
3221 break;
3223 case DEFINE_PEEPHOLE:
3224 id->insn_code = info->index;
3225 id->insn_index = insn_index_number;
3226 id->num_alternatives = count_alternatives (def);
3227 if (id->num_alternatives == 0)
3228 id->num_alternatives = 1;
3229 id->vec_idx = 3;
3230 break;
3232 case DEFINE_ASM_ATTRIBUTES:
3233 id->insn_code = -1;
3234 id->insn_index = -1;
3235 id->num_alternatives = 1;
3236 id->vec_idx = 0;
3237 got_define_asm_attributes = 1;
3238 break;
3240 default:
3241 gcc_unreachable ();
3245 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3246 true or annul false is specified, and make a `struct delay_desc'. */
3248 static void
3249 gen_delay (md_rtx_info *info)
3251 class delay_desc *delay;
3252 int i;
3254 rtx def = info->def;
3255 if (XVECLEN (def, 1) % 3 != 0)
3257 error_at (info->loc, "number of elements in DEFINE_DELAY must"
3258 " be multiple of three");
3259 return;
3262 for (i = 0; i < XVECLEN (def, 1); i += 3)
3264 if (XVECEXP (def, 1, i + 1))
3265 have_annul_true = 1;
3266 if (XVECEXP (def, 1, i + 2))
3267 have_annul_false = 1;
3270 delay = oballoc (class delay_desc);
3271 delay->def = def;
3272 delay->num = ++num_delays;
3273 delay->next = delays;
3274 delay->loc = info->loc;
3275 delays = delay;
3278 /* Names of attributes that could be possibly cached. */
3279 static const char *cached_attrs[32];
3280 /* Number of such attributes. */
3281 static int cached_attr_count;
3282 /* Bitmasks of possibly cached attributes. */
3283 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3284 static unsigned int attrs_to_cache;
3285 static unsigned int attrs_cached_inside, attrs_cached_after;
3287 /* Finds non-const attributes that could be possibly cached.
3288 When create is TRUE, fills in cached_attrs array.
3289 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3290 bitmasks. */
3292 static void
3293 find_attrs_to_cache (rtx exp, bool create)
3295 int i;
3296 const char *name;
3297 class attr_desc *attr;
3299 if (exp == NULL)
3300 return;
3302 switch (GET_CODE (exp))
3304 case NOT:
3305 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3306 find_attrs_to_cache (XEXP (exp, 0), create);
3307 return;
3309 case EQ_ATTR:
3310 name = XSTR (exp, 0);
3311 if (name == alternative_name)
3312 return;
3313 for (i = 0; i < cached_attr_count; i++)
3314 if (name == cached_attrs[i])
3316 if ((attrs_seen_once & (1U << i)) != 0)
3317 attrs_seen_more_than_once |= (1U << i);
3318 else
3319 attrs_seen_once |= (1U << i);
3320 return;
3322 if (!create)
3323 return;
3324 attr = find_attr (&name, 0);
3325 gcc_assert (attr);
3326 if (attr->is_const)
3327 return;
3328 if (cached_attr_count == 32)
3329 return;
3330 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3331 attrs_seen_once |= (1U << cached_attr_count);
3332 cached_attr_count++;
3333 return;
3335 case AND:
3336 case IOR:
3337 find_attrs_to_cache (XEXP (exp, 0), create);
3338 find_attrs_to_cache (XEXP (exp, 1), create);
3339 return;
3341 case COND:
3342 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3343 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3344 return;
3346 default:
3347 return;
3351 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3352 We use AND and IOR both for logical and bit-wise operations, so
3353 interpret them as logical unless they are inside a comparison expression.
3355 An outermost pair of parentheses is emitted around this C expression unless
3356 EMIT_PARENS is false. */
3358 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3359 #define FLG_BITWISE 1
3360 /* Set if cached attribute will be known initialized in else block after
3361 this condition. This is true for LHS of toplevel && and || and
3362 even for RHS of ||, but not for RHS of &&. */
3363 #define FLG_AFTER 2
3364 /* Set if cached attribute will be known initialized in then 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_INSIDE 4
3368 /* Cleared when an operand of &&. */
3369 #define FLG_OUTSIDE_AND 8
3371 static unsigned int
3372 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags,
3373 bool emit_parens = true)
3375 int comparison_operator = 0;
3376 RTX_CODE code;
3377 class attr_desc *attr;
3379 if (emit_parens)
3380 fprintf (outf, "(");
3382 code = GET_CODE (exp);
3383 switch (code)
3385 /* Binary operators. */
3386 case GEU: case GTU:
3387 case LEU: case LTU:
3388 fprintf (outf, "(unsigned) ");
3389 /* Fall through. */
3391 case EQ: case NE:
3392 case GE: case GT:
3393 case LE: case LT:
3394 comparison_operator = FLG_BITWISE;
3395 /* FALLTHRU */
3397 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3398 case AND: case IOR: case XOR:
3399 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3400 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3402 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3403 write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3404 flags | comparison_operator);
3406 else
3408 if (code == AND)
3409 flags &= ~FLG_OUTSIDE_AND;
3410 if (GET_CODE (XEXP (exp, 0)) == code
3411 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3412 || (GET_CODE (XEXP (exp, 0)) == NOT
3413 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3414 attrs_cached
3415 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3416 else
3417 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3419 switch (code)
3421 case EQ:
3422 fprintf (outf, " == ");
3423 break;
3424 case NE:
3425 fprintf (outf, " != ");
3426 break;
3427 case GE:
3428 fprintf (outf, " >= ");
3429 break;
3430 case GT:
3431 fprintf (outf, " > ");
3432 break;
3433 case GEU:
3434 fprintf (outf, " >= (unsigned) ");
3435 break;
3436 case GTU:
3437 fprintf (outf, " > (unsigned) ");
3438 break;
3439 case LE:
3440 fprintf (outf, " <= ");
3441 break;
3442 case LT:
3443 fprintf (outf, " < ");
3444 break;
3445 case LEU:
3446 fprintf (outf, " <= (unsigned) ");
3447 break;
3448 case LTU:
3449 fprintf (outf, " < (unsigned) ");
3450 break;
3451 case PLUS:
3452 fprintf (outf, " + ");
3453 break;
3454 case MINUS:
3455 fprintf (outf, " - ");
3456 break;
3457 case MULT:
3458 fprintf (outf, " * ");
3459 break;
3460 case DIV:
3461 fprintf (outf, " / ");
3462 break;
3463 case MOD:
3464 fprintf (outf, " %% ");
3465 break;
3466 case AND:
3467 if (flags & FLG_BITWISE)
3468 fprintf (outf, " & ");
3469 else
3470 fprintf (outf, " && ");
3471 break;
3472 case IOR:
3473 if (flags & FLG_BITWISE)
3474 fprintf (outf, " | ");
3475 else
3476 fprintf (outf, " || ");
3477 break;
3478 case XOR:
3479 fprintf (outf, " ^ ");
3480 break;
3481 case ASHIFT:
3482 fprintf (outf, " << ");
3483 break;
3484 case LSHIFTRT:
3485 case ASHIFTRT:
3486 fprintf (outf, " >> ");
3487 break;
3488 default:
3489 gcc_unreachable ();
3492 if (code == AND)
3494 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3495 cached_x is only known to be initialized in then block. */
3496 flags &= ~FLG_AFTER;
3498 else if (code == IOR)
3500 if (flags & FLG_OUTSIDE_AND)
3501 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3502 cached_x is only known to be initialized in else block
3503 and else if conditions. */
3504 flags &= ~FLG_INSIDE;
3505 else
3506 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3507 && something_else)
3508 cached_x is not know to be initialized anywhere. */
3509 flags &= ~(FLG_AFTER | FLG_INSIDE);
3511 if ((code == AND || code == IOR)
3512 && (GET_CODE (XEXP (exp, 1)) == code
3513 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3514 || (GET_CODE (XEXP (exp, 1)) == NOT
3515 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3517 bool need_parens = true;
3519 /* No need to emit parentheses around the right-hand operand if we are
3520 continuing a chain of && or || (or & or |). */
3521 if (GET_CODE (XEXP (exp, 1)) == code)
3522 need_parens = false;
3524 attrs_cached
3525 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags,
3526 need_parens);
3528 else
3529 write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3530 flags | comparison_operator);
3531 break;
3533 case NOT:
3534 /* Special-case (not (eq_attrq "alternative" "x")) */
3535 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3537 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3539 fprintf (outf, "which_alternative != %s",
3540 XSTR (XEXP (exp, 0), 1));
3541 break;
3544 fprintf (outf, "! ");
3545 attrs_cached =
3546 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3547 break;
3550 /* Otherwise, fall through to normal unary operator. */
3551 gcc_fallthrough ();
3553 /* Unary operators. */
3554 case ABS: case NEG:
3555 switch (code)
3557 case NOT:
3558 if (flags & FLG_BITWISE)
3559 fprintf (outf, "~ ");
3560 else
3561 fprintf (outf, "! ");
3562 break;
3563 case ABS:
3564 fprintf (outf, "abs ");
3565 break;
3566 case NEG:
3567 fprintf (outf, "-");
3568 break;
3569 default:
3570 gcc_unreachable ();
3573 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3574 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3575 break;
3577 case EQ_ATTR_ALT:
3579 alternative_mask set = XWINT (exp, 0);
3580 int bit = 0;
3582 if (flags & FLG_BITWISE)
3583 fatal ("EQ_ATTR_ALT not valid inside comparison");
3585 if (!set)
3586 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3588 if (!(set & (set - 1)))
3590 if (!(set & 0xffffffff))
3592 bit += 32;
3593 set >>= 32;
3595 if (!(set & 0xffff))
3597 bit += 16;
3598 set >>= 16;
3600 if (!(set & 0xff))
3602 bit += 8;
3603 set >>= 8;
3605 if (!(set & 0xf))
3607 bit += 4;
3608 set >>= 4;
3610 if (!(set & 0x3))
3612 bit += 2;
3613 set >>= 2;
3615 if (!(set & 1))
3616 bit++;
3618 fprintf (outf, "which_alternative %s= %d",
3619 XWINT (exp, 1) ? "!" : "=", bit);
3621 else
3623 fprintf (outf, "%s((1ULL << which_alternative) & %#" PRIx64
3624 "ULL)",
3625 XWINT (exp, 1) ? "!" : "", set);
3628 break;
3630 /* Comparison test of an attribute with a value. Most of these will
3631 have been removed by optimization. Handle "alternative"
3632 specially and give error if EQ_ATTR present inside a comparison. */
3633 case EQ_ATTR:
3634 if (flags & FLG_BITWISE)
3635 fatal ("EQ_ATTR not valid inside comparison");
3637 if (XSTR (exp, 0) == alternative_name)
3639 fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3640 break;
3643 attr = find_attr (&XSTR (exp, 0), 0);
3644 gcc_assert (attr);
3646 /* Now is the time to expand the value of a constant attribute. */
3647 if (attr->is_const)
3649 write_test_expr (outf,
3650 evaluate_eq_attr (exp, attr,
3651 attr->default_val->value,
3652 -2, -2),
3653 attrs_cached, 0);
3655 else
3657 int i;
3658 for (i = 0; i < cached_attr_count; i++)
3659 if (attr->name == cached_attrs[i])
3660 break;
3661 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3662 fprintf (outf, "cached_%s", attr->name);
3663 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3665 fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3666 attr->name, attr->name);
3667 if (flags & FLG_AFTER)
3668 attrs_cached_after |= (1U << i);
3669 if (flags & FLG_INSIDE)
3670 attrs_cached_inside |= (1U << i);
3671 attrs_cached |= (1U << i);
3673 else
3674 fprintf (outf, "get_attr_%s (insn)", attr->name);
3675 fprintf (outf, " == ");
3676 write_attr_valueq (outf, attr, XSTR (exp, 1));
3678 break;
3680 /* Comparison test of flags for define_delays. */
3681 case ATTR_FLAG:
3682 if (flags & FLG_BITWISE)
3683 fatal ("ATTR_FLAG not valid inside comparison");
3684 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3685 break;
3687 /* See if an operand matches a predicate. */
3688 case MATCH_OPERAND:
3689 /* If only a mode is given, just ensure the mode matches the operand.
3690 If neither a mode nor predicate is given, error. */
3691 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3693 if (GET_MODE (exp) == VOIDmode)
3694 fatal ("null MATCH_OPERAND specified as test");
3695 else
3696 fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3697 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3699 else
3700 fprintf (outf, "%s (operands[%d], %smode)",
3701 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3702 break;
3704 /* Constant integer. */
3705 case CONST_INT:
3706 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3707 break;
3709 case MATCH_TEST:
3710 rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
3711 if (flags & FLG_BITWISE)
3712 fprintf (outf, " != 0");
3713 break;
3715 /* A random C expression. */
3716 case SYMBOL_REF:
3717 rtx_reader_ptr->fprint_c_condition (outf, XSTR (exp, 0));
3718 break;
3720 /* The address of the branch target. */
3721 case MATCH_DUP:
3722 fprintf (outf,
3723 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3724 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3725 break;
3727 case PC:
3728 /* The address of the current insn. We implement this actually as the
3729 address of the current insn for backward branches, but the last
3730 address of the next insn for forward branches, and both with
3731 adjustments that account for the worst-case possible stretching of
3732 intervening alignments between this insn and its destination. */
3733 fprintf (outf, "insn_current_reference_address (insn)");
3734 break;
3736 case CONST_STRING:
3737 fprintf (outf, "%s", XSTR (exp, 0));
3738 break;
3740 case IF_THEN_ELSE:
3741 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3742 fprintf (outf, " ? ");
3743 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3744 fprintf (outf, " : ");
3745 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3746 break;
3748 default:
3749 fatal ("bad RTX code `%s' in attribute calculation\n",
3750 GET_RTX_NAME (code));
3753 if (emit_parens)
3754 fprintf (outf, ")");
3756 return attrs_cached;
3759 /* Given an attribute value expression, return the maximum value that
3760 might be evaluated. Return INT_MAX if the value can't be
3761 calculated by this function. */
3763 static int
3764 max_attr_value (rtx exp)
3766 int current_max;
3767 int i, n;
3769 switch (GET_CODE (exp))
3771 case CONST_STRING:
3772 current_max = atoi (XSTR (exp, 0));
3773 break;
3775 case CONST_INT:
3776 current_max = INTVAL (exp);
3777 break;
3779 case PLUS:
3780 current_max = max_attr_value (XEXP (exp, 0));
3781 if (current_max != INT_MAX)
3783 n = current_max;
3784 current_max = max_attr_value (XEXP (exp, 1));
3785 if (current_max != INT_MAX)
3786 current_max += n;
3788 break;
3790 case MINUS:
3791 current_max = max_attr_value (XEXP (exp, 0));
3792 if (current_max != INT_MAX)
3794 n = current_max;
3795 current_max = min_attr_value (XEXP (exp, 1));
3796 if (current_max != INT_MAX)
3797 current_max = n - current_max;
3799 break;
3801 case MULT:
3802 current_max = max_attr_value (XEXP (exp, 0));
3803 if (current_max != INT_MAX)
3805 n = current_max;
3806 current_max = max_attr_value (XEXP (exp, 1));
3807 if (current_max != INT_MAX)
3808 current_max *= n;
3810 break;
3812 case COND:
3813 current_max = max_attr_value (XEXP (exp, 1));
3814 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3816 n = max_attr_value (XVECEXP (exp, 0, i + 1));
3817 if (n > current_max)
3818 current_max = n;
3820 break;
3822 case IF_THEN_ELSE:
3823 current_max = max_attr_value (XEXP (exp, 1));
3824 n = max_attr_value (XEXP (exp, 2));
3825 if (n > current_max)
3826 current_max = n;
3827 break;
3829 default:
3830 current_max = INT_MAX;
3831 break;
3834 return current_max;
3837 /* Given an attribute value expression, return the minimum value that
3838 might be evaluated. Return INT_MAX if the value can't be
3839 calculated by this function. Note that when this function can
3840 calculate one value inside IF_THEN_ELSE or some but not all values
3841 inside COND, then it returns the minimum among those values it can
3842 calculate. */
3844 static int
3845 min_attr_value (rtx exp)
3847 int current_min;
3848 int i, n;
3850 switch (GET_CODE (exp))
3852 case CONST_STRING:
3853 current_min = atoi (XSTR (exp, 0));
3854 break;
3856 case CONST_INT:
3857 current_min = INTVAL (exp);
3858 break;
3860 case PLUS:
3861 current_min = min_attr_value (XEXP (exp, 0));
3862 if (current_min != INT_MAX)
3864 n = current_min;
3865 current_min = min_attr_value (XEXP (exp, 1));
3866 if (current_min != INT_MAX)
3867 current_min += n;
3869 break;
3871 case MINUS:
3872 current_min = min_attr_value (XEXP (exp, 0));
3873 if (current_min != INT_MAX)
3875 n = current_min;
3876 current_min = max_attr_value (XEXP (exp, 1));
3877 if (current_min != INT_MAX)
3878 current_min = n - current_min;
3880 break;
3882 case MULT:
3883 current_min = min_attr_value (XEXP (exp, 0));
3884 if (current_min != INT_MAX)
3886 n = current_min;
3887 current_min = min_attr_value (XEXP (exp, 1));
3888 if (current_min != INT_MAX)
3889 current_min *= n;
3891 break;
3893 case COND:
3894 current_min = min_attr_value (XEXP (exp, 1));
3895 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3897 n = min_attr_value (XVECEXP (exp, 0, i + 1));
3898 if (n < current_min)
3899 current_min = n;
3901 break;
3903 case IF_THEN_ELSE:
3904 current_min = min_attr_value (XEXP (exp, 1));
3905 n = min_attr_value (XEXP (exp, 2));
3906 if (n < current_min)
3907 current_min = n;
3908 break;
3910 default:
3911 current_min = INT_MAX;
3912 break;
3915 return current_min;
3918 /* Given an attribute value expression, return the alignment of values.
3919 Return 0 if EXP is known to be zero, and 1 if the value can't be
3920 calculated by this function. */
3922 static unsigned int
3923 attr_value_alignment (rtx exp)
3925 unsigned int current_or;
3926 int i;
3928 switch (GET_CODE (exp))
3930 case CONST_STRING:
3931 current_or = atoi (XSTR (exp, 0));
3932 break;
3934 case CONST_INT:
3935 current_or = INTVAL (exp);
3936 break;
3938 case PLUS:
3939 case MINUS:
3940 current_or = attr_value_alignment (XEXP (exp, 0));
3941 current_or |= attr_value_alignment (XEXP (exp, 1));
3942 break;
3944 case MULT:
3945 current_or = attr_value_alignment (XEXP (exp, 0));
3946 current_or *= attr_value_alignment (XEXP (exp, 1));
3947 break;
3949 case COND:
3950 current_or = attr_value_alignment (XEXP (exp, 1));
3951 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3952 current_or |= attr_value_alignment (XVECEXP (exp, 0, i + 1));
3953 break;
3955 case IF_THEN_ELSE:
3956 current_or = attr_value_alignment (XEXP (exp, 1));
3957 current_or |= attr_value_alignment (XEXP (exp, 2));
3958 break;
3960 default:
3961 current_or = 1;
3962 break;
3965 return current_or & -current_or;
3968 /* Scan an attribute value, possibly a conditional, and record what actions
3969 will be required to do any conditional tests in it.
3971 Specifically, set
3972 `must_extract' if we need to extract the insn operands
3973 `must_constrain' if we must compute `which_alternative'
3974 `address_used' if an address expression was used
3975 `length_used' if an (eq_attr "length" ...) was used
3978 static void
3979 walk_attr_value (rtx exp)
3981 int i, j;
3982 const char *fmt;
3983 RTX_CODE code;
3985 if (exp == NULL)
3986 return;
3988 code = GET_CODE (exp);
3989 switch (code)
3991 case SYMBOL_REF:
3992 if (! ATTR_IND_SIMPLIFIED_P (exp))
3993 /* Since this is an arbitrary expression, it can look at anything.
3994 However, constant expressions do not depend on any particular
3995 insn. */
3996 must_extract = must_constrain = 1;
3997 return;
3999 case MATCH_OPERAND:
4000 must_extract = 1;
4001 return;
4003 case MATCH_TEST:
4004 case EQ_ATTR_ALT:
4005 must_extract = must_constrain = 1;
4006 break;
4008 case EQ_ATTR:
4009 if (XSTR (exp, 0) == alternative_name)
4010 must_extract = must_constrain = 1;
4011 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
4012 length_used = 1;
4013 return;
4015 case MATCH_DUP:
4016 must_extract = 1;
4017 address_used = 1;
4018 return;
4020 case PC:
4021 address_used = 1;
4022 return;
4024 case ATTR_FLAG:
4025 return;
4027 default:
4028 break;
4031 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4032 switch (*fmt++)
4034 case 'e':
4035 case 'u':
4036 walk_attr_value (XEXP (exp, i));
4037 break;
4039 case 'E':
4040 if (XVEC (exp, i) != NULL)
4041 for (j = 0; j < XVECLEN (exp, i); j++)
4042 walk_attr_value (XVECEXP (exp, i, j));
4043 break;
4047 /* Write out a function to obtain the attribute for a given INSN. */
4049 static void
4050 write_attr_get (FILE *outf, class attr_desc *attr)
4052 struct attr_value *av, *common_av;
4053 int i, j;
4055 /* Find the most used attribute value. Handle that as the `default' of the
4056 switch we will generate. */
4057 common_av = find_most_used (attr);
4059 /* Write out start of function, then all values with explicit `case' lines,
4060 then a `default', then the value with the most uses. */
4061 fprintf (outf, "%s\n", attr->cxx_type);
4063 /* If the attribute name starts with a star, the remainder is the name of
4064 the subroutine to use, instead of `get_attr_...'. */
4065 if (attr->name[0] == '*')
4066 fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4067 else if (attr->is_const == 0)
4068 fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name);
4069 else
4071 fprintf (outf, "get_attr_%s (void)\n", attr->name);
4072 fprintf (outf, "{\n");
4074 for (av = attr->first_value; av; av = av->next)
4075 if (av->num_insns == 1)
4076 write_attr_set (outf, attr, 2, av->value, "return", ";",
4077 true_rtx, av->first_insn->def->insn_code,
4078 av->first_insn->def->insn_index, 0);
4079 else if (av->num_insns != 0)
4080 write_attr_set (outf, attr, 2, av->value, "return", ";",
4081 true_rtx, -2, 0, 0);
4083 fprintf (outf, "}\n\n");
4084 return;
4087 fprintf (outf, "{\n");
4089 /* Find attributes that are worth caching in the conditions. */
4090 cached_attr_count = 0;
4091 attrs_seen_more_than_once = 0;
4092 for (av = attr->first_value; av; av = av->next)
4094 attrs_seen_once = 0;
4095 find_attrs_to_cache (av->value, true);
4097 /* Remove those that aren't worth caching from the array. */
4098 for (i = 0, j = 0; i < cached_attr_count; i++)
4099 if ((attrs_seen_more_than_once & (1U << i)) != 0)
4101 const char *name = cached_attrs[i];
4102 class attr_desc *cached_attr;
4103 if (i != j)
4104 cached_attrs[j] = name;
4105 cached_attr = find_attr (&name, 0);
4106 gcc_assert (cached_attr && cached_attr->is_const == 0);
4107 fprintf (outf, " %s cached_%s ATTRIBUTE_UNUSED;\n",
4108 cached_attr->cxx_type, name);
4109 j++;
4111 cached_attr_count = j;
4112 if (cached_attr_count)
4113 fprintf (outf, "\n");
4115 fprintf (outf, " switch (recog_memoized (insn))\n");
4116 fprintf (outf, " {\n");
4118 for (av = attr->first_value; av; av = av->next)
4119 if (av != common_av)
4120 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4122 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4123 fprintf (outf, " }\n}\n\n");
4124 cached_attr_count = 0;
4127 /* Given an AND tree of known true terms (because we are inside an `if' with
4128 that as the condition or are in an `else' clause) and an expression,
4129 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4130 the bulk of the work. */
4132 static rtx
4133 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4135 rtx term;
4137 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4139 if (GET_CODE (known_true) == AND)
4141 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4142 insn_code, insn_index);
4143 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4144 insn_code, insn_index);
4146 else
4148 term = known_true;
4149 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4152 return exp;
4155 /* Write out a series of tests and assignment statements to perform tests and
4156 sets of an attribute value. We are passed an indentation amount and prefix
4157 and suffix strings to write around each attribute value (e.g., "return"
4158 and ";"). */
4160 static void
4161 write_attr_set (FILE *outf, class attr_desc *attr, int indent, rtx value,
4162 const char *prefix, const char *suffix, rtx known_true,
4163 int insn_code, int insn_index, unsigned int attrs_cached)
4165 if (GET_CODE (value) == COND)
4167 /* Assume the default value will be the default of the COND unless we
4168 find an always true expression. */
4169 rtx default_val = XEXP (value, 1);
4170 rtx our_known_true = known_true;
4171 rtx newexp;
4172 int first_if = 1;
4173 int i;
4175 if (cached_attr_count)
4177 attrs_seen_once = 0;
4178 attrs_seen_more_than_once = 0;
4179 for (i = 0; i < XVECLEN (value, 0); i += 2)
4180 find_attrs_to_cache (XVECEXP (value, 0, i), false);
4181 attrs_to_cache |= attrs_seen_more_than_once;
4184 for (i = 0; i < XVECLEN (value, 0); i += 2)
4186 rtx testexp;
4187 rtx inner_true;
4189 /* Reset our_known_true after some time to not accumulate
4190 too much cruft (slowing down genattrtab). */
4191 if ((i & 31) == 0)
4192 our_known_true = known_true;
4193 testexp = eliminate_known_true (our_known_true,
4194 XVECEXP (value, 0, i),
4195 insn_code, insn_index);
4196 newexp = attr_rtx (NOT, testexp);
4197 newexp = insert_right_side (AND, our_known_true, newexp,
4198 insn_code, insn_index);
4200 /* If the test expression is always true or if the next `known_true'
4201 expression is always false, this is the last case, so break
4202 out and let this value be the `else' case. */
4203 if (testexp == true_rtx || newexp == false_rtx)
4205 default_val = XVECEXP (value, 0, i + 1);
4206 break;
4209 /* Compute the expression to pass to our recursive call as being
4210 known true. */
4211 inner_true = insert_right_side (AND, our_known_true,
4212 testexp, insn_code, insn_index);
4214 /* If this is always false, skip it. */
4215 if (inner_true == false_rtx)
4216 continue;
4218 attrs_cached_inside = attrs_cached;
4219 attrs_cached_after = attrs_cached;
4220 write_indent (outf, indent);
4221 fprintf (outf, "%sif ", first_if ? "" : "else ");
4222 first_if = 0;
4223 write_test_expr (outf, testexp, attrs_cached,
4224 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4225 attrs_cached = attrs_cached_after;
4226 fprintf (outf, "\n");
4227 write_indent (outf, indent + 2);
4228 fprintf (outf, "{\n");
4230 write_attr_set (outf, attr, indent + 4,
4231 XVECEXP (value, 0, i + 1), prefix, suffix,
4232 inner_true, insn_code, insn_index,
4233 attrs_cached_inside);
4234 write_indent (outf, indent + 2);
4235 fprintf (outf, "}\n");
4236 our_known_true = newexp;
4239 if (! first_if)
4241 write_indent (outf, indent);
4242 fprintf (outf, "else\n");
4243 write_indent (outf, indent + 2);
4244 fprintf (outf, "{\n");
4247 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4248 prefix, suffix, our_known_true, insn_code, insn_index,
4249 attrs_cached);
4251 if (! first_if)
4253 write_indent (outf, indent + 2);
4254 fprintf (outf, "}\n");
4257 else
4259 write_indent (outf, indent);
4260 fprintf (outf, "%s ", prefix);
4261 write_attr_value (outf, attr, value);
4262 fprintf (outf, "%s\n", suffix);
4266 /* Write a series of case statements for every instruction in list IE.
4267 INDENT is the amount of indentation to write before each case. */
4269 static void
4270 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4272 for (; ie != 0; ie = ie->next)
4273 if (ie->def->insn_code != -1)
4275 write_indent (outf, indent);
4276 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4277 fprintf (outf, "case %d: /* define_peephole, %s:%d */\n",
4278 ie->def->insn_code, ie->def->loc.filename,
4279 ie->def->loc.lineno);
4280 else
4281 fprintf (outf, "case %d: /* %s */\n",
4282 ie->def->insn_code, XSTR (ie->def->def, 0));
4286 /* Write out the computation for one attribute value. */
4288 static void
4289 write_attr_case (FILE *outf, class attr_desc *attr, struct attr_value *av,
4290 int write_case_lines, const char *prefix, const char *suffix,
4291 int indent, rtx known_true)
4293 if (av->num_insns == 0)
4294 return;
4296 if (av->has_asm_insn)
4298 write_indent (outf, indent);
4299 fprintf (outf, "case -1:\n");
4300 write_indent (outf, indent + 2);
4301 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4302 write_indent (outf, indent + 2);
4303 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
4304 write_indent (outf, indent + 2);
4305 fprintf (outf, " fatal_insn_not_found (insn);\n");
4306 write_indent (outf, indent + 2);
4307 fprintf (outf, "/* FALLTHRU */\n");
4310 if (write_case_lines)
4311 write_insn_cases (outf, av->first_insn, indent);
4312 else
4314 write_indent (outf, indent);
4315 fprintf (outf, "default:\n");
4318 /* See what we have to do to output this value. */
4319 must_extract = must_constrain = address_used = 0;
4320 walk_attr_value (av->value);
4322 if (must_constrain)
4324 write_indent (outf, indent + 2);
4325 fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4327 else if (must_extract)
4329 write_indent (outf, indent + 2);
4330 fprintf (outf, "extract_insn_cached (insn);\n");
4333 attrs_to_cache = 0;
4334 if (av->num_insns == 1)
4335 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4336 known_true, av->first_insn->def->insn_code,
4337 av->first_insn->def->insn_index, 0);
4338 else
4339 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4340 known_true, -2, 0, 0);
4342 if (!startswith (prefix, "return"))
4344 write_indent (outf, indent + 2);
4345 fprintf (outf, "break;\n");
4347 fprintf (outf, "\n");
4350 /* Utilities to write in various forms. */
4352 static void
4353 write_attr_valueq (FILE *outf, class attr_desc *attr, const char *s)
4355 if (attr->is_numeric)
4357 int num = atoi (s);
4359 fprintf (outf, "%d", num);
4361 if (num > 9 || num < 0)
4362 fprintf (outf, " /* %#x */", num);
4364 else
4366 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4367 fprintf (outf, "_");
4368 write_upcase (outf, s);
4372 static void
4373 write_attr_value (FILE *outf, class attr_desc *attr, rtx value)
4375 int op;
4377 switch (GET_CODE (value))
4379 case CONST_STRING:
4380 write_attr_valueq (outf, attr, XSTR (value, 0));
4381 break;
4383 case CONST_INT:
4384 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4385 break;
4387 case SYMBOL_REF:
4388 rtx_reader_ptr->fprint_c_condition (outf, XSTR (value, 0));
4389 break;
4391 case ATTR:
4393 class attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4394 fprintf (outf, "(%s) get_attr_%s (%s)", attr->cxx_type, attr2->name,
4395 (attr2->is_const ? "" : "insn"));
4397 break;
4399 case PLUS:
4400 op = '+';
4401 goto do_operator;
4402 case MINUS:
4403 op = '-';
4404 goto do_operator;
4405 case MULT:
4406 op = '*';
4407 goto do_operator;
4408 case DIV:
4409 op = '/';
4410 goto do_operator;
4411 case MOD:
4412 op = '%';
4413 goto do_operator;
4415 do_operator:
4416 fprintf (outf, "(");
4417 write_attr_value (outf, attr, XEXP (value, 0));
4418 fprintf (outf, " %c ", op);
4419 write_attr_value (outf, attr, XEXP (value, 1));
4420 fprintf (outf, ")");
4421 break;
4423 case IF_THEN_ELSE:
4424 fprintf (outf, "(");
4425 write_test_expr (outf, XEXP (value, 0), 0, 0, false);
4426 fprintf (outf, " ? ");
4427 write_attr_value (outf, attr, XEXP (value, 1));
4428 fprintf (outf, " : ");
4429 write_attr_value (outf, attr, XEXP (value, 2));
4430 fprintf (outf, ")");
4431 break;
4433 default:
4434 gcc_unreachable ();
4438 static void
4439 write_upcase (FILE *outf, const char *str)
4441 while (*str)
4443 /* The argument of TOUPPER should not have side effects. */
4444 fputc (TOUPPER (*str), outf);
4445 str++;
4449 static void
4450 write_indent (FILE *outf, int indent)
4452 for (; indent > 8; indent -= 8)
4453 fprintf (outf, "\t");
4455 for (; indent; indent--)
4456 fprintf (outf, " ");
4459 /* If the target does not have annul-true or annul-false delay slots, this
4460 function will create a dummy eligible_for function on OUTF which always
4461 returns false. KIND will be annul_true or annul_false. */
4463 static void
4464 write_dummy_eligible_delay (FILE *outf, const char *kind)
4466 /* Write function prelude. */
4468 fprintf (outf, "int\n");
4469 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4470 " int slot ATTRIBUTE_UNUSED,\n"
4471 " rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4472 " int flags ATTRIBUTE_UNUSED)\n",
4473 kind);
4474 fprintf (outf, "{\n");
4475 fprintf (outf, " return 0;\n");
4476 fprintf (outf, "}\n\n");
4479 /* Write a subroutine that is given an insn that requires a delay slot, a
4480 delay slot ordinal, and a candidate insn. It returns nonzero if the
4481 candidate can be placed in the specified delay slot of the insn.
4483 We can write as many as three subroutines. `eligible_for_delay'
4484 handles normal delay slots, `eligible_for_annul_true' indicates that
4485 the specified insn can be annulled if the branch is true, and likewise
4486 for `eligible_for_annul_false'.
4488 KIND is a string distinguishing these three cases ("delay", "annul_true",
4489 or "annul_false"). */
4491 static void
4492 write_eligible_delay (FILE *outf, const char *kind)
4494 class delay_desc *delay;
4495 int max_slots;
4496 char str[50];
4497 const char *pstr;
4498 class attr_desc *attr;
4499 struct attr_value *av, *common_av;
4500 int i;
4502 /* Compute the maximum number of delay slots required. We use the delay
4503 ordinal times this number plus one, plus the slot number as an index into
4504 the appropriate predicate to test. */
4506 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4507 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4508 max_slots = XVECLEN (delay->def, 1) / 3;
4510 /* Write function prelude. */
4512 fprintf (outf, "int\n");
4513 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4514 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4515 kind);
4516 fprintf (outf, "{\n");
4517 fprintf (outf, " rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4518 fprintf (outf, "\n");
4519 fprintf (outf, " if (num_delay_slots (delay_insn) == 0)\n");
4520 fprintf (outf, " return 0;");
4521 fprintf (outf, "\n");
4522 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
4523 fprintf (outf, "\n");
4524 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4525 converts a compound instruction into a loop. */
4526 fprintf (outf, " if (!INSN_P (candidate_insn))\n");
4527 fprintf (outf, " return 0;\n");
4528 fprintf (outf, "\n");
4530 /* If more than one delay type, find out which type the delay insn is. */
4532 if (num_delays > 1)
4534 attr = find_attr (&delay_type_str, 0);
4535 gcc_assert (attr);
4536 common_av = find_most_used (attr);
4538 fprintf (outf, " insn = delay_insn;\n");
4539 fprintf (outf, " switch (recog_memoized (insn))\n");
4540 fprintf (outf, " {\n");
4542 sprintf (str, " * %d;\n break;", max_slots);
4543 for (av = attr->first_value; av; av = av->next)
4544 if (av != common_av)
4545 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4547 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4548 fprintf (outf, " }\n\n");
4550 /* Ensure matched. Otherwise, shouldn't have been called. */
4551 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
4554 /* If just one type of delay slot, write simple switch. */
4555 if (num_delays == 1 && max_slots == 1)
4557 fprintf (outf, " insn = candidate_insn;\n");
4558 fprintf (outf, " switch (recog_memoized (insn))\n");
4559 fprintf (outf, " {\n");
4561 attr = find_attr (&delay_1_0_str, 0);
4562 gcc_assert (attr);
4563 common_av = find_most_used (attr);
4565 for (av = attr->first_value; av; av = av->next)
4566 if (av != common_av)
4567 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4569 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4570 fprintf (outf, " }\n");
4573 else
4575 /* Write a nested CASE. The first indicates which condition we need to
4576 test, and the inner CASE tests the condition. */
4577 fprintf (outf, " insn = candidate_insn;\n");
4578 fprintf (outf, " switch (slot)\n");
4579 fprintf (outf, " {\n");
4581 for (delay = delays; delay; delay = delay->next)
4582 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4584 fprintf (outf, " case %d:\n",
4585 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4586 fprintf (outf, " switch (recog_memoized (insn))\n");
4587 fprintf (outf, "\t{\n");
4589 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4590 pstr = str;
4591 attr = find_attr (&pstr, 0);
4592 gcc_assert (attr);
4593 common_av = find_most_used (attr);
4595 for (av = attr->first_value; av; av = av->next)
4596 if (av != common_av)
4597 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4599 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4600 fprintf (outf, " }\n");
4603 fprintf (outf, " default:\n");
4604 fprintf (outf, " gcc_unreachable ();\n");
4605 fprintf (outf, " }\n");
4608 fprintf (outf, "}\n\n");
4611 /* This page contains miscellaneous utility routines. */
4613 /* Given a pointer to a (char *), return a malloc'ed string containing the
4614 next comma-separated element. Advance the pointer to after the string
4615 scanned, or the end-of-string. Return NULL if at end of string. */
4617 static char *
4618 next_comma_elt (const char **pstr)
4620 const char *start;
4622 start = scan_comma_elt (pstr);
4624 if (start == NULL)
4625 return NULL;
4627 return attr_string (start, *pstr - start);
4630 /* Return a `class attr_desc' pointer for a given named attribute. If CREATE
4631 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4632 replaced by a pointer to a canonical copy of the string. */
4634 static class attr_desc *
4635 find_attr (const char **name_p, int create)
4637 class attr_desc *attr;
4638 int index;
4639 const char *name = *name_p;
4641 /* Before we resort to using `strcmp', see if the string address matches
4642 anywhere. In most cases, it should have been canonicalized to do so. */
4643 if (name == alternative_name)
4644 return NULL;
4646 index = name[0] & (MAX_ATTRS_INDEX - 1);
4647 for (attr = attrs[index]; attr; attr = attr->next)
4648 if (name == attr->name)
4649 return attr;
4651 /* Otherwise, do it the slow way. */
4652 for (attr = attrs[index]; attr; attr = attr->next)
4653 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4655 *name_p = attr->name;
4656 return attr;
4659 if (! create)
4660 return NULL;
4662 attr = oballoc (class attr_desc);
4663 attr->name = DEF_ATTR_STRING (name);
4664 attr->enum_name = nullptr;
4665 attr->cxx_type = nullptr;
4666 attr->first_value = attr->default_val = NULL;
4667 attr->is_numeric = attr->is_const = attr->is_special = 0;
4668 attr->next = attrs[index];
4669 attrs[index] = attr;
4671 *name_p = attr->name;
4673 return attr;
4676 /* Create internal attribute with the given default value. */
4678 static void
4679 make_internal_attr (const char *name, rtx value, int special)
4681 class attr_desc *attr;
4683 attr = find_attr (&name, 1);
4684 gcc_assert (!attr->default_val);
4686 attr->cxx_type = "int";
4687 attr->is_numeric = 1;
4688 attr->is_const = 0;
4689 attr->is_special = (special & ATTR_SPECIAL) != 0;
4690 attr->default_val = get_attr_value (file_location ("<internal>", 0, 0),
4691 value, attr, -2);
4694 /* Find the most used value of an attribute. */
4696 static struct attr_value *
4697 find_most_used (class attr_desc *attr)
4699 struct attr_value *av;
4700 struct attr_value *most_used;
4701 int nuses;
4703 most_used = NULL;
4704 nuses = -1;
4706 for (av = attr->first_value; av; av = av->next)
4707 if (av->num_insns > nuses)
4708 nuses = av->num_insns, most_used = av;
4710 return most_used;
4713 /* Return (attr_value "n") */
4715 static rtx
4716 make_numeric_value (int n)
4718 static rtx int_values[20];
4719 rtx exp;
4720 char *p;
4722 gcc_assert (n >= 0);
4724 if (n < 20 && int_values[n])
4725 return int_values[n];
4727 p = attr_printf (MAX_DIGITS, "%d", n);
4728 exp = attr_rtx (CONST_STRING, p);
4730 if (n < 20)
4731 int_values[n] = exp;
4733 return exp;
4736 static rtx
4737 copy_rtx_unchanging (rtx orig)
4739 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4740 return orig;
4742 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4743 return orig;
4746 /* Determine if an insn has a constant number of delay slots, i.e., the
4747 number of delay slots is not a function of the length of the insn. */
4749 static void
4750 write_const_num_delay_slots (FILE *outf)
4752 class attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4753 struct attr_value *av;
4755 if (attr)
4757 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4758 fprintf (outf, "{\n");
4759 fprintf (outf, " switch (recog_memoized (insn))\n");
4760 fprintf (outf, " {\n");
4762 for (av = attr->first_value; av; av = av->next)
4764 length_used = 0;
4765 walk_attr_value (av->value);
4766 if (length_used)
4767 write_insn_cases (outf, av->first_insn, 4);
4770 fprintf (outf, " default:\n");
4771 fprintf (outf, " return 1;\n");
4772 fprintf (outf, " }\n}\n\n");
4776 /* Synthetic attributes used by insn-automata.cc and the scheduler.
4777 These are primarily concerned with (define_insn_reservation)
4778 patterns. */
4780 struct insn_reserv
4782 struct insn_reserv *next;
4784 const char *name;
4785 int default_latency;
4786 rtx condexp;
4788 /* Sequence number of this insn. */
4789 int insn_num;
4791 /* Whether a (define_bypass) construct names this insn in its
4792 output list. */
4793 bool bypassed;
4796 static struct insn_reserv *all_insn_reservs = 0;
4797 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4798 static size_t n_insn_reservs;
4800 /* Store information from a DEFINE_INSN_RESERVATION for future
4801 attribute generation. */
4802 static void
4803 gen_insn_reserv (md_rtx_info *info)
4805 struct insn_reserv *decl = oballoc (struct insn_reserv);
4806 rtx def = info->def;
4808 class attr_desc attr = { };
4810 attr.name = DEF_ATTR_STRING (XSTR (def, 0));
4811 attr.loc = info->loc;
4813 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4814 decl->default_latency = XINT (def, 1);
4815 decl->condexp = check_attr_test (info->loc, XEXP (def, 2), &attr);
4816 decl->insn_num = n_insn_reservs;
4817 decl->bypassed = false;
4818 decl->next = 0;
4820 *last_insn_reserv_p = decl;
4821 last_insn_reserv_p = &decl->next;
4822 n_insn_reservs++;
4825 /* Store information from a DEFINE_BYPASS for future attribute
4826 generation. The only thing we care about is the list of output
4827 insns, which will later be used to tag reservation structures with
4828 a 'bypassed' bit. */
4830 struct bypass_list
4832 struct bypass_list *next;
4833 const char *pattern;
4836 static struct bypass_list *all_bypasses;
4837 static size_t n_bypasses;
4838 static size_t n_bypassed;
4840 static void
4841 gen_bypass_1 (const char *s, size_t len)
4843 struct bypass_list *b;
4845 if (len == 0)
4846 return;
4848 s = attr_string (s, len);
4849 for (b = all_bypasses; b; b = b->next)
4850 if (s == b->pattern)
4851 return; /* already got that one */
4853 b = oballoc (struct bypass_list);
4854 b->pattern = s;
4855 b->next = all_bypasses;
4856 all_bypasses = b;
4857 n_bypasses++;
4860 static void
4861 gen_bypass (md_rtx_info *info)
4863 const char *p, *base;
4865 rtx def = info->def;
4866 for (p = base = XSTR (def, 1); *p; p++)
4867 if (*p == ',')
4869 gen_bypass_1 (base, p - base);
4871 p++;
4872 while (ISSPACE (*p));
4873 base = p;
4875 gen_bypass_1 (base, p - base);
4878 /* Find and mark all of the bypassed insns. */
4879 static void
4880 process_bypasses (void)
4882 struct bypass_list *b;
4883 struct insn_reserv *r;
4885 n_bypassed = 0;
4887 /* The reservation list is likely to be much longer than the bypass
4888 list. */
4889 for (r = all_insn_reservs; r; r = r->next)
4890 for (b = all_bypasses; b; b = b->next)
4891 if (fnmatch (b->pattern, r->name, 0) == 0)
4893 n_bypassed++;
4894 r->bypassed = true;
4895 break;
4899 /* Check that attribute NAME is used in define_insn_reservation condition
4900 EXP. Return true if it is. */
4901 static bool
4902 check_tune_attr (const char *name, rtx exp)
4904 switch (GET_CODE (exp))
4906 case AND:
4907 if (check_tune_attr (name, XEXP (exp, 0)))
4908 return true;
4909 return check_tune_attr (name, XEXP (exp, 1));
4911 case IOR:
4912 return (check_tune_attr (name, XEXP (exp, 0))
4913 && check_tune_attr (name, XEXP (exp, 1)));
4915 case EQ_ATTR:
4916 return XSTR (exp, 0) == name;
4918 default:
4919 return false;
4923 /* Try to find a const attribute (usually cpu or tune) that is used
4924 in all define_insn_reservation conditions. */
4925 static class attr_desc *
4926 find_tune_attr (rtx exp)
4928 class attr_desc *attr;
4930 switch (GET_CODE (exp))
4932 case AND:
4933 case IOR:
4934 attr = find_tune_attr (XEXP (exp, 0));
4935 if (attr)
4936 return attr;
4937 return find_tune_attr (XEXP (exp, 1));
4939 case EQ_ATTR:
4940 if (XSTR (exp, 0) == alternative_name)
4941 return NULL;
4943 attr = find_attr (&XSTR (exp, 0), 0);
4944 gcc_assert (attr);
4946 if (attr->is_const && !attr->is_special)
4948 struct insn_reserv *decl;
4950 for (decl = all_insn_reservs; decl; decl = decl->next)
4951 if (! check_tune_attr (attr->name, decl->condexp))
4952 return NULL;
4953 return attr;
4955 return NULL;
4957 default:
4958 return NULL;
4962 /* Create all of the attributes that describe automaton properties.
4963 Write the DFA and latency function prototypes to the files that
4964 need to have them, and write the init_sched_attrs(). */
4966 static void
4967 make_automaton_attrs (void)
4969 int i;
4970 struct insn_reserv *decl;
4971 rtx code_exp, lats_exp, byps_exp;
4972 class attr_desc *tune_attr;
4974 if (n_insn_reservs == 0)
4975 return;
4977 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4978 if (tune_attr != NULL)
4980 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4981 struct attr_value *val;
4982 bool first = true;
4984 gcc_assert (tune_attr->is_const
4985 && !tune_attr->is_special
4986 && !tune_attr->is_numeric);
4988 /* Write the prototypes for all DFA functions. */
4989 for (val = tune_attr->first_value; val; val = val->next)
4991 if (val == tune_attr->default_val)
4992 continue;
4993 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4994 fprintf (dfa_file,
4995 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4996 XSTR (val->value, 0));
4998 fprintf (dfa_file, "\n");
5000 /* Write the prototypes for all latency functions. */
5001 for (val = tune_attr->first_value; val; val = val->next)
5003 if (val == tune_attr->default_val)
5004 continue;
5005 gcc_assert (GET_CODE (val->value) == CONST_STRING);
5006 fprintf (latency_file,
5007 "extern int insn_default_latency_%s (rtx_insn *);\n",
5008 XSTR (val->value, 0));
5010 fprintf (latency_file, "\n");
5012 /* Write the prototypes for all automaton functions. */
5013 for (val = tune_attr->first_value; val; val = val->next)
5015 if (val == tune_attr->default_val)
5016 continue;
5017 gcc_assert (GET_CODE (val->value) == CONST_STRING);
5018 fprintf (attr_file,
5019 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
5020 "extern int insn_default_latency_%s (rtx_insn *);\n",
5021 XSTR (val->value, 0), XSTR (val->value, 0));
5023 fprintf (attr_file, "\n");
5024 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
5025 fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n");
5026 fprintf (attr_file, "\n");
5027 fprintf (attr_file, "void\n");
5028 fprintf (attr_file, "init_sched_attrs (void)\n");
5029 fprintf (attr_file, "{\n");
5031 for (val = tune_attr->first_value; val; val = val->next)
5033 int j;
5034 char *name;
5035 rtx test = attr_eq (tune_attr->name, XSTR (val->value, 0));
5037 if (val == tune_attr->default_val)
5038 continue;
5039 for (decl = all_insn_reservs, i = 0;
5040 decl;
5041 decl = decl->next)
5043 rtx ctest = test;
5044 rtx condexp
5045 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
5046 if (condexp == false_rtx)
5047 continue;
5048 if (condexp == true_rtx)
5049 break;
5050 condexps[i] = condexp;
5051 condexps[i + 1] = make_numeric_value (decl->insn_num);
5052 condexps[i + 2] = make_numeric_value (decl->default_latency);
5053 i += 3;
5056 code_exp = rtx_alloc (COND);
5057 lats_exp = rtx_alloc (COND);
5059 j = i / 3 * 2;
5060 XVEC (code_exp, 0) = rtvec_alloc (j);
5061 XVEC (lats_exp, 0) = rtvec_alloc (j);
5063 if (decl)
5065 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
5066 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
5068 else
5070 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5071 XEXP (lats_exp, 1) = make_numeric_value (0);
5074 while (i > 0)
5076 i -= 3;
5077 j -= 2;
5078 XVECEXP (code_exp, 0, j) = condexps[i];
5079 XVECEXP (lats_exp, 0, j) = condexps[i];
5081 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
5082 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5085 name = XNEWVEC (char,
5086 sizeof ("*internal_dfa_insn_code_")
5087 + strlen (XSTR (val->value, 0)));
5088 strcpy (name, "*internal_dfa_insn_code_");
5089 strcat (name, XSTR (val->value, 0));
5090 make_internal_attr (name, code_exp, ATTR_NONE);
5091 strcpy (name, "*insn_default_latency_");
5092 strcat (name, XSTR (val->value, 0));
5093 make_internal_attr (name, lats_exp, ATTR_NONE);
5094 XDELETEVEC (name);
5096 if (first)
5098 fprintf (attr_file, " if (");
5099 first = false;
5101 else
5102 fprintf (attr_file, " else if (");
5103 write_test_expr (attr_file, test, 0, 0);
5104 fprintf (attr_file, ")\n");
5105 fprintf (attr_file, " {\n");
5106 fprintf (attr_file, " internal_dfa_insn_code\n");
5107 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
5108 XSTR (val->value, 0));
5109 fprintf (attr_file, " insn_default_latency\n");
5110 fprintf (attr_file, " = insn_default_latency_%s;\n",
5111 XSTR (val->value, 0));
5112 fprintf (attr_file, " }\n");
5115 fprintf (attr_file, " else\n");
5116 fprintf (attr_file, " gcc_unreachable ();\n");
5117 fprintf (attr_file, "}\n");
5118 fprintf (attr_file, "\n");
5120 XDELETEVEC (condexps);
5122 else
5124 code_exp = rtx_alloc (COND);
5125 lats_exp = rtx_alloc (COND);
5127 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5128 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5130 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5131 XEXP (lats_exp, 1) = make_numeric_value (0);
5133 for (decl = all_insn_reservs, i = 0;
5134 decl;
5135 decl = decl->next, i += 2)
5137 XVECEXP (code_exp, 0, i) = decl->condexp;
5138 XVECEXP (lats_exp, 0, i) = decl->condexp;
5140 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5141 XVECEXP (lats_exp, 0, i+1)
5142 = make_numeric_value (decl->default_latency);
5144 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5145 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
5148 if (n_bypasses == 0)
5149 byps_exp = make_numeric_value (0);
5150 else
5152 process_bypasses ();
5154 byps_exp = rtx_alloc (COND);
5155 XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2);
5156 XEXP (byps_exp, 1) = make_numeric_value (0);
5157 for (decl = all_insn_reservs, i = 0;
5158 decl;
5159 decl = decl->next)
5160 if (decl->bypassed)
5162 XVECEXP (byps_exp, 0, i) = decl->condexp;
5163 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5164 i += 2;
5168 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5171 static void
5172 write_header (FILE *outf)
5174 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5175 " from the machine description file `md'. */\n\n");
5177 fprintf (outf, "#define IN_TARGET_CODE 1\n");
5178 fprintf (outf, "#include \"config.h\"\n");
5179 fprintf (outf, "#include \"system.h\"\n");
5180 fprintf (outf, "#include \"coretypes.h\"\n");
5181 fprintf (outf, "#include \"backend.h\"\n");
5182 fprintf (outf, "#include \"predict.h\"\n");
5183 fprintf (outf, "#include \"tree.h\"\n");
5184 fprintf (outf, "#include \"rtl.h\"\n");
5185 fprintf (outf, "#include \"alias.h\"\n");
5186 fprintf (outf, "#include \"options.h\"\n");
5187 fprintf (outf, "#include \"varasm.h\"\n");
5188 fprintf (outf, "#include \"stor-layout.h\"\n");
5189 fprintf (outf, "#include \"calls.h\"\n");
5190 fprintf (outf, "#include \"insn-attr.h\"\n");
5191 fprintf (outf, "#include \"memmodel.h\"\n");
5192 fprintf (outf, "#include \"tm_p.h\"\n");
5193 fprintf (outf, "#include \"insn-config.h\"\n");
5194 fprintf (outf, "#include \"recog.h\"\n");
5195 fprintf (outf, "#include \"regs.h\"\n");
5196 fprintf (outf, "#include \"real.h\"\n");
5197 fprintf (outf, "#include \"output.h\"\n");
5198 fprintf (outf, "#include \"toplev.h\"\n");
5199 fprintf (outf, "#include \"flags.h\"\n");
5200 fprintf (outf, "#include \"emit-rtl.h\"\n");
5201 fprintf (outf, "\n");
5202 fprintf (outf, "#define operands recog_data.operand\n\n");
5205 static FILE *
5206 open_outfile (const char *file_name)
5208 FILE *outf;
5209 outf = fopen (file_name, "w");
5210 if (! outf)
5211 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5212 write_header (outf);
5213 return outf;
5216 static bool
5217 handle_arg (const char *arg)
5219 switch (arg[1])
5221 case 'A':
5222 attr_file_name = &arg[2];
5223 return true;
5224 case 'D':
5225 dfa_file_name = &arg[2];
5226 return true;
5227 case 'L':
5228 latency_file_name = &arg[2];
5229 return true;
5230 default:
5231 return false;
5236 main (int argc, const char **argv)
5238 class attr_desc *attr;
5239 class insn_def *id;
5240 int i;
5242 progname = "genattrtab";
5244 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5245 return FATAL_EXIT_CODE;
5247 attr_file = open_outfile (attr_file_name);
5248 dfa_file = open_outfile (dfa_file_name);
5249 latency_file = open_outfile (latency_file_name);
5251 obstack_init (hash_obstack);
5252 obstack_init (temp_obstack);
5254 /* Set up true and false rtx's */
5255 true_rtx = rtx_alloc (CONST_INT);
5256 XWINT (true_rtx, 0) = 1;
5257 false_rtx = rtx_alloc (CONST_INT);
5258 XWINT (false_rtx, 0) = 0;
5259 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5260 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5262 alternative_name = DEF_ATTR_STRING ("alternative");
5263 length_str = DEF_ATTR_STRING ("length");
5264 delay_type_str = DEF_ATTR_STRING ("*delay_type");
5265 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5266 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5268 /* Read the machine description. */
5270 md_rtx_info info;
5271 while (read_md_rtx (&info))
5273 switch (GET_CODE (info.def))
5275 case DEFINE_INSN:
5276 case DEFINE_PEEPHOLE:
5277 case DEFINE_ASM_ATTRIBUTES:
5278 gen_insn (&info);
5279 break;
5281 case DEFINE_ATTR:
5282 case DEFINE_ENUM_ATTR:
5283 gen_attr (&info);
5284 break;
5286 case DEFINE_DELAY:
5287 gen_delay (&info);
5288 break;
5290 case DEFINE_INSN_RESERVATION:
5291 gen_insn_reserv (&info);
5292 break;
5294 case DEFINE_BYPASS:
5295 gen_bypass (&info);
5296 break;
5298 default:
5299 break;
5301 if (GET_CODE (info.def) != DEFINE_ASM_ATTRIBUTES)
5302 insn_index_number++;
5305 if (have_error)
5306 return FATAL_EXIT_CODE;
5308 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5309 if (! got_define_asm_attributes)
5311 md_rtx_info info;
5312 info.def = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5313 XVEC (info.def, 0) = rtvec_alloc (0);
5314 info.loc = file_location ("<internal>", 0, 0);
5315 info.index = -1;
5316 gen_insn (&info);
5319 /* Expand DEFINE_DELAY information into new attribute. */
5320 expand_delays ();
5322 /* Make `insn_alternatives'. */
5323 int num_insn_codes = get_num_insn_codes ();
5324 insn_alternatives = oballocvec (alternative_mask, num_insn_codes);
5325 for (id = defs; id; id = id->next)
5326 if (id->insn_code >= 0)
5327 insn_alternatives[id->insn_code]
5328 = (((alternative_mask) 1) << id->num_alternatives) - 1;
5330 /* Make `insn_n_alternatives'. */
5331 insn_n_alternatives = oballocvec (int, num_insn_codes);
5332 for (id = defs; id; id = id->next)
5333 if (id->insn_code >= 0)
5334 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5336 /* Construct extra attributes for automata. */
5337 make_automaton_attrs ();
5339 /* Prepare to write out attribute subroutines by checking everything stored
5340 away and building the attribute cases. */
5342 check_defs ();
5344 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5345 for (attr = attrs[i]; attr; attr = attr->next)
5346 attr->default_val->value
5347 = check_attr_value (attr->loc, attr->default_val->value, attr);
5349 if (have_error)
5350 return FATAL_EXIT_CODE;
5352 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5353 for (attr = attrs[i]; attr; attr = attr->next)
5354 fill_attr (attr);
5356 /* Construct extra attributes for `length'. */
5357 make_length_attrs ();
5359 /* Perform any possible optimizations to speed up compilation. */
5360 optimize_attrs (num_insn_codes);
5362 /* Now write out all the `gen_attr_...' routines. Do these before the
5363 special routines so that they get defined before they are used. */
5365 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5366 for (attr = attrs[i]; attr; attr = attr->next)
5368 FILE *outf;
5370 if (startswith(attr->name, "*internal_dfa_insn_code"))
5371 outf = dfa_file;
5372 else if (startswith (attr->name, "*insn_default_latency"))
5373 outf = latency_file;
5374 else
5375 outf = attr_file;
5377 if (! attr->is_special && ! attr->is_const)
5378 write_attr_get (outf, attr);
5381 /* Write out delay eligibility information, if DEFINE_DELAY present.
5382 (The function to compute the number of delay slots will be written
5383 below.) */
5384 write_eligible_delay (attr_file, "delay");
5385 if (have_annul_true)
5386 write_eligible_delay (attr_file, "annul_true");
5387 else
5388 write_dummy_eligible_delay (attr_file, "annul_true");
5389 if (have_annul_false)
5390 write_eligible_delay (attr_file, "annul_false");
5391 else
5392 write_dummy_eligible_delay (attr_file, "annul_false");
5394 /* Write out constant delay slot info. */
5395 write_const_num_delay_slots (attr_file);
5397 write_length_unit_log (attr_file);
5399 if (fclose (attr_file) != 0)
5400 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5401 if (fclose (dfa_file) != 0)
5402 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5403 if (fclose (latency_file) != 0)
5404 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5406 return SUCCESS_EXIT_CODE;