* configure: Regenerated.
[official-gcc.git] / gcc / genattrtab.c
blob19732ba1fc565783d6e87ca457bd256ce6b7673c
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
34 expression).
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
47 `get_attr_length'.
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
54 used.
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
77 will be written.
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
93 (see attr_rtx). */
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
99 #if 0
100 #define strcmp_check(S1, S2) ((S1) == (S2) \
101 ? 0 \
102 : (gcc_assert (strcmp ((S1), (S2))), 1))
103 #else
104 #define strcmp_check(S1, S2) ((S1) != (S2))
105 #endif
107 #include "bconfig.h"
108 #include "system.h"
109 #include "coretypes.h"
110 #include "tm.h"
111 #include "rtl.h"
112 #include "obstack.h"
113 #include "errors.h"
114 #include "read-md.h"
115 #include "gensupport.h"
116 #include "vecprim.h"
117 #include "fnmatch.h"
119 #define DEBUG 0
121 /* Flags for make_internal_attr's `special' parameter. */
122 #define ATTR_NONE 0
123 #define ATTR_SPECIAL (1 << 0)
125 static struct obstack obstack1, obstack2;
126 static struct obstack *hash_obstack = &obstack1;
127 static struct obstack *temp_obstack = &obstack2;
129 /* enough space to reserve for printing out ints */
130 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
132 /* Define structures used to record attributes and values. */
134 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
135 encountered, we store all the relevant information into a
136 `struct insn_def'. This is done to allow attribute definitions to occur
137 anywhere in the file. */
139 struct insn_def
141 struct insn_def *next; /* Next insn in chain. */
142 rtx def; /* The DEFINE_... */
143 int insn_code; /* Instruction number. */
144 int insn_index; /* Expression number in file, for errors. */
145 int lineno; /* Line number. */
146 int num_alternatives; /* Number of alternatives. */
147 int vec_idx; /* Index of attribute vector in `def'. */
150 /* Once everything has been read in, we store in each attribute value a list
151 of insn codes that have that value. Here is the structure used for the
152 list. */
154 struct insn_ent
156 struct insn_ent *next; /* Next in chain. */
157 struct insn_def *def; /* Instruction definition. */
160 /* Each value of an attribute (either constant or computed) is assigned a
161 structure which is used as the listhead of the insns that have that
162 value. */
164 struct attr_value
166 rtx value; /* Value of attribute. */
167 struct attr_value *next; /* Next attribute value in chain. */
168 struct insn_ent *first_insn; /* First insn with this value. */
169 int num_insns; /* Number of insns with this value. */
170 int has_asm_insn; /* True if this value used for `asm' insns */
173 /* Structure for each attribute. */
175 struct attr_desc
177 char *name; /* Name of attribute. */
178 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */
179 struct 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 int lineno : 24; /* Line number. */
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 struct delay_desc
192 rtx def; /* DEFINE_DELAY expression. */
193 struct delay_desc *next; /* Next DEFINE_DELAY. */
194 int num; /* Number of DEFINE_DELAY, starting at 1. */
195 int lineno; /* Line number. */
198 struct attr_value_list
200 struct attr_value *av;
201 struct insn_ent *ie;
202 struct attr_desc *attr;
203 struct attr_value_list *next;
206 /* Listheads of above structures. */
208 /* This one is indexed by the first character of the attribute name. */
209 #define MAX_ATTRS_INDEX 256
210 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
211 static struct insn_def *defs;
212 static struct delay_desc *delays;
213 struct attr_value_list **insn_code_values;
215 /* Other variables. */
217 static int insn_code_number;
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 static int *insn_alternatives;
237 /* Used to simplify expressions. */
239 static rtx true_rtx, false_rtx;
241 /* Used to reduce calls to `strcmp' */
243 static const char *alternative_name;
244 static const char *length_str;
245 static const char *delay_type_str;
246 static const char *delay_1_0_str;
247 static const char *num_delay_slots_str;
249 /* Simplify an expression. Only call the routine if there is something to
250 simplify. */
251 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
252 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
253 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
255 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
257 /* Forward declarations of functions used before their definitions, only. */
258 static char *attr_string (const char *, int);
259 static char *attr_printf (unsigned int, const char *, ...)
260 ATTRIBUTE_PRINTF_2;
261 static rtx make_numeric_value (int);
262 static struct attr_desc *find_attr (const char **, int);
263 static rtx mk_attr_alt (int);
264 static char *next_comma_elt (const char **);
265 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
266 static rtx copy_boolean (rtx);
267 static int compares_alternatives_p (rtx);
268 static void make_internal_attr (const char *, rtx, int);
269 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
270 static void walk_attr_value (rtx);
271 static int max_attr_value (rtx, int*);
272 static int min_attr_value (rtx, int*);
273 static int or_attr_value (rtx, int*);
274 static rtx simplify_test_exp (rtx, int, int);
275 static rtx simplify_test_exp_in_temp (rtx, int, int);
276 static rtx copy_rtx_unchanging (rtx);
277 static bool attr_alt_subset_p (rtx, rtx);
278 static bool attr_alt_subset_of_compl_p (rtx, rtx);
279 static void clear_struct_flag (rtx);
280 static void write_attr_valueq (FILE *, struct attr_desc *, const char *);
281 static struct attr_value *find_most_used (struct attr_desc *);
282 static void write_attr_set (FILE *, struct attr_desc *, int, rtx,
283 const char *, const char *, rtx,
284 int, int, unsigned int);
285 static void write_attr_case (FILE *, struct attr_desc *,
286 struct attr_value *,
287 int, const char *, const char *, int, rtx);
288 static void write_attr_value (FILE *, struct attr_desc *, rtx);
289 static void write_upcase (FILE *, const char *);
290 static void write_indent (FILE *, int);
291 static rtx identity_fn (rtx);
292 static rtx zero_fn (rtx);
293 static rtx one_fn (rtx);
294 static rtx max_fn (rtx);
295 static rtx min_fn (rtx);
297 #define oballoc(T) XOBNEW (hash_obstack, T)
298 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
300 /* This gen* file is unique, in that it writes out multiple files.
302 Before GCC 4.8, insn-attrtab.c was written out containing many large
303 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
304 a parallel build, and even made it impossible to build GCC on machines
305 with relatively small RAM space (PR other/29442). Therefore, the
306 atrribute functions/tables are now written out to three separate
307 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
308 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
309 rest goes to ATTR_FILE_NAME. */
311 static const char *attr_file_name = NULL;
312 static const char *dfa_file_name = NULL;
313 static const char *latency_file_name = NULL;
315 static FILE *attr_file, *dfa_file, *latency_file;
317 /* Hash table for sharing RTL and strings. */
319 /* Each hash table slot is a bucket containing a chain of these structures.
320 Strings are given negative hash codes; RTL expressions are given positive
321 hash codes. */
323 struct attr_hash
325 struct attr_hash *next; /* Next structure in the bucket. */
326 int hashcode; /* Hash code of this rtx or string. */
327 union
329 char *str; /* The string (negative hash codes) */
330 rtx rtl; /* or the RTL recorded here. */
331 } u;
334 /* Now here is the hash table. When recording an RTL, it is added to
335 the slot whose index is the hash code mod the table size. Note
336 that the hash table is used for several kinds of RTL (see attr_rtx)
337 and for strings. While all these live in the same table, they are
338 completely independent, and the hash code is computed differently
339 for each. */
341 #define RTL_HASH_SIZE 4093
342 static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
344 /* Here is how primitive or already-shared RTL's hash
345 codes are made. */
346 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
348 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
350 static void
351 attr_hash_add_rtx (int hashcode, rtx rtl)
353 struct attr_hash *h;
355 h = XOBNEW (hash_obstack, struct attr_hash);
356 h->hashcode = hashcode;
357 h->u.rtl = rtl;
358 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
359 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
362 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
364 static void
365 attr_hash_add_string (int hashcode, char *str)
367 struct attr_hash *h;
369 h = XOBNEW (hash_obstack, struct attr_hash);
370 h->hashcode = -hashcode;
371 h->u.str = str;
372 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
373 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
376 /* Generate an RTL expression, but avoid duplicates.
377 Set the ATTR_PERMANENT_P flag for these permanent objects.
379 In some cases we cannot uniquify; then we return an ordinary
380 impermanent rtx with ATTR_PERMANENT_P clear.
382 Args are as follows:
384 rtx attr_rtx (code, [element1, ..., elementn]) */
386 static rtx
387 attr_rtx_1 (enum rtx_code code, va_list p)
389 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
390 int hashcode;
391 struct attr_hash *h;
392 struct obstack *old_obstack = rtl_obstack;
394 /* For each of several cases, search the hash table for an existing entry.
395 Use that entry if one is found; otherwise create a new RTL and add it
396 to the table. */
398 if (GET_RTX_CLASS (code) == RTX_UNARY)
400 rtx arg0 = va_arg (p, rtx);
402 /* A permanent object cannot point to impermanent ones. */
403 if (! ATTR_PERMANENT_P (arg0))
405 rt_val = rtx_alloc (code);
406 XEXP (rt_val, 0) = arg0;
407 return rt_val;
410 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
411 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
412 if (h->hashcode == hashcode
413 && GET_CODE (h->u.rtl) == code
414 && XEXP (h->u.rtl, 0) == arg0)
415 return h->u.rtl;
417 if (h == 0)
419 rtl_obstack = hash_obstack;
420 rt_val = rtx_alloc (code);
421 XEXP (rt_val, 0) = arg0;
424 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
425 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
426 || GET_RTX_CLASS (code) == RTX_COMPARE
427 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
429 rtx arg0 = va_arg (p, rtx);
430 rtx arg1 = va_arg (p, rtx);
432 /* A permanent object cannot point to impermanent ones. */
433 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
435 rt_val = rtx_alloc (code);
436 XEXP (rt_val, 0) = arg0;
437 XEXP (rt_val, 1) = arg1;
438 return rt_val;
441 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
442 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
443 if (h->hashcode == hashcode
444 && GET_CODE (h->u.rtl) == code
445 && XEXP (h->u.rtl, 0) == arg0
446 && XEXP (h->u.rtl, 1) == arg1)
447 return h->u.rtl;
449 if (h == 0)
451 rtl_obstack = hash_obstack;
452 rt_val = rtx_alloc (code);
453 XEXP (rt_val, 0) = arg0;
454 XEXP (rt_val, 1) = arg1;
457 else if (code == SYMBOL_REF
458 || (GET_RTX_LENGTH (code) == 1
459 && GET_RTX_FORMAT (code)[0] == 's'))
461 char *arg0 = va_arg (p, char *);
463 arg0 = DEF_ATTR_STRING (arg0);
465 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
466 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
467 if (h->hashcode == hashcode
468 && GET_CODE (h->u.rtl) == code
469 && XSTR (h->u.rtl, 0) == arg0)
470 return h->u.rtl;
472 if (h == 0)
474 rtl_obstack = hash_obstack;
475 rt_val = rtx_alloc (code);
476 XSTR (rt_val, 0) = arg0;
477 if (code == SYMBOL_REF)
479 X0EXP (rt_val, 1) = NULL_RTX;
480 X0EXP (rt_val, 2) = NULL_RTX;
484 else if (GET_RTX_LENGTH (code) == 2
485 && GET_RTX_FORMAT (code)[0] == 's'
486 && GET_RTX_FORMAT (code)[1] == 's')
488 char *arg0 = va_arg (p, char *);
489 char *arg1 = va_arg (p, char *);
491 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
492 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
493 if (h->hashcode == hashcode
494 && GET_CODE (h->u.rtl) == code
495 && XSTR (h->u.rtl, 0) == arg0
496 && XSTR (h->u.rtl, 1) == arg1)
497 return h->u.rtl;
499 if (h == 0)
501 rtl_obstack = hash_obstack;
502 rt_val = rtx_alloc (code);
503 XSTR (rt_val, 0) = arg0;
504 XSTR (rt_val, 1) = arg1;
507 else if (code == CONST_INT)
509 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
510 if (arg0 == 0)
511 return false_rtx;
512 else if (arg0 == 1)
513 return true_rtx;
514 else
515 goto nohash;
517 else
519 int i; /* Array indices... */
520 const char *fmt; /* Current rtx's format... */
521 nohash:
522 rt_val = rtx_alloc (code); /* Allocate the storage space. */
524 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
525 for (i = 0; i < GET_RTX_LENGTH (code); i++)
527 switch (*fmt++)
529 case '0': /* Unused field. */
530 break;
532 case 'i': /* An integer? */
533 XINT (rt_val, i) = va_arg (p, int);
534 break;
536 case 'w': /* A wide integer? */
537 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
538 break;
540 case 's': /* A string? */
541 XSTR (rt_val, i) = va_arg (p, char *);
542 break;
544 case 'e': /* An expression? */
545 case 'u': /* An insn? Same except when printing. */
546 XEXP (rt_val, i) = va_arg (p, rtx);
547 break;
549 case 'E': /* An RTX vector? */
550 XVEC (rt_val, i) = va_arg (p, rtvec);
551 break;
553 default:
554 gcc_unreachable ();
557 return rt_val;
560 rtl_obstack = old_obstack;
561 attr_hash_add_rtx (hashcode, rt_val);
562 ATTR_PERMANENT_P (rt_val) = 1;
563 return rt_val;
566 static rtx
567 attr_rtx (enum rtx_code code, ...)
569 rtx result;
570 va_list p;
572 va_start (p, code);
573 result = attr_rtx_1 (code, p);
574 va_end (p);
575 return result;
578 /* Create a new string printed with the printf line arguments into a space
579 of at most LEN bytes:
581 rtx attr_printf (len, format, [arg1, ..., argn]) */
583 static char *
584 attr_printf (unsigned int len, const char *fmt, ...)
586 char str[256];
587 va_list p;
589 va_start (p, fmt);
591 gcc_assert (len < sizeof str); /* Leave room for \0. */
593 vsprintf (str, fmt, p);
594 va_end (p);
596 return DEF_ATTR_STRING (str);
599 static rtx
600 attr_eq (const char *name, const char *value)
602 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
605 static const char *
606 attr_numeral (int n)
608 return XSTR (make_numeric_value (n), 0);
611 /* Return a permanent (possibly shared) copy of a string STR (not assumed
612 to be null terminated) with LEN bytes. */
614 static char *
615 attr_string (const char *str, int len)
617 struct attr_hash *h;
618 int hashcode;
619 int i;
620 char *new_str;
622 /* Compute the hash code. */
623 hashcode = (len + 1) * 613 + (unsigned) str[0];
624 for (i = 1; i < len; i += 2)
625 hashcode = ((hashcode * 613) + (unsigned) str[i]);
626 if (hashcode < 0)
627 hashcode = -hashcode;
629 /* Search the table for the string. */
630 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
631 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
632 && !strncmp (h->u.str, str, len))
633 return h->u.str; /* <-- return if found. */
635 /* Not found; create a permanent copy and add it to the hash table. */
636 new_str = XOBNEWVAR (hash_obstack, char, len + 1);
637 memcpy (new_str, str, len);
638 new_str[len] = '\0';
639 attr_hash_add_string (hashcode, new_str);
640 copy_md_ptr_loc (new_str, str);
642 return new_str; /* Return the new string. */
645 /* Check two rtx's for equality of contents,
646 taking advantage of the fact that if both are hashed
647 then they can't be equal unless they are the same object. */
649 static int
650 attr_equal_p (rtx x, rtx y)
652 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
653 && rtx_equal_p (x, y)));
656 /* Copy an attribute value expression,
657 descending to all depths, but not copying any
658 permanent hashed subexpressions. */
660 static rtx
661 attr_copy_rtx (rtx orig)
663 rtx copy;
664 int i, j;
665 RTX_CODE code;
666 const char *format_ptr;
668 /* No need to copy a permanent object. */
669 if (ATTR_PERMANENT_P (orig))
670 return orig;
672 code = GET_CODE (orig);
674 switch (code)
676 case REG:
677 CASE_CONST_ANY:
678 case SYMBOL_REF:
679 case MATCH_TEST:
680 case CODE_LABEL:
681 case PC:
682 case CC0:
683 return orig;
685 default:
686 break;
689 copy = rtx_alloc (code);
690 PUT_MODE (copy, GET_MODE (orig));
691 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
692 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
693 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
695 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
697 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
699 switch (*format_ptr++)
701 case 'e':
702 XEXP (copy, i) = XEXP (orig, i);
703 if (XEXP (orig, i) != NULL)
704 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
705 break;
707 case 'E':
708 case 'V':
709 XVEC (copy, i) = XVEC (orig, i);
710 if (XVEC (orig, i) != NULL)
712 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
713 for (j = 0; j < XVECLEN (copy, i); j++)
714 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
716 break;
718 case 'n':
719 case 'i':
720 XINT (copy, i) = XINT (orig, i);
721 break;
723 case 'w':
724 XWINT (copy, i) = XWINT (orig, i);
725 break;
727 case 's':
728 case 'S':
729 XSTR (copy, i) = XSTR (orig, i);
730 break;
732 default:
733 gcc_unreachable ();
736 return copy;
739 /* Given a test expression for an attribute, ensure it is validly formed.
740 IS_CONST indicates whether the expression is constant for each compiler
741 run (a constant expression may not test any particular insn).
743 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
744 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
745 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
747 Update the string address in EQ_ATTR expression to be the same used
748 in the attribute (or `alternative_name') to speed up subsequent
749 `find_attr' calls and eliminate most `strcmp' calls.
751 Return the new expression, if any. */
753 static rtx
754 check_attr_test (rtx exp, int is_const, int lineno)
756 struct attr_desc *attr;
757 struct attr_value *av;
758 const char *name_ptr, *p;
759 rtx orexp, newexp;
761 switch (GET_CODE (exp))
763 case EQ_ATTR:
764 /* Handle negation test. */
765 if (XSTR (exp, 1)[0] == '!')
766 return check_attr_test (attr_rtx (NOT,
767 attr_eq (XSTR (exp, 0),
768 &XSTR (exp, 1)[1])),
769 is_const, lineno);
771 else if (n_comma_elts (XSTR (exp, 1)) == 1)
773 attr = find_attr (&XSTR (exp, 0), 0);
774 if (attr == NULL)
776 if (! strcmp (XSTR (exp, 0), "alternative"))
777 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
778 else
779 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
782 if (is_const && ! attr->is_const)
783 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
784 XSTR (exp, 0));
786 /* Copy this just to make it permanent,
787 so expressions using it can be permanent too. */
788 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
790 /* It shouldn't be possible to simplify the value given to a
791 constant attribute, so don't expand this until it's time to
792 write the test expression. */
793 if (attr->is_const)
794 ATTR_IND_SIMPLIFIED_P (exp) = 1;
796 if (attr->is_numeric)
798 for (p = XSTR (exp, 1); *p; p++)
799 if (! ISDIGIT (*p))
800 fatal ("attribute `%s' takes only numeric values",
801 XSTR (exp, 0));
803 else
805 for (av = attr->first_value; av; av = av->next)
806 if (GET_CODE (av->value) == CONST_STRING
807 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
808 break;
810 if (av == NULL)
811 fatal ("unknown value `%s' for `%s' attribute",
812 XSTR (exp, 1), XSTR (exp, 0));
815 else
817 if (! strcmp (XSTR (exp, 0), "alternative"))
819 int set = 0;
821 name_ptr = XSTR (exp, 1);
822 while ((p = next_comma_elt (&name_ptr)) != NULL)
823 set |= 1 << atoi (p);
825 return mk_attr_alt (set);
827 else
829 /* Make an IOR tree of the possible values. */
830 orexp = false_rtx;
831 name_ptr = XSTR (exp, 1);
832 while ((p = next_comma_elt (&name_ptr)) != NULL)
834 newexp = attr_eq (XSTR (exp, 0), p);
835 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
838 return check_attr_test (orexp, is_const, lineno);
841 break;
843 case ATTR_FLAG:
844 break;
846 case CONST_INT:
847 /* Either TRUE or FALSE. */
848 if (XWINT (exp, 0))
849 return true_rtx;
850 else
851 return false_rtx;
853 case IOR:
854 case AND:
855 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
856 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
857 break;
859 case NOT:
860 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
861 break;
863 case MATCH_TEST:
864 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
865 ATTR_IND_SIMPLIFIED_P (exp) = 1;
866 break;
868 case MATCH_OPERAND:
869 if (is_const)
870 fatal ("RTL operator \"%s\" not valid in constant attribute test",
871 GET_RTX_NAME (GET_CODE (exp)));
872 /* These cases can't be simplified. */
873 ATTR_IND_SIMPLIFIED_P (exp) = 1;
874 break;
876 case LE: case LT: case GT: case GE:
877 case LEU: case LTU: case GTU: case GEU:
878 case NE: case EQ:
879 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
880 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
881 exp = attr_rtx (GET_CODE (exp),
882 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
883 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
884 /* These cases can't be simplified. */
885 ATTR_IND_SIMPLIFIED_P (exp) = 1;
886 break;
888 case SYMBOL_REF:
889 if (is_const)
891 /* These cases are valid for constant attributes, but can't be
892 simplified. */
893 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
894 ATTR_IND_SIMPLIFIED_P (exp) = 1;
895 break;
897 default:
898 fatal ("RTL operator \"%s\" not valid in attribute test",
899 GET_RTX_NAME (GET_CODE (exp)));
902 return exp;
905 /* Given an expression, ensure that it is validly formed and that all named
906 attribute values are valid for the given attribute. Issue a fatal error
907 if not. If no attribute is specified, assume a numeric attribute.
909 Return a perhaps modified replacement expression for the value. */
911 static rtx
912 check_attr_value (rtx exp, struct attr_desc *attr)
914 struct attr_value *av;
915 const char *p;
916 int i;
918 switch (GET_CODE (exp))
920 case CONST_INT:
921 if (attr && ! attr->is_numeric)
923 error_with_line (attr->lineno,
924 "CONST_INT not valid for non-numeric attribute %s",
925 attr->name);
926 break;
929 if (INTVAL (exp) < 0)
931 error_with_line (attr->lineno,
932 "negative numeric value specified for attribute %s",
933 attr->name);
934 break;
936 break;
938 case CONST_STRING:
939 if (! strcmp (XSTR (exp, 0), "*"))
940 break;
942 if (attr == 0 || attr->is_numeric)
944 p = XSTR (exp, 0);
945 for (; *p; p++)
946 if (! ISDIGIT (*p))
948 error_with_line (attr ? attr->lineno : 0,
949 "non-numeric value for numeric attribute %s",
950 attr ? attr->name : "internal");
951 break;
953 break;
956 for (av = attr->first_value; av; av = av->next)
957 if (GET_CODE (av->value) == CONST_STRING
958 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
959 break;
961 if (av == NULL)
962 error_with_line (attr->lineno,
963 "unknown value `%s' for `%s' attribute",
964 XSTR (exp, 0), attr ? attr->name : "internal");
965 break;
967 case IF_THEN_ELSE:
968 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
969 attr ? attr->is_const : 0,
970 attr ? attr->lineno : 0);
971 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
972 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
973 break;
975 case PLUS:
976 case MINUS:
977 case MULT:
978 case DIV:
979 case MOD:
980 if (attr && !attr->is_numeric)
982 error_with_line (attr->lineno,
983 "invalid operation `%s' for non-numeric"
984 " attribute value", GET_RTX_NAME (GET_CODE (exp)));
985 break;
987 /* Fall through. */
989 case IOR:
990 case AND:
991 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
992 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
993 break;
995 case FFS:
996 case CLZ:
997 case CTZ:
998 case POPCOUNT:
999 case PARITY:
1000 case BSWAP:
1001 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1002 break;
1004 case COND:
1005 if (XVECLEN (exp, 0) % 2 != 0)
1007 error_with_line (attr->lineno,
1008 "first operand of COND must have even length");
1009 break;
1012 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1014 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1015 attr ? attr->is_const : 0,
1016 attr ? attr->lineno : 0);
1017 XVECEXP (exp, 0, i + 1)
1018 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1021 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1022 break;
1024 case ATTR:
1026 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1027 if (attr2 == NULL)
1028 error_with_line (attr ? attr->lineno : 0,
1029 "unknown attribute `%s' in ATTR",
1030 XSTR (exp, 0));
1031 else if (attr && attr->is_const && ! attr2->is_const)
1032 error_with_line (attr->lineno,
1033 "non-constant attribute `%s' referenced from `%s'",
1034 XSTR (exp, 0), attr->name);
1035 else if (attr
1036 && attr->is_numeric != attr2->is_numeric)
1037 error_with_line (attr->lineno,
1038 "numeric attribute mismatch calling `%s' from `%s'",
1039 XSTR (exp, 0), attr->name);
1041 break;
1043 case SYMBOL_REF:
1044 /* A constant SYMBOL_REF is valid as a constant attribute test and
1045 is expanded later by make_canonical into a COND. In a non-constant
1046 attribute test, it is left be. */
1047 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1049 default:
1050 error_with_line (attr ? attr->lineno : 0,
1051 "invalid operation `%s' for attribute value",
1052 GET_RTX_NAME (GET_CODE (exp)));
1053 break;
1056 return exp;
1059 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1060 It becomes a COND with each test being (eq_attr "alternative" "n") */
1062 static rtx
1063 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1065 int num_alt = id->num_alternatives;
1066 rtx condexp;
1067 int i;
1069 if (XVECLEN (exp, 1) != num_alt)
1071 error_with_line (id->lineno,
1072 "bad number of entries in SET_ATTR_ALTERNATIVE");
1073 return NULL_RTX;
1076 /* Make a COND with all tests but the last. Select the last value via the
1077 default. */
1078 condexp = rtx_alloc (COND);
1079 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1081 for (i = 0; i < num_alt - 1; i++)
1083 const char *p;
1084 p = attr_numeral (i);
1086 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1087 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1090 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1092 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1095 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1096 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1098 static rtx
1099 convert_set_attr (rtx exp, struct insn_def *id)
1101 rtx newexp;
1102 const char *name_ptr;
1103 char *p;
1104 int n;
1106 /* See how many alternative specified. */
1107 n = n_comma_elts (XSTR (exp, 1));
1108 if (n == 1)
1109 return attr_rtx (SET,
1110 attr_rtx (ATTR, XSTR (exp, 0)),
1111 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1113 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1114 XSTR (newexp, 0) = XSTR (exp, 0);
1115 XVEC (newexp, 1) = rtvec_alloc (n);
1117 /* Process each comma-separated name. */
1118 name_ptr = XSTR (exp, 1);
1119 n = 0;
1120 while ((p = next_comma_elt (&name_ptr)) != NULL)
1121 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1123 return convert_set_attr_alternative (newexp, id);
1126 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1127 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1128 expressions. */
1130 static void
1131 check_defs (void)
1133 struct insn_def *id;
1134 struct attr_desc *attr;
1135 int i;
1136 rtx value;
1138 for (id = defs; id; id = id->next)
1140 if (XVEC (id->def, id->vec_idx) == NULL)
1141 continue;
1143 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1145 value = XVECEXP (id->def, id->vec_idx, i);
1146 switch (GET_CODE (value))
1148 case SET:
1149 if (GET_CODE (XEXP (value, 0)) != ATTR)
1151 error_with_line (id->lineno, "bad attribute set");
1152 value = NULL_RTX;
1154 break;
1156 case SET_ATTR_ALTERNATIVE:
1157 value = convert_set_attr_alternative (value, id);
1158 break;
1160 case SET_ATTR:
1161 value = convert_set_attr (value, id);
1162 break;
1164 default:
1165 error_with_line (id->lineno, "invalid attribute code %s",
1166 GET_RTX_NAME (GET_CODE (value)));
1167 value = NULL_RTX;
1169 if (value == NULL_RTX)
1170 continue;
1172 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1174 error_with_line (id->lineno, "unknown attribute %s",
1175 XSTR (XEXP (value, 0), 0));
1176 continue;
1179 XVECEXP (id->def, id->vec_idx, i) = value;
1180 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1185 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1186 expressions by converting them into a COND. This removes cases from this
1187 program. Also, replace an attribute value of "*" with the default attribute
1188 value. */
1190 static rtx
1191 make_canonical (struct attr_desc *attr, rtx exp)
1193 int i;
1194 rtx newexp;
1196 switch (GET_CODE (exp))
1198 case CONST_INT:
1199 exp = make_numeric_value (INTVAL (exp));
1200 break;
1202 case CONST_STRING:
1203 if (! strcmp (XSTR (exp, 0), "*"))
1205 if (attr == 0 || attr->default_val == 0)
1206 fatal ("(attr_value \"*\") used in invalid context");
1207 exp = attr->default_val->value;
1209 else
1210 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1212 break;
1214 case SYMBOL_REF:
1215 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1216 break;
1217 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1218 This makes the COND something that won't be considered an arbitrary
1219 expression by walk_attr_value. */
1220 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1221 exp = check_attr_value (exp, attr);
1222 break;
1224 case IF_THEN_ELSE:
1225 newexp = rtx_alloc (COND);
1226 XVEC (newexp, 0) = rtvec_alloc (2);
1227 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1228 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1230 XEXP (newexp, 1) = XEXP (exp, 2);
1232 exp = newexp;
1233 /* Fall through to COND case since this is now a COND. */
1235 case COND:
1237 int allsame = 1;
1238 rtx defval;
1240 /* First, check for degenerate COND. */
1241 if (XVECLEN (exp, 0) == 0)
1242 return make_canonical (attr, XEXP (exp, 1));
1243 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1245 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1247 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1248 XVECEXP (exp, 0, i + 1)
1249 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1250 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1251 allsame = 0;
1253 if (allsame)
1254 return defval;
1256 break;
1258 default:
1259 break;
1262 return exp;
1265 static rtx
1266 copy_boolean (rtx exp)
1268 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1269 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1270 copy_boolean (XEXP (exp, 1)));
1271 if (GET_CODE (exp) == MATCH_OPERAND)
1273 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1274 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1276 else if (GET_CODE (exp) == EQ_ATTR)
1278 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1279 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1282 return exp;
1285 /* Given a value and an attribute description, return a `struct attr_value *'
1286 that represents that value. This is either an existing structure, if the
1287 value has been previously encountered, or a newly-created structure.
1289 `insn_code' is the code of an insn whose attribute has the specified
1290 value (-2 if not processing an insn). We ensure that all insns for
1291 a given value have the same number of alternatives if the value checks
1292 alternatives. */
1294 static struct attr_value *
1295 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1297 struct attr_value *av;
1298 int num_alt = 0;
1300 value = make_canonical (attr, value);
1301 if (compares_alternatives_p (value))
1303 if (insn_code < 0 || insn_alternatives == NULL)
1304 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1305 else
1306 num_alt = insn_alternatives[insn_code];
1309 for (av = attr->first_value; av; av = av->next)
1310 if (rtx_equal_p (value, av->value)
1311 && (num_alt == 0 || av->first_insn == NULL
1312 || insn_alternatives[av->first_insn->def->insn_code]))
1313 return av;
1315 av = oballoc (struct attr_value);
1316 av->value = value;
1317 av->next = attr->first_value;
1318 attr->first_value = av;
1319 av->first_insn = NULL;
1320 av->num_insns = 0;
1321 av->has_asm_insn = 0;
1323 return av;
1326 /* After all DEFINE_DELAYs have been read in, create internal attributes
1327 to generate the required routines.
1329 First, we compute the number of delay slots for each insn (as a COND of
1330 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1331 delay type is specified, we compute a similar function giving the
1332 DEFINE_DELAY ordinal for each insn.
1334 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1335 tells whether a given insn can be in that delay slot.
1337 Normal attribute filling and optimization expands these to contain the
1338 information needed to handle delay slots. */
1340 static void
1341 expand_delays (void)
1343 struct delay_desc *delay;
1344 rtx condexp;
1345 rtx newexp;
1346 int i;
1347 char *p;
1349 /* First, generate data for `num_delay_slots' function. */
1351 condexp = rtx_alloc (COND);
1352 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1353 XEXP (condexp, 1) = make_numeric_value (0);
1355 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1357 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1358 XVECEXP (condexp, 0, i + 1)
1359 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1362 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1364 /* If more than one delay type, do the same for computing the delay type. */
1365 if (num_delays > 1)
1367 condexp = rtx_alloc (COND);
1368 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1369 XEXP (condexp, 1) = make_numeric_value (0);
1371 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1373 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1374 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1377 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1380 /* For each delay possibility and delay slot, compute an eligibility
1381 attribute for non-annulled insns and for each type of annulled (annul
1382 if true and annul if false). */
1383 for (delay = delays; delay; delay = delay->next)
1385 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1387 condexp = XVECEXP (delay->def, 1, i);
1388 if (condexp == 0)
1389 condexp = false_rtx;
1390 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1391 make_numeric_value (1), make_numeric_value (0));
1393 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1394 "*delay_%d_%d", delay->num, i / 3);
1395 make_internal_attr (p, newexp, ATTR_SPECIAL);
1397 if (have_annul_true)
1399 condexp = XVECEXP (delay->def, 1, i + 1);
1400 if (condexp == 0) condexp = false_rtx;
1401 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1402 make_numeric_value (1),
1403 make_numeric_value (0));
1404 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1405 "*annul_true_%d_%d", delay->num, i / 3);
1406 make_internal_attr (p, newexp, ATTR_SPECIAL);
1409 if (have_annul_false)
1411 condexp = XVECEXP (delay->def, 1, i + 2);
1412 if (condexp == 0) condexp = false_rtx;
1413 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1414 make_numeric_value (1),
1415 make_numeric_value (0));
1416 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1417 "*annul_false_%d_%d", delay->num, i / 3);
1418 make_internal_attr (p, newexp, ATTR_SPECIAL);
1424 /* Once all attributes and insns have been read and checked, we construct for
1425 each attribute value a list of all the insns that have that value for
1426 the attribute. */
1428 static void
1429 fill_attr (struct attr_desc *attr)
1431 struct attr_value *av;
1432 struct insn_ent *ie;
1433 struct insn_def *id;
1434 int i;
1435 rtx value;
1437 /* Don't fill constant attributes. The value is independent of
1438 any particular insn. */
1439 if (attr->is_const)
1440 return;
1442 for (id = defs; id; id = id->next)
1444 /* If no value is specified for this insn for this attribute, use the
1445 default. */
1446 value = NULL;
1447 if (XVEC (id->def, id->vec_idx))
1448 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1449 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1450 attr->name))
1451 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1453 if (value == NULL)
1454 av = attr->default_val;
1455 else
1456 av = get_attr_value (value, attr, id->insn_code);
1458 ie = oballoc (struct insn_ent);
1459 ie->def = id;
1460 insert_insn_ent (av, ie);
1464 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1465 test that checks relative positions of insns (uses MATCH_DUP or PC).
1466 If so, replace it with what is obtained by passing the expression to
1467 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1468 recursively on each value (including the default value). Otherwise,
1469 return the value returned by NO_ADDRESS_FN applied to EXP. */
1471 static rtx
1472 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1473 rtx (*address_fn) (rtx))
1475 int i;
1476 rtx newexp;
1478 if (GET_CODE (exp) == COND)
1480 /* See if any tests use addresses. */
1481 address_used = 0;
1482 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1483 walk_attr_value (XVECEXP (exp, 0, i));
1485 if (address_used)
1486 return (*address_fn) (exp);
1488 /* Make a new copy of this COND, replacing each element. */
1489 newexp = rtx_alloc (COND);
1490 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1491 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1493 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1494 XVECEXP (newexp, 0, i + 1)
1495 = substitute_address (XVECEXP (exp, 0, i + 1),
1496 no_address_fn, address_fn);
1499 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1500 no_address_fn, address_fn);
1502 return newexp;
1505 else if (GET_CODE (exp) == IF_THEN_ELSE)
1507 address_used = 0;
1508 walk_attr_value (XEXP (exp, 0));
1509 if (address_used)
1510 return (*address_fn) (exp);
1512 return attr_rtx (IF_THEN_ELSE,
1513 substitute_address (XEXP (exp, 0),
1514 no_address_fn, address_fn),
1515 substitute_address (XEXP (exp, 1),
1516 no_address_fn, address_fn),
1517 substitute_address (XEXP (exp, 2),
1518 no_address_fn, address_fn));
1521 return (*no_address_fn) (exp);
1524 /* Make new attributes from the `length' attribute. The following are made,
1525 each corresponding to a function called from `shorten_branches' or
1526 `get_attr_length':
1528 *insn_default_length This is the length of the insn to be returned
1529 by `get_attr_length' before `shorten_branches'
1530 has been called. In each case where the length
1531 depends on relative addresses, the largest
1532 possible is used. This routine is also used
1533 to compute the initial size of the insn.
1535 *insn_variable_length_p This returns 1 if the insn's length depends
1536 on relative addresses, zero otherwise.
1538 *insn_current_length This is only called when it is known that the
1539 insn has a variable length and returns the
1540 current length, based on relative addresses.
1543 static void
1544 make_length_attrs (void)
1546 static const char *new_names[] =
1548 "*insn_default_length",
1549 "*insn_min_length",
1550 "*insn_variable_length_p",
1551 "*insn_current_length"
1553 static rtx (*const no_address_fn[]) (rtx)
1554 = {identity_fn,identity_fn, zero_fn, zero_fn};
1555 static rtx (*const address_fn[]) (rtx)
1556 = {max_fn, min_fn, one_fn, identity_fn};
1557 size_t i;
1558 struct attr_desc *length_attr, *new_attr;
1559 struct attr_value *av, *new_av;
1560 struct insn_ent *ie, *new_ie;
1562 /* See if length attribute is defined. If so, it must be numeric. Make
1563 it special so we don't output anything for it. */
1564 length_attr = find_attr (&length_str, 0);
1565 if (length_attr == 0)
1566 return;
1568 if (! length_attr->is_numeric)
1569 fatal ("length attribute must be numeric");
1571 length_attr->is_const = 0;
1572 length_attr->is_special = 1;
1574 /* Make each new attribute, in turn. */
1575 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1577 make_internal_attr (new_names[i],
1578 substitute_address (length_attr->default_val->value,
1579 no_address_fn[i], address_fn[i]),
1580 ATTR_NONE);
1581 new_attr = find_attr (&new_names[i], 0);
1582 for (av = length_attr->first_value; av; av = av->next)
1583 for (ie = av->first_insn; ie; ie = ie->next)
1585 new_av = get_attr_value (substitute_address (av->value,
1586 no_address_fn[i],
1587 address_fn[i]),
1588 new_attr, ie->def->insn_code);
1589 new_ie = oballoc (struct insn_ent);
1590 new_ie->def = ie->def;
1591 insert_insn_ent (new_av, new_ie);
1596 /* Utility functions called from above routine. */
1598 static rtx
1599 identity_fn (rtx exp)
1601 return exp;
1604 static rtx
1605 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1607 return make_numeric_value (0);
1610 static rtx
1611 one_fn (rtx exp ATTRIBUTE_UNUSED)
1613 return make_numeric_value (1);
1616 static rtx
1617 max_fn (rtx exp)
1619 int unknown;
1620 return make_numeric_value (max_attr_value (exp, &unknown));
1623 static rtx
1624 min_fn (rtx exp)
1626 int unknown;
1627 return make_numeric_value (min_attr_value (exp, &unknown));
1630 static void
1631 write_length_unit_log (FILE *outf)
1633 struct attr_desc *length_attr = find_attr (&length_str, 0);
1634 struct attr_value *av;
1635 struct insn_ent *ie;
1636 unsigned int length_unit_log, length_or;
1637 int unknown = 0;
1639 if (length_attr == 0)
1640 return;
1641 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1642 for (av = length_attr->first_value; av; av = av->next)
1643 for (ie = av->first_insn; ie; ie = ie->next)
1644 length_or |= or_attr_value (av->value, &unknown);
1646 if (unknown)
1647 length_unit_log = 0;
1648 else
1650 length_or = ~length_or;
1651 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1652 length_unit_log++;
1654 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1657 /* Compute approximate cost of the expression. Used to decide whether
1658 expression is cheap enough for inline. */
1659 static int
1660 attr_rtx_cost (rtx x)
1662 int cost = 1;
1663 enum rtx_code code;
1664 if (!x)
1665 return 0;
1666 code = GET_CODE (x);
1667 switch (code)
1669 case MATCH_OPERAND:
1670 if (XSTR (x, 1)[0])
1671 return 10;
1672 else
1673 return 1;
1675 case EQ_ATTR_ALT:
1676 return 1;
1678 case EQ_ATTR:
1679 /* Alternatives don't result into function call. */
1680 if (!strcmp_check (XSTR (x, 0), alternative_name))
1681 return 1;
1682 else
1683 return 5;
1684 default:
1686 int i, j;
1687 const char *fmt = GET_RTX_FORMAT (code);
1688 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1690 switch (fmt[i])
1692 case 'V':
1693 case 'E':
1694 for (j = 0; j < XVECLEN (x, i); j++)
1695 cost += attr_rtx_cost (XVECEXP (x, i, j));
1696 break;
1697 case 'e':
1698 cost += attr_rtx_cost (XEXP (x, i));
1699 break;
1703 break;
1705 return cost;
1708 /* Take a COND expression and see if any of the conditions in it can be
1709 simplified. If any are known true or known false for the particular insn
1710 code, the COND can be further simplified.
1712 Also call ourselves on any COND operations that are values of this COND.
1714 We do not modify EXP; rather, we make and return a new rtx. */
1716 static rtx
1717 simplify_cond (rtx exp, int insn_code, int insn_index)
1719 int i, j;
1720 /* We store the desired contents here,
1721 then build a new expression if they don't match EXP. */
1722 rtx defval = XEXP (exp, 1);
1723 rtx new_defval = XEXP (exp, 1);
1724 int len = XVECLEN (exp, 0);
1725 rtx *tests = XNEWVEC (rtx, len);
1726 int allsame = 1;
1727 rtx ret;
1729 /* This lets us free all storage allocated below, if appropriate. */
1730 obstack_finish (rtl_obstack);
1732 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1734 /* See if default value needs simplification. */
1735 if (GET_CODE (defval) == COND)
1736 new_defval = simplify_cond (defval, insn_code, insn_index);
1738 /* Simplify the subexpressions, and see what tests we can get rid of. */
1740 for (i = 0; i < len; i += 2)
1742 rtx newtest, newval;
1744 /* Simplify this test. */
1745 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1746 tests[i] = newtest;
1748 newval = tests[i + 1];
1749 /* See if this value may need simplification. */
1750 if (GET_CODE (newval) == COND)
1751 newval = simplify_cond (newval, insn_code, insn_index);
1753 /* Look for ways to delete or combine this test. */
1754 if (newtest == true_rtx)
1756 /* If test is true, make this value the default
1757 and discard this + any following tests. */
1758 len = i;
1759 defval = tests[i + 1];
1760 new_defval = newval;
1763 else if (newtest == false_rtx)
1765 /* If test is false, discard it and its value. */
1766 for (j = i; j < len - 2; j++)
1767 tests[j] = tests[j + 2];
1768 i -= 2;
1769 len -= 2;
1772 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1774 /* If this value and the value for the prev test are the same,
1775 merge the tests. */
1777 tests[i - 2]
1778 = insert_right_side (IOR, tests[i - 2], newtest,
1779 insn_code, insn_index);
1781 /* Delete this test/value. */
1782 for (j = i; j < len - 2; j++)
1783 tests[j] = tests[j + 2];
1784 len -= 2;
1785 i -= 2;
1788 else
1789 tests[i + 1] = newval;
1792 /* If the last test in a COND has the same value
1793 as the default value, that test isn't needed. */
1795 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1796 len -= 2;
1798 /* See if we changed anything. */
1799 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1800 allsame = 0;
1801 else
1802 for (i = 0; i < len; i++)
1803 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1805 allsame = 0;
1806 break;
1809 if (len == 0)
1811 if (GET_CODE (defval) == COND)
1812 ret = simplify_cond (defval, insn_code, insn_index);
1813 else
1814 ret = defval;
1816 else if (allsame)
1817 ret = exp;
1818 else
1820 rtx newexp = rtx_alloc (COND);
1822 XVEC (newexp, 0) = rtvec_alloc (len);
1823 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1824 XEXP (newexp, 1) = new_defval;
1825 ret = newexp;
1827 free (tests);
1828 return ret;
1831 /* Remove an insn entry from an attribute value. */
1833 static void
1834 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1836 struct insn_ent *previe;
1838 if (av->first_insn == ie)
1839 av->first_insn = ie->next;
1840 else
1842 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1844 previe->next = ie->next;
1847 av->num_insns--;
1848 if (ie->def->insn_code == -1)
1849 av->has_asm_insn = 0;
1851 num_insn_ents--;
1854 /* Insert an insn entry in an attribute value list. */
1856 static void
1857 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1859 ie->next = av->first_insn;
1860 av->first_insn = ie;
1861 av->num_insns++;
1862 if (ie->def->insn_code == -1)
1863 av->has_asm_insn = 1;
1865 num_insn_ents++;
1868 /* This is a utility routine to take an expression that is a tree of either
1869 AND or IOR expressions and insert a new term. The new term will be
1870 inserted at the right side of the first node whose code does not match
1871 the root. A new node will be created with the root's code. Its left
1872 side will be the old right side and its right side will be the new
1873 term.
1875 If the `term' is itself a tree, all its leaves will be inserted. */
1877 static rtx
1878 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1880 rtx newexp;
1882 /* Avoid consing in some special cases. */
1883 if (code == AND && term == true_rtx)
1884 return exp;
1885 if (code == AND && term == false_rtx)
1886 return false_rtx;
1887 if (code == AND && exp == true_rtx)
1888 return term;
1889 if (code == AND && exp == false_rtx)
1890 return false_rtx;
1891 if (code == IOR && term == true_rtx)
1892 return true_rtx;
1893 if (code == IOR && term == false_rtx)
1894 return exp;
1895 if (code == IOR && exp == true_rtx)
1896 return true_rtx;
1897 if (code == IOR && exp == false_rtx)
1898 return term;
1899 if (attr_equal_p (exp, term))
1900 return exp;
1902 if (GET_CODE (term) == code)
1904 exp = insert_right_side (code, exp, XEXP (term, 0),
1905 insn_code, insn_index);
1906 exp = insert_right_side (code, exp, XEXP (term, 1),
1907 insn_code, insn_index);
1909 return exp;
1912 if (GET_CODE (exp) == code)
1914 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1915 term, insn_code, insn_index);
1916 if (new_rtx != XEXP (exp, 1))
1917 /* Make a copy of this expression and call recursively. */
1918 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1919 else
1920 newexp = exp;
1922 else
1924 /* Insert the new term. */
1925 newexp = attr_rtx (code, exp, term);
1928 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1931 /* If we have an expression which AND's a bunch of
1932 (not (eq_attrq "alternative" "n"))
1933 terms, we may have covered all or all but one of the possible alternatives.
1934 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1936 This routine is passed an expression and either AND or IOR. It returns a
1937 bitmask indicating which alternatives are mentioned within EXP. */
1939 static int
1940 compute_alternative_mask (rtx exp, enum rtx_code code)
1942 const char *string;
1943 if (GET_CODE (exp) == code)
1944 return compute_alternative_mask (XEXP (exp, 0), code)
1945 | compute_alternative_mask (XEXP (exp, 1), code);
1947 else if (code == AND && GET_CODE (exp) == NOT
1948 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1949 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1950 string = XSTR (XEXP (exp, 0), 1);
1952 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1953 && XSTR (exp, 0) == alternative_name)
1954 string = XSTR (exp, 1);
1956 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1958 if (code == AND && XINT (exp, 1))
1959 return XINT (exp, 0);
1961 if (code == IOR && !XINT (exp, 1))
1962 return XINT (exp, 0);
1964 return 0;
1966 else
1967 return 0;
1969 if (string[1] == 0)
1970 return 1 << (string[0] - '0');
1971 return 1 << atoi (string);
1974 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1975 attribute with the value represented by that bit. */
1977 static rtx
1978 make_alternative_compare (int mask)
1980 return mk_attr_alt (mask);
1983 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1984 of "attr" for this insn code. From that value, we can compute a test
1985 showing when the EQ_ATTR will be true. This routine performs that
1986 computation. If a test condition involves an address, we leave the EQ_ATTR
1987 intact because addresses are only valid for the `length' attribute.
1989 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1990 it refers. VALUE is the value of that attribute for the insn
1991 corresponding to INSN_CODE and INSN_INDEX. */
1993 static rtx
1994 evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
1995 int insn_code, int insn_index)
1997 rtx orexp, andexp;
1998 rtx right;
1999 rtx newexp;
2000 int i;
2002 while (GET_CODE (value) == ATTR)
2004 struct attr_value *av = NULL;
2006 attr = find_attr (&XSTR (value, 0), 0);
2008 if (insn_code_values)
2010 struct attr_value_list *iv;
2011 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2012 if (iv->attr == attr)
2014 av = iv->av;
2015 break;
2018 else
2020 struct insn_ent *ie;
2021 for (av = attr->first_value; av; av = av->next)
2022 for (ie = av->first_insn; ie; ie = ie->next)
2023 if (ie->def->insn_code == insn_code)
2024 goto got_av;
2026 if (av)
2028 got_av:
2029 value = av->value;
2033 switch (GET_CODE (value))
2035 case CONST_STRING:
2036 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
2037 newexp = true_rtx;
2038 else
2039 newexp = false_rtx;
2040 break;
2042 case SYMBOL_REF:
2044 const char *prefix;
2045 char *string, *p;
2047 gcc_assert (GET_CODE (exp) == EQ_ATTR);
2048 prefix = attr->enum_name ? attr->enum_name : attr->name;
2049 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
2050 for (p = string; *p; p++)
2051 *p = TOUPPER (*p);
2053 newexp = attr_rtx (EQ, value,
2054 attr_rtx (SYMBOL_REF,
2055 DEF_ATTR_STRING (string)));
2056 break;
2059 case COND:
2060 /* We construct an IOR of all the cases for which the
2061 requested attribute value is present. Since we start with
2062 FALSE, if it is not present, FALSE will be returned.
2064 Each case is the AND of the NOT's of the previous conditions with the
2065 current condition; in the default case the current condition is TRUE.
2067 For each possible COND value, call ourselves recursively.
2069 The extra TRUE and FALSE expressions will be eliminated by another
2070 call to the simplification routine. */
2072 orexp = false_rtx;
2073 andexp = true_rtx;
2075 for (i = 0; i < XVECLEN (value, 0); i += 2)
2077 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2078 insn_code, insn_index);
2080 right = insert_right_side (AND, andexp, this_cond,
2081 insn_code, insn_index);
2082 right = insert_right_side (AND, right,
2083 evaluate_eq_attr (exp, attr,
2084 XVECEXP (value, 0,
2085 i + 1),
2086 insn_code, insn_index),
2087 insn_code, insn_index);
2088 orexp = insert_right_side (IOR, orexp, right,
2089 insn_code, insn_index);
2091 /* Add this condition into the AND expression. */
2092 newexp = attr_rtx (NOT, this_cond);
2093 andexp = insert_right_side (AND, andexp, newexp,
2094 insn_code, insn_index);
2097 /* Handle the default case. */
2098 right = insert_right_side (AND, andexp,
2099 evaluate_eq_attr (exp, attr, XEXP (value, 1),
2100 insn_code, insn_index),
2101 insn_code, insn_index);
2102 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2103 break;
2105 default:
2106 gcc_unreachable ();
2109 /* If uses an address, must return original expression. But set the
2110 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2112 address_used = 0;
2113 walk_attr_value (newexp);
2115 if (address_used)
2117 if (! ATTR_IND_SIMPLIFIED_P (exp))
2118 return copy_rtx_unchanging (exp);
2119 return exp;
2121 else
2122 return newexp;
2125 /* This routine is called when an AND of a term with a tree of AND's is
2126 encountered. If the term or its complement is present in the tree, it
2127 can be replaced with TRUE or FALSE, respectively.
2129 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2130 be true and hence are complementary.
2132 There is one special case: If we see
2133 (and (not (eq_attr "att" "v1"))
2134 (eq_attr "att" "v2"))
2135 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2136 replace the term, not anything in the AND tree. So we pass a pointer to
2137 the term. */
2139 static rtx
2140 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2142 rtx left, right;
2143 rtx newexp;
2144 rtx temp;
2145 int left_eliminates_term, right_eliminates_term;
2147 if (GET_CODE (exp) == AND)
2149 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2150 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2151 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2153 newexp = attr_rtx (AND, left, right);
2155 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2159 else if (GET_CODE (exp) == IOR)
2161 /* For the IOR case, we do the same as above, except that we can
2162 only eliminate `term' if both sides of the IOR would do so. */
2163 temp = *pterm;
2164 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2165 left_eliminates_term = (temp == true_rtx);
2167 temp = *pterm;
2168 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2169 right_eliminates_term = (temp == true_rtx);
2171 if (left_eliminates_term && right_eliminates_term)
2172 *pterm = true_rtx;
2174 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2176 newexp = attr_rtx (IOR, left, right);
2178 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2182 /* Check for simplifications. Do some extra checking here since this
2183 routine is called so many times. */
2185 if (exp == *pterm)
2186 return true_rtx;
2188 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2189 return false_rtx;
2191 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2192 return false_rtx;
2194 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2196 if (attr_alt_subset_p (*pterm, exp))
2197 return true_rtx;
2199 if (attr_alt_subset_of_compl_p (*pterm, exp))
2200 return false_rtx;
2202 if (attr_alt_subset_p (exp, *pterm))
2203 *pterm = true_rtx;
2205 return exp;
2208 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2210 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2211 return exp;
2213 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2214 return true_rtx;
2215 else
2216 return false_rtx;
2219 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2220 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2222 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2223 return exp;
2225 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2226 return false_rtx;
2227 else
2228 return true_rtx;
2231 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2232 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2234 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2235 return exp;
2237 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2238 return false_rtx;
2239 else
2240 *pterm = true_rtx;
2243 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2245 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2246 return true_rtx;
2249 else if (GET_CODE (exp) == NOT)
2251 if (attr_equal_p (XEXP (exp, 0), *pterm))
2252 return false_rtx;
2255 else if (GET_CODE (*pterm) == NOT)
2257 if (attr_equal_p (XEXP (*pterm, 0), exp))
2258 return false_rtx;
2261 else if (attr_equal_p (exp, *pterm))
2262 return true_rtx;
2264 return exp;
2267 /* Similar to `simplify_and_tree', but for IOR trees. */
2269 static rtx
2270 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2272 rtx left, right;
2273 rtx newexp;
2274 rtx temp;
2275 int left_eliminates_term, right_eliminates_term;
2277 if (GET_CODE (exp) == IOR)
2279 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2280 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2281 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2283 newexp = attr_rtx (GET_CODE (exp), left, right);
2285 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2289 else if (GET_CODE (exp) == AND)
2291 /* For the AND case, we do the same as above, except that we can
2292 only eliminate `term' if both sides of the AND would do so. */
2293 temp = *pterm;
2294 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2295 left_eliminates_term = (temp == false_rtx);
2297 temp = *pterm;
2298 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2299 right_eliminates_term = (temp == false_rtx);
2301 if (left_eliminates_term && right_eliminates_term)
2302 *pterm = false_rtx;
2304 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2306 newexp = attr_rtx (GET_CODE (exp), left, right);
2308 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2312 if (attr_equal_p (exp, *pterm))
2313 return false_rtx;
2315 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2316 return true_rtx;
2318 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2319 return true_rtx;
2321 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2322 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2323 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2324 *pterm = false_rtx;
2326 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2327 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2328 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2329 return false_rtx;
2331 return exp;
2334 /* Simplify test expression and use temporary obstack in order to avoid
2335 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2336 and avoid unnecessary copying if possible. */
2338 static rtx
2339 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2341 rtx x;
2342 struct obstack *old;
2343 if (ATTR_IND_SIMPLIFIED_P (exp))
2344 return exp;
2345 old = rtl_obstack;
2346 rtl_obstack = temp_obstack;
2347 x = simplify_test_exp (exp, insn_code, insn_index);
2348 rtl_obstack = old;
2349 if (x == exp || rtl_obstack == temp_obstack)
2350 return x;
2351 return attr_copy_rtx (x);
2354 /* Returns true if S1 is a subset of S2. */
2356 static bool
2357 attr_alt_subset_p (rtx s1, rtx s2)
2359 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2361 case (0 << 1) | 0:
2362 return !(XINT (s1, 0) &~ XINT (s2, 0));
2364 case (0 << 1) | 1:
2365 return !(XINT (s1, 0) & XINT (s2, 0));
2367 case (1 << 1) | 0:
2368 return false;
2370 case (1 << 1) | 1:
2371 return !(XINT (s2, 0) &~ XINT (s1, 0));
2373 default:
2374 gcc_unreachable ();
2378 /* Returns true if S1 is a subset of complement of S2. */
2380 static bool
2381 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2383 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2385 case (0 << 1) | 0:
2386 return !(XINT (s1, 0) & XINT (s2, 0));
2388 case (0 << 1) | 1:
2389 return !(XINT (s1, 0) & ~XINT (s2, 0));
2391 case (1 << 1) | 0:
2392 return !(XINT (s2, 0) &~ XINT (s1, 0));
2394 case (1 << 1) | 1:
2395 return false;
2397 default:
2398 gcc_unreachable ();
2402 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2404 static rtx
2405 attr_alt_intersection (rtx s1, rtx s2)
2407 rtx result = rtx_alloc (EQ_ATTR_ALT);
2409 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2411 case (0 << 1) | 0:
2412 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2413 break;
2414 case (0 << 1) | 1:
2415 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2416 break;
2417 case (1 << 1) | 0:
2418 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2419 break;
2420 case (1 << 1) | 1:
2421 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2422 break;
2423 default:
2424 gcc_unreachable ();
2426 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2428 return result;
2431 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2433 static rtx
2434 attr_alt_union (rtx s1, rtx s2)
2436 rtx result = rtx_alloc (EQ_ATTR_ALT);
2438 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2440 case (0 << 1) | 0:
2441 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2442 break;
2443 case (0 << 1) | 1:
2444 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2445 break;
2446 case (1 << 1) | 0:
2447 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2448 break;
2449 case (1 << 1) | 1:
2450 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2451 break;
2452 default:
2453 gcc_unreachable ();
2456 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2457 return result;
2460 /* Return EQ_ATTR_ALT expression representing complement of S. */
2462 static rtx
2463 attr_alt_complement (rtx s)
2465 rtx result = rtx_alloc (EQ_ATTR_ALT);
2467 XINT (result, 0) = XINT (s, 0);
2468 XINT (result, 1) = 1 - XINT (s, 1);
2470 return result;
2473 /* Return EQ_ATTR_ALT expression representing set containing elements set
2474 in E. */
2476 static rtx
2477 mk_attr_alt (int e)
2479 rtx result = rtx_alloc (EQ_ATTR_ALT);
2481 XINT (result, 0) = e;
2482 XINT (result, 1) = 0;
2484 return result;
2487 /* Given an expression, see if it can be simplified for a particular insn
2488 code based on the values of other attributes being tested. This can
2489 eliminate nested get_attr_... calls.
2491 Note that if an endless recursion is specified in the patterns, the
2492 optimization will loop. However, it will do so in precisely the cases where
2493 an infinite recursion loop could occur during compilation. It's better that
2494 it occurs here! */
2496 static rtx
2497 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2499 rtx left, right;
2500 struct attr_desc *attr;
2501 struct attr_value *av;
2502 struct insn_ent *ie;
2503 struct attr_value_list *iv;
2504 int i;
2505 rtx newexp = exp;
2506 bool left_alt, right_alt;
2508 /* Don't re-simplify something we already simplified. */
2509 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2510 return exp;
2512 switch (GET_CODE (exp))
2514 case AND:
2515 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2516 if (left == false_rtx)
2517 return false_rtx;
2518 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2519 if (right == false_rtx)
2520 return false_rtx;
2522 if (GET_CODE (left) == EQ_ATTR_ALT
2523 && GET_CODE (right) == EQ_ATTR_ALT)
2525 exp = attr_alt_intersection (left, right);
2526 return simplify_test_exp (exp, insn_code, insn_index);
2529 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2530 present on both sides, apply the distributive law since this will
2531 yield simplifications. */
2532 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2533 && compute_alternative_mask (left, IOR)
2534 && compute_alternative_mask (right, IOR))
2536 if (GET_CODE (left) == IOR)
2538 rtx tem = left;
2539 left = right;
2540 right = tem;
2543 newexp = attr_rtx (IOR,
2544 attr_rtx (AND, left, XEXP (right, 0)),
2545 attr_rtx (AND, left, XEXP (right, 1)));
2547 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2550 /* Try with the term on both sides. */
2551 right = simplify_and_tree (right, &left, insn_code, insn_index);
2552 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2553 left = simplify_and_tree (left, &right, insn_code, insn_index);
2555 if (left == false_rtx || right == false_rtx)
2556 return false_rtx;
2557 else if (left == true_rtx)
2559 return right;
2561 else if (right == true_rtx)
2563 return left;
2565 /* See if all or all but one of the insn's alternatives are specified
2566 in this tree. Optimize if so. */
2568 if (GET_CODE (left) == NOT)
2569 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2570 && XSTR (XEXP (left, 0), 0) == alternative_name);
2571 else
2572 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2573 && XINT (left, 1));
2575 if (GET_CODE (right) == NOT)
2576 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2577 && XSTR (XEXP (right, 0), 0) == alternative_name);
2578 else
2579 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2580 && XINT (right, 1));
2582 if (insn_code >= 0
2583 && (GET_CODE (left) == AND
2584 || left_alt
2585 || GET_CODE (right) == AND
2586 || right_alt))
2588 i = compute_alternative_mask (exp, AND);
2589 if (i & ~insn_alternatives[insn_code])
2590 fatal ("invalid alternative specified for pattern number %d",
2591 insn_index);
2593 /* If all alternatives are excluded, this is false. */
2594 i ^= insn_alternatives[insn_code];
2595 if (i == 0)
2596 return false_rtx;
2597 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2599 /* If just one excluded, AND a comparison with that one to the
2600 front of the tree. The others will be eliminated by
2601 optimization. We do not want to do this if the insn has one
2602 alternative and we have tested none of them! */
2603 left = make_alternative_compare (i);
2604 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2605 newexp = attr_rtx (AND, left, right);
2607 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2611 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2613 newexp = attr_rtx (AND, left, right);
2614 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2616 break;
2618 case IOR:
2619 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2620 if (left == true_rtx)
2621 return true_rtx;
2622 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2623 if (right == true_rtx)
2624 return true_rtx;
2626 if (GET_CODE (left) == EQ_ATTR_ALT
2627 && GET_CODE (right) == EQ_ATTR_ALT)
2629 exp = attr_alt_union (left, right);
2630 return simplify_test_exp (exp, insn_code, insn_index);
2633 right = simplify_or_tree (right, &left, insn_code, insn_index);
2634 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2635 left = simplify_or_tree (left, &right, insn_code, insn_index);
2637 if (right == true_rtx || left == true_rtx)
2638 return true_rtx;
2639 else if (left == false_rtx)
2641 return right;
2643 else if (right == false_rtx)
2645 return left;
2648 /* Test for simple cases where the distributive law is useful. I.e.,
2649 convert (ior (and (x) (y))
2650 (and (x) (z)))
2651 to (and (x)
2652 (ior (y) (z)))
2655 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2656 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2658 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2660 left = XEXP (left, 0);
2661 right = newexp;
2662 newexp = attr_rtx (AND, left, right);
2663 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2666 /* Similarly,
2667 convert (ior (and (y) (x))
2668 (and (z) (x)))
2669 to (and (ior (y) (z))
2670 (x))
2671 Note that we want the common term to stay at the end.
2674 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2675 && attr_equal_p (XEXP (left, 1), XEXP (right, 1)))
2677 newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0));
2679 left = newexp;
2680 right = XEXP (right, 1);
2681 newexp = attr_rtx (AND, left, right);
2682 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2685 /* See if all or all but one of the insn's alternatives are specified
2686 in this tree. Optimize if so. */
2688 else if (insn_code >= 0
2689 && (GET_CODE (left) == IOR
2690 || (GET_CODE (left) == EQ_ATTR_ALT
2691 && !XINT (left, 1))
2692 || (GET_CODE (left) == EQ_ATTR
2693 && XSTR (left, 0) == alternative_name)
2694 || GET_CODE (right) == IOR
2695 || (GET_CODE (right) == EQ_ATTR_ALT
2696 && !XINT (right, 1))
2697 || (GET_CODE (right) == EQ_ATTR
2698 && XSTR (right, 0) == alternative_name)))
2700 i = compute_alternative_mask (exp, IOR);
2701 if (i & ~insn_alternatives[insn_code])
2702 fatal ("invalid alternative specified for pattern number %d",
2703 insn_index);
2705 /* If all alternatives are included, this is true. */
2706 i ^= insn_alternatives[insn_code];
2707 if (i == 0)
2708 return true_rtx;
2709 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2711 /* If just one excluded, IOR a comparison with that one to the
2712 front of the tree. The others will be eliminated by
2713 optimization. We do not want to do this if the insn has one
2714 alternative and we have tested none of them! */
2715 left = make_alternative_compare (i);
2716 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2717 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2719 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2723 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2725 newexp = attr_rtx (IOR, left, right);
2726 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2728 break;
2730 case NOT:
2731 if (GET_CODE (XEXP (exp, 0)) == NOT)
2733 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2734 insn_code, insn_index);
2735 return left;
2738 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2739 if (GET_CODE (left) == NOT)
2740 return XEXP (left, 0);
2742 if (left == false_rtx)
2743 return true_rtx;
2744 if (left == true_rtx)
2745 return false_rtx;
2747 if (GET_CODE (left) == EQ_ATTR_ALT)
2749 exp = attr_alt_complement (left);
2750 return simplify_test_exp (exp, insn_code, insn_index);
2753 /* Try to apply De`Morgan's laws. */
2754 if (GET_CODE (left) == IOR)
2756 newexp = attr_rtx (AND,
2757 attr_rtx (NOT, XEXP (left, 0)),
2758 attr_rtx (NOT, XEXP (left, 1)));
2760 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2762 else if (GET_CODE (left) == AND)
2764 newexp = attr_rtx (IOR,
2765 attr_rtx (NOT, XEXP (left, 0)),
2766 attr_rtx (NOT, XEXP (left, 1)));
2768 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2770 else if (left != XEXP (exp, 0))
2772 newexp = attr_rtx (NOT, left);
2774 break;
2776 case EQ_ATTR_ALT:
2777 if (!XINT (exp, 0))
2778 return XINT (exp, 1) ? true_rtx : false_rtx;
2779 break;
2781 case EQ_ATTR:
2782 if (XSTR (exp, 0) == alternative_name)
2784 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2785 break;
2788 /* Look at the value for this insn code in the specified attribute.
2789 We normally can replace this comparison with the condition that
2790 would give this insn the values being tested for. */
2791 if (insn_code >= 0
2792 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2794 rtx x;
2796 av = NULL;
2797 if (insn_code_values)
2799 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2800 if (iv->attr == attr)
2802 av = iv->av;
2803 break;
2806 else
2808 for (av = attr->first_value; av; av = av->next)
2809 for (ie = av->first_insn; ie; ie = ie->next)
2810 if (ie->def->insn_code == insn_code)
2811 goto got_av;
2814 if (av)
2816 got_av:
2817 x = evaluate_eq_attr (exp, attr, av->value,
2818 insn_code, insn_index);
2819 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2820 if (attr_rtx_cost(x) < 7)
2821 return x;
2824 break;
2826 default:
2827 break;
2830 /* We have already simplified this expression. Simplifying it again
2831 won't buy anything unless we weren't given a valid insn code
2832 to process (i.e., we are canonicalizing something.). */
2833 if (insn_code != -2
2834 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2835 return copy_rtx_unchanging (newexp);
2837 return newexp;
2840 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2841 otherwise return 0. */
2843 static int
2844 tests_attr_p (rtx p, struct attr_desc *attr)
2846 const char *fmt;
2847 int i, ie, j, je;
2849 if (GET_CODE (p) == EQ_ATTR)
2851 if (XSTR (p, 0) != attr->name)
2852 return 0;
2853 return 1;
2856 fmt = GET_RTX_FORMAT (GET_CODE (p));
2857 ie = GET_RTX_LENGTH (GET_CODE (p));
2858 for (i = 0; i < ie; i++)
2860 switch (*fmt++)
2862 case 'e':
2863 if (tests_attr_p (XEXP (p, i), attr))
2864 return 1;
2865 break;
2867 case 'E':
2868 je = XVECLEN (p, i);
2869 for (j = 0; j < je; ++j)
2870 if (tests_attr_p (XVECEXP (p, i, j), attr))
2871 return 1;
2872 break;
2876 return 0;
2879 /* Calculate a topological sorting of all attributes so that
2880 all attributes only depend on attributes in front of it.
2881 Place the result in *RET (which is a pointer to an array of
2882 attr_desc pointers), and return the size of that array. */
2884 static int
2885 get_attr_order (struct attr_desc ***ret)
2887 int i, j;
2888 int num = 0;
2889 struct attr_desc *attr;
2890 struct attr_desc **all, **sorted;
2891 char *handled;
2892 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2893 for (attr = attrs[i]; attr; attr = attr->next)
2894 num++;
2895 all = XNEWVEC (struct attr_desc *, num);
2896 sorted = XNEWVEC (struct attr_desc *, num);
2897 handled = XCNEWVEC (char, num);
2898 num = 0;
2899 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2900 for (attr = attrs[i]; attr; attr = attr->next)
2901 all[num++] = attr;
2903 j = 0;
2904 for (i = 0; i < num; i++)
2905 if (all[i]->is_const)
2906 handled[i] = 1, sorted[j++] = all[i];
2908 /* We have only few attributes hence we can live with the inner
2909 loop being O(n^2), unlike the normal fast variants of topological
2910 sorting. */
2911 while (j < num)
2913 for (i = 0; i < num; i++)
2914 if (!handled[i])
2916 /* Let's see if I depends on anything interesting. */
2917 int k;
2918 for (k = 0; k < num; k++)
2919 if (!handled[k])
2921 struct attr_value *av;
2922 for (av = all[i]->first_value; av; av = av->next)
2923 if (av->num_insns != 0)
2924 if (tests_attr_p (av->value, all[k]))
2925 break;
2927 if (av)
2928 /* Something in I depends on K. */
2929 break;
2931 if (k == num)
2933 /* Nothing in I depended on anything intersting, so
2934 it's done. */
2935 handled[i] = 1;
2936 sorted[j++] = all[i];
2941 if (DEBUG)
2942 for (j = 0; j < num; j++)
2944 struct attr_desc *attr2;
2945 struct attr_value *av;
2947 attr = sorted[j];
2948 fprintf (stderr, "%s depends on: ", attr->name);
2949 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
2950 for (attr2 = attrs[i]; attr2; attr2 = attr2->next)
2951 if (!attr2->is_const)
2952 for (av = attr->first_value; av; av = av->next)
2953 if (av->num_insns != 0)
2954 if (tests_attr_p (av->value, attr2))
2956 fprintf (stderr, "%s, ", attr2->name);
2957 break;
2959 fprintf (stderr, "\n");
2962 free (all);
2963 *ret = sorted;
2964 return num;
2967 /* Optimize the attribute lists by seeing if we can determine conditional
2968 values from the known values of other attributes. This will save subroutine
2969 calls during the compilation. */
2971 static void
2972 optimize_attrs (void)
2974 struct attr_desc *attr;
2975 struct attr_value *av;
2976 struct insn_ent *ie;
2977 rtx newexp;
2978 int i;
2979 struct attr_value_list *ivbuf;
2980 struct attr_value_list *iv;
2981 struct attr_desc **topsort;
2982 int topnum;
2984 /* For each insn code, make a list of all the insn_ent's for it,
2985 for all values for all attributes. */
2987 if (num_insn_ents == 0)
2988 return;
2990 /* Make 2 extra elements, for "code" values -2 and -1. */
2991 insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
2993 /* Offset the table address so we can index by -2 or -1. */
2994 insn_code_values += 2;
2996 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2998 /* Create the chain of insn*attr values such that we see dependend
2999 attributes after their dependencies. As we use a stack via the
3000 next pointers start from the end of the topological order. */
3001 topnum = get_attr_order (&topsort);
3002 for (i = topnum - 1; i >= 0; i--)
3003 for (av = topsort[i]->first_value; av; av = av->next)
3004 for (ie = av->first_insn; ie; ie = ie->next)
3006 iv->attr = topsort[i];
3007 iv->av = av;
3008 iv->ie = ie;
3009 iv->next = insn_code_values[ie->def->insn_code];
3010 insn_code_values[ie->def->insn_code] = iv;
3011 iv++;
3013 free (topsort);
3015 /* Sanity check on num_insn_ents. */
3016 gcc_assert (iv == ivbuf + num_insn_ents);
3018 /* Process one insn code at a time. */
3019 for (i = -2; i < insn_code_number; i++)
3021 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3022 We use it to mean "already simplified for this insn". */
3023 for (iv = insn_code_values[i]; iv; iv = iv->next)
3024 clear_struct_flag (iv->av->value);
3026 for (iv = insn_code_values[i]; iv; iv = iv->next)
3028 struct obstack *old = rtl_obstack;
3030 attr = iv->attr;
3031 av = iv->av;
3032 ie = iv->ie;
3033 if (GET_CODE (av->value) != COND)
3034 continue;
3036 rtl_obstack = temp_obstack;
3037 newexp = av->value;
3038 while (GET_CODE (newexp) == COND)
3040 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
3041 ie->def->insn_index);
3042 if (newexp2 == newexp)
3043 break;
3044 newexp = newexp2;
3047 rtl_obstack = old;
3048 /* If we created a new value for this instruction, and it's
3049 cheaper than the old value, and overall cheap, use that
3050 one as specific value for the current instruction.
3051 The last test is to avoid exploding the get_attr_ function
3052 sizes for no much gain. */
3053 if (newexp != av->value
3054 && attr_rtx_cost (newexp) < attr_rtx_cost (av->value)
3055 && attr_rtx_cost (newexp) < 26
3058 newexp = attr_copy_rtx (newexp);
3059 remove_insn_ent (av, ie);
3060 av = get_attr_value (newexp, attr, ie->def->insn_code);
3061 iv->av = av;
3062 insert_insn_ent (av, ie);
3067 free (ivbuf);
3068 free (insn_code_values - 2);
3069 insn_code_values = NULL;
3072 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3074 static void
3075 clear_struct_flag (rtx x)
3077 int i;
3078 int j;
3079 enum rtx_code code;
3080 const char *fmt;
3082 ATTR_CURR_SIMPLIFIED_P (x) = 0;
3083 if (ATTR_IND_SIMPLIFIED_P (x))
3084 return;
3086 code = GET_CODE (x);
3088 switch (code)
3090 case REG:
3091 CASE_CONST_ANY:
3092 case MATCH_TEST:
3093 case SYMBOL_REF:
3094 case CODE_LABEL:
3095 case PC:
3096 case CC0:
3097 case EQ_ATTR:
3098 case ATTR_FLAG:
3099 return;
3101 default:
3102 break;
3105 /* Compare the elements. If any pair of corresponding elements
3106 fail to match, return 0 for the whole things. */
3108 fmt = GET_RTX_FORMAT (code);
3109 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3111 switch (fmt[i])
3113 case 'V':
3114 case 'E':
3115 for (j = 0; j < XVECLEN (x, i); j++)
3116 clear_struct_flag (XVECEXP (x, i, j));
3117 break;
3119 case 'e':
3120 clear_struct_flag (XEXP (x, i));
3121 break;
3126 /* Add attribute value NAME to the beginning of ATTR's list. */
3128 static void
3129 add_attr_value (struct attr_desc *attr, const char *name)
3131 struct attr_value *av;
3133 av = oballoc (struct attr_value);
3134 av->value = attr_rtx (CONST_STRING, name);
3135 av->next = attr->first_value;
3136 attr->first_value = av;
3137 av->first_insn = NULL;
3138 av->num_insns = 0;
3139 av->has_asm_insn = 0;
3142 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3144 static void
3145 gen_attr (rtx exp, int lineno)
3147 struct enum_type *et;
3148 struct enum_value *ev;
3149 struct attr_desc *attr;
3150 const char *name_ptr;
3151 char *p;
3153 /* Make a new attribute structure. Check for duplicate by looking at
3154 attr->default_val, since it is initialized by this routine. */
3155 attr = find_attr (&XSTR (exp, 0), 1);
3156 if (attr->default_val)
3158 error_with_line (lineno, "duplicate definition for attribute %s",
3159 attr->name);
3160 message_with_line (attr->lineno, "previous definition");
3161 return;
3163 attr->lineno = lineno;
3165 if (GET_CODE (exp) == DEFINE_ENUM_ATTR)
3167 attr->enum_name = XSTR (exp, 1);
3168 et = lookup_enum_type (XSTR (exp, 1));
3169 if (!et || !et->md_p)
3170 error_with_line (lineno, "No define_enum called `%s' defined",
3171 attr->name);
3172 if (et)
3173 for (ev = et->values; ev; ev = ev->next)
3174 add_attr_value (attr, ev->name);
3176 else if (*XSTR (exp, 1) == '\0')
3177 attr->is_numeric = 1;
3178 else
3180 name_ptr = XSTR (exp, 1);
3181 while ((p = next_comma_elt (&name_ptr)) != NULL)
3182 add_attr_value (attr, p);
3185 if (GET_CODE (XEXP (exp, 2)) == CONST)
3187 attr->is_const = 1;
3188 if (attr->is_numeric)
3189 error_with_line (lineno,
3190 "constant attributes may not take numeric values");
3192 /* Get rid of the CONST node. It is allowed only at top-level. */
3193 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3196 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3197 error_with_line (lineno, "`length' attribute must take numeric values");
3199 /* Set up the default value. */
3200 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3201 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3204 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3205 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3206 number of alternatives as this should be checked elsewhere. */
3208 static int
3209 count_alternatives (rtx exp)
3211 int i, j, n;
3212 const char *fmt;
3214 if (GET_CODE (exp) == MATCH_OPERAND)
3215 return n_comma_elts (XSTR (exp, 2));
3217 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3218 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3219 switch (*fmt++)
3221 case 'e':
3222 case 'u':
3223 n = count_alternatives (XEXP (exp, i));
3224 if (n)
3225 return n;
3226 break;
3228 case 'E':
3229 case 'V':
3230 if (XVEC (exp, i) != NULL)
3231 for (j = 0; j < XVECLEN (exp, i); j++)
3233 n = count_alternatives (XVECEXP (exp, i, j));
3234 if (n)
3235 return n;
3239 return 0;
3242 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3243 `alternative' attribute. */
3245 static int
3246 compares_alternatives_p (rtx exp)
3248 int i, j;
3249 const char *fmt;
3251 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3252 return 1;
3254 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3255 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3256 switch (*fmt++)
3258 case 'e':
3259 case 'u':
3260 if (compares_alternatives_p (XEXP (exp, i)))
3261 return 1;
3262 break;
3264 case 'E':
3265 for (j = 0; j < XVECLEN (exp, i); j++)
3266 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3267 return 1;
3268 break;
3271 return 0;
3274 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3276 static void
3277 gen_insn (rtx exp, int lineno)
3279 struct insn_def *id;
3281 id = oballoc (struct insn_def);
3282 id->next = defs;
3283 defs = id;
3284 id->def = exp;
3285 id->lineno = lineno;
3287 switch (GET_CODE (exp))
3289 case DEFINE_INSN:
3290 id->insn_code = insn_code_number;
3291 id->insn_index = insn_index_number;
3292 id->num_alternatives = count_alternatives (exp);
3293 if (id->num_alternatives == 0)
3294 id->num_alternatives = 1;
3295 id->vec_idx = 4;
3296 break;
3298 case DEFINE_PEEPHOLE:
3299 id->insn_code = insn_code_number;
3300 id->insn_index = insn_index_number;
3301 id->num_alternatives = count_alternatives (exp);
3302 if (id->num_alternatives == 0)
3303 id->num_alternatives = 1;
3304 id->vec_idx = 3;
3305 break;
3307 case DEFINE_ASM_ATTRIBUTES:
3308 id->insn_code = -1;
3309 id->insn_index = -1;
3310 id->num_alternatives = 1;
3311 id->vec_idx = 0;
3312 got_define_asm_attributes = 1;
3313 break;
3315 default:
3316 gcc_unreachable ();
3320 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3321 true or annul false is specified, and make a `struct delay_desc'. */
3323 static void
3324 gen_delay (rtx def, int lineno)
3326 struct delay_desc *delay;
3327 int i;
3329 if (XVECLEN (def, 1) % 3 != 0)
3331 error_with_line (lineno,
3332 "number of elements in DEFINE_DELAY must"
3333 " be multiple of three");
3334 return;
3337 for (i = 0; i < XVECLEN (def, 1); i += 3)
3339 if (XVECEXP (def, 1, i + 1))
3340 have_annul_true = 1;
3341 if (XVECEXP (def, 1, i + 2))
3342 have_annul_false = 1;
3345 delay = oballoc (struct delay_desc);
3346 delay->def = def;
3347 delay->num = ++num_delays;
3348 delay->next = delays;
3349 delay->lineno = lineno;
3350 delays = delay;
3353 /* Names of attributes that could be possibly cached. */
3354 static const char *cached_attrs[32];
3355 /* Number of such attributes. */
3356 static int cached_attr_count;
3357 /* Bitmasks of possibly cached attributes. */
3358 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3359 static unsigned int attrs_to_cache;
3360 static unsigned int attrs_cached_inside, attrs_cached_after;
3362 /* Finds non-const attributes that could be possibly cached.
3363 When create is TRUE, fills in cached_attrs array.
3364 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3365 bitmasks. */
3367 static void
3368 find_attrs_to_cache (rtx exp, bool create)
3370 int i;
3371 const char *name;
3372 struct attr_desc *attr;
3374 if (exp == NULL)
3375 return;
3377 switch (GET_CODE (exp))
3379 case NOT:
3380 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3381 find_attrs_to_cache (XEXP (exp, 0), create);
3382 return;
3384 case EQ_ATTR:
3385 name = XSTR (exp, 0);
3386 if (name == alternative_name)
3387 return;
3388 for (i = 0; i < cached_attr_count; i++)
3389 if (name == cached_attrs[i])
3391 if ((attrs_seen_once & (1U << i)) != 0)
3392 attrs_seen_more_than_once |= (1U << i);
3393 else
3394 attrs_seen_once |= (1U << i);
3395 return;
3397 if (!create)
3398 return;
3399 attr = find_attr (&name, 0);
3400 gcc_assert (attr);
3401 if (attr->is_const)
3402 return;
3403 if (cached_attr_count == 32)
3404 return;
3405 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3406 attrs_seen_once |= (1U << cached_attr_count);
3407 cached_attr_count++;
3408 return;
3410 case AND:
3411 case IOR:
3412 find_attrs_to_cache (XEXP (exp, 0), create);
3413 find_attrs_to_cache (XEXP (exp, 1), create);
3414 return;
3416 case COND:
3417 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3418 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3419 return;
3421 default:
3422 return;
3426 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3427 We use AND and IOR both for logical and bit-wise operations, so
3428 interpret them as logical unless they are inside a comparison expression. */
3430 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3431 #define FLG_BITWISE 1
3432 /* Set if cached attribute will be known initialized in else block after
3433 this condition. This is true for LHS of toplevel && and || and
3434 even for RHS of ||, but not for RHS of &&. */
3435 #define FLG_AFTER 2
3436 /* Set if cached attribute will be known initialized in then block after
3437 this condition. This is true for LHS of toplevel && and || and
3438 even for RHS of &&, but not for RHS of ||. */
3439 #define FLG_INSIDE 4
3440 /* Cleared when an operand of &&. */
3441 #define FLG_OUTSIDE_AND 8
3443 static unsigned int
3444 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags)
3446 int comparison_operator = 0;
3447 RTX_CODE code;
3448 struct attr_desc *attr;
3450 /* In order not to worry about operator precedence, surround our part of
3451 the expression with parentheses. */
3453 fprintf (outf, "(");
3454 code = GET_CODE (exp);
3455 switch (code)
3457 /* Binary operators. */
3458 case GEU: case GTU:
3459 case LEU: case LTU:
3460 fprintf (outf, "(unsigned) ");
3461 /* Fall through. */
3463 case EQ: case NE:
3464 case GE: case GT:
3465 case LE: case LT:
3466 comparison_operator = FLG_BITWISE;
3468 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3469 case AND: case IOR: case XOR:
3470 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3471 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3473 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3474 write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3475 flags | comparison_operator);
3477 else
3479 if (code == AND)
3480 flags &= ~FLG_OUTSIDE_AND;
3481 if (GET_CODE (XEXP (exp, 0)) == code
3482 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3483 || (GET_CODE (XEXP (exp, 0)) == NOT
3484 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3485 attrs_cached
3486 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3487 else
3488 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3490 switch (code)
3492 case EQ:
3493 fprintf (outf, " == ");
3494 break;
3495 case NE:
3496 fprintf (outf, " != ");
3497 break;
3498 case GE:
3499 fprintf (outf, " >= ");
3500 break;
3501 case GT:
3502 fprintf (outf, " > ");
3503 break;
3504 case GEU:
3505 fprintf (outf, " >= (unsigned) ");
3506 break;
3507 case GTU:
3508 fprintf (outf, " > (unsigned) ");
3509 break;
3510 case LE:
3511 fprintf (outf, " <= ");
3512 break;
3513 case LT:
3514 fprintf (outf, " < ");
3515 break;
3516 case LEU:
3517 fprintf (outf, " <= (unsigned) ");
3518 break;
3519 case LTU:
3520 fprintf (outf, " < (unsigned) ");
3521 break;
3522 case PLUS:
3523 fprintf (outf, " + ");
3524 break;
3525 case MINUS:
3526 fprintf (outf, " - ");
3527 break;
3528 case MULT:
3529 fprintf (outf, " * ");
3530 break;
3531 case DIV:
3532 fprintf (outf, " / ");
3533 break;
3534 case MOD:
3535 fprintf (outf, " %% ");
3536 break;
3537 case AND:
3538 if (flags & FLG_BITWISE)
3539 fprintf (outf, " & ");
3540 else
3541 fprintf (outf, " && ");
3542 break;
3543 case IOR:
3544 if (flags & FLG_BITWISE)
3545 fprintf (outf, " | ");
3546 else
3547 fprintf (outf, " || ");
3548 break;
3549 case XOR:
3550 fprintf (outf, " ^ ");
3551 break;
3552 case ASHIFT:
3553 fprintf (outf, " << ");
3554 break;
3555 case LSHIFTRT:
3556 case ASHIFTRT:
3557 fprintf (outf, " >> ");
3558 break;
3559 default:
3560 gcc_unreachable ();
3563 if (code == AND)
3565 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3566 cached_x is only known to be initialized in then block. */
3567 flags &= ~FLG_AFTER;
3569 else if (code == IOR)
3571 if (flags & FLG_OUTSIDE_AND)
3572 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3573 cached_x is only known to be initialized in else block
3574 and else if conditions. */
3575 flags &= ~FLG_INSIDE;
3576 else
3577 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3578 && something_else)
3579 cached_x is not know to be initialized anywhere. */
3580 flags &= ~(FLG_AFTER | FLG_INSIDE);
3582 if ((code == AND || code == IOR)
3583 && (GET_CODE (XEXP (exp, 1)) == code
3584 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3585 || (GET_CODE (XEXP (exp, 1)) == NOT
3586 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3587 attrs_cached
3588 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags);
3589 else
3590 write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3591 flags | comparison_operator);
3592 break;
3594 case NOT:
3595 /* Special-case (not (eq_attrq "alternative" "x")) */
3596 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3598 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3600 fprintf (outf, "which_alternative != %s",
3601 XSTR (XEXP (exp, 0), 1));
3602 break;
3605 fprintf (outf, "! ");
3606 attrs_cached =
3607 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3608 break;
3611 /* Otherwise, fall through to normal unary operator. */
3613 /* Unary operators. */
3614 case ABS: case NEG:
3615 switch (code)
3617 case NOT:
3618 if (flags & FLG_BITWISE)
3619 fprintf (outf, "~ ");
3620 else
3621 fprintf (outf, "! ");
3622 break;
3623 case ABS:
3624 fprintf (outf, "abs ");
3625 break;
3626 case NEG:
3627 fprintf (outf, "-");
3628 break;
3629 default:
3630 gcc_unreachable ();
3633 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3634 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3635 break;
3637 case EQ_ATTR_ALT:
3639 int set = XINT (exp, 0), bit = 0;
3641 if (flags & FLG_BITWISE)
3642 fatal ("EQ_ATTR_ALT not valid inside comparison");
3644 if (!set)
3645 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3647 if (!(set & (set - 1)))
3649 if (!(set & 0xffff))
3651 bit += 16;
3652 set >>= 16;
3654 if (!(set & 0xff))
3656 bit += 8;
3657 set >>= 8;
3659 if (!(set & 0xf))
3661 bit += 4;
3662 set >>= 4;
3664 if (!(set & 0x3))
3666 bit += 2;
3667 set >>= 2;
3669 if (!(set & 1))
3670 bit++;
3672 fprintf (outf, "which_alternative %s= %d",
3673 XINT (exp, 1) ? "!" : "=", bit);
3675 else
3677 fprintf (outf, "%s((1 << which_alternative) & %#x)",
3678 XINT (exp, 1) ? "!" : "", set);
3681 break;
3683 /* Comparison test of an attribute with a value. Most of these will
3684 have been removed by optimization. Handle "alternative"
3685 specially and give error if EQ_ATTR present inside a comparison. */
3686 case EQ_ATTR:
3687 if (flags & FLG_BITWISE)
3688 fatal ("EQ_ATTR not valid inside comparison");
3690 if (XSTR (exp, 0) == alternative_name)
3692 fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3693 break;
3696 attr = find_attr (&XSTR (exp, 0), 0);
3697 gcc_assert (attr);
3699 /* Now is the time to expand the value of a constant attribute. */
3700 if (attr->is_const)
3702 write_test_expr (outf,
3703 evaluate_eq_attr (exp, attr,
3704 attr->default_val->value,
3705 -2, -2),
3706 attrs_cached, 0);
3708 else
3710 int i;
3711 for (i = 0; i < cached_attr_count; i++)
3712 if (attr->name == cached_attrs[i])
3713 break;
3714 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3715 fprintf (outf, "cached_%s", attr->name);
3716 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3718 fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3719 attr->name, attr->name);
3720 if (flags & FLG_AFTER)
3721 attrs_cached_after |= (1U << i);
3722 if (flags & FLG_INSIDE)
3723 attrs_cached_inside |= (1U << i);
3724 attrs_cached |= (1U << i);
3726 else
3727 fprintf (outf, "get_attr_%s (insn)", attr->name);
3728 fprintf (outf, " == ");
3729 write_attr_valueq (outf, attr, XSTR (exp, 1));
3731 break;
3733 /* Comparison test of flags for define_delays. */
3734 case ATTR_FLAG:
3735 if (flags & FLG_BITWISE)
3736 fatal ("ATTR_FLAG not valid inside comparison");
3737 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3738 break;
3740 /* See if an operand matches a predicate. */
3741 case MATCH_OPERAND:
3742 /* If only a mode is given, just ensure the mode matches the operand.
3743 If neither a mode nor predicate is given, error. */
3744 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3746 if (GET_MODE (exp) == VOIDmode)
3747 fatal ("null MATCH_OPERAND specified as test");
3748 else
3749 fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3750 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3752 else
3753 fprintf (outf, "%s (operands[%d], %smode)",
3754 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3755 break;
3757 /* Constant integer. */
3758 case CONST_INT:
3759 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3760 break;
3762 case MATCH_TEST:
3763 fprint_c_condition (outf, XSTR (exp, 0));
3764 if (flags & FLG_BITWISE)
3765 fprintf (outf, " != 0");
3766 break;
3768 /* A random C expression. */
3769 case SYMBOL_REF:
3770 fprint_c_condition (outf, XSTR (exp, 0));
3771 break;
3773 /* The address of the branch target. */
3774 case MATCH_DUP:
3775 fprintf (outf,
3776 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3777 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3778 break;
3780 case PC:
3781 /* The address of the current insn. We implement this actually as the
3782 address of the current insn for backward branches, but the last
3783 address of the next insn for forward branches, and both with
3784 adjustments that account for the worst-case possible stretching of
3785 intervening alignments between this insn and its destination. */
3786 fprintf (outf, "insn_current_reference_address (insn)");
3787 break;
3789 case CONST_STRING:
3790 fprintf (outf, "%s", XSTR (exp, 0));
3791 break;
3793 case IF_THEN_ELSE:
3794 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3795 fprintf (outf, " ? ");
3796 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3797 fprintf (outf, " : ");
3798 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3799 break;
3801 default:
3802 fatal ("bad RTX code `%s' in attribute calculation\n",
3803 GET_RTX_NAME (code));
3806 fprintf (outf, ")");
3807 return attrs_cached;
3810 /* Given an attribute value, return the maximum CONST_STRING argument
3811 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3813 static int
3814 max_attr_value (rtx exp, int *unknownp)
3816 int current_max;
3817 int i, n;
3819 switch (GET_CODE (exp))
3821 case CONST_STRING:
3822 current_max = atoi (XSTR (exp, 0));
3823 break;
3825 case COND:
3826 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3827 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3829 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3830 if (n > current_max)
3831 current_max = n;
3833 break;
3835 case IF_THEN_ELSE:
3836 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3837 n = max_attr_value (XEXP (exp, 2), unknownp);
3838 if (n > current_max)
3839 current_max = n;
3840 break;
3842 default:
3843 *unknownp = 1;
3844 current_max = INT_MAX;
3845 break;
3848 return current_max;
3851 /* Given an attribute value, return the minimum CONST_STRING argument
3852 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3854 static int
3855 min_attr_value (rtx exp, int *unknownp)
3857 int current_min;
3858 int i, n;
3860 switch (GET_CODE (exp))
3862 case CONST_STRING:
3863 current_min = atoi (XSTR (exp, 0));
3864 break;
3866 case COND:
3867 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3868 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3870 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3871 if (n < current_min)
3872 current_min = n;
3874 break;
3876 case IF_THEN_ELSE:
3877 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3878 n = min_attr_value (XEXP (exp, 2), unknownp);
3879 if (n < current_min)
3880 current_min = n;
3881 break;
3883 default:
3884 *unknownp = 1;
3885 current_min = INT_MAX;
3886 break;
3889 return current_min;
3892 /* Given an attribute value, return the result of ORing together all
3893 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3894 if the numeric value is not known. */
3896 static int
3897 or_attr_value (rtx exp, int *unknownp)
3899 int current_or;
3900 int i;
3902 switch (GET_CODE (exp))
3904 case CONST_STRING:
3905 current_or = atoi (XSTR (exp, 0));
3906 break;
3908 case COND:
3909 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3910 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3911 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3912 break;
3914 case IF_THEN_ELSE:
3915 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3916 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3917 break;
3919 default:
3920 *unknownp = 1;
3921 current_or = -1;
3922 break;
3925 return current_or;
3928 /* Scan an attribute value, possibly a conditional, and record what actions
3929 will be required to do any conditional tests in it.
3931 Specifically, set
3932 `must_extract' if we need to extract the insn operands
3933 `must_constrain' if we must compute `which_alternative'
3934 `address_used' if an address expression was used
3935 `length_used' if an (eq_attr "length" ...) was used
3938 static void
3939 walk_attr_value (rtx exp)
3941 int i, j;
3942 const char *fmt;
3943 RTX_CODE code;
3945 if (exp == NULL)
3946 return;
3948 code = GET_CODE (exp);
3949 switch (code)
3951 case SYMBOL_REF:
3952 if (! ATTR_IND_SIMPLIFIED_P (exp))
3953 /* Since this is an arbitrary expression, it can look at anything.
3954 However, constant expressions do not depend on any particular
3955 insn. */
3956 must_extract = must_constrain = 1;
3957 return;
3959 case MATCH_OPERAND:
3960 must_extract = 1;
3961 return;
3963 case MATCH_TEST:
3964 case EQ_ATTR_ALT:
3965 must_extract = must_constrain = 1;
3966 break;
3968 case EQ_ATTR:
3969 if (XSTR (exp, 0) == alternative_name)
3970 must_extract = must_constrain = 1;
3971 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3972 length_used = 1;
3973 return;
3975 case MATCH_DUP:
3976 must_extract = 1;
3977 address_used = 1;
3978 return;
3980 case PC:
3981 address_used = 1;
3982 return;
3984 case ATTR_FLAG:
3985 return;
3987 default:
3988 break;
3991 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3992 switch (*fmt++)
3994 case 'e':
3995 case 'u':
3996 walk_attr_value (XEXP (exp, i));
3997 break;
3999 case 'E':
4000 if (XVEC (exp, i) != NULL)
4001 for (j = 0; j < XVECLEN (exp, i); j++)
4002 walk_attr_value (XVECEXP (exp, i, j));
4003 break;
4007 /* Write out a function to obtain the attribute for a given INSN. */
4009 static void
4010 write_attr_get (FILE *outf, struct attr_desc *attr)
4012 struct attr_value *av, *common_av;
4013 int i, j;
4015 /* Find the most used attribute value. Handle that as the `default' of the
4016 switch we will generate. */
4017 common_av = find_most_used (attr);
4019 /* Write out start of function, then all values with explicit `case' lines,
4020 then a `default', then the value with the most uses. */
4021 if (attr->enum_name)
4022 fprintf (outf, "enum %s\n", attr->enum_name);
4023 else if (!attr->is_numeric)
4024 fprintf (outf, "enum attr_%s\n", attr->name);
4025 else
4026 fprintf (outf, "int\n");
4028 /* If the attribute name starts with a star, the remainder is the name of
4029 the subroutine to use, instead of `get_attr_...'. */
4030 if (attr->name[0] == '*')
4031 fprintf (outf, "%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4032 else if (attr->is_const == 0)
4033 fprintf (outf, "get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
4034 else
4036 fprintf (outf, "get_attr_%s (void)\n", attr->name);
4037 fprintf (outf, "{\n");
4039 for (av = attr->first_value; av; av = av->next)
4040 if (av->num_insns == 1)
4041 write_attr_set (outf, attr, 2, av->value, "return", ";",
4042 true_rtx, av->first_insn->def->insn_code,
4043 av->first_insn->def->insn_index, 0);
4044 else if (av->num_insns != 0)
4045 write_attr_set (outf, attr, 2, av->value, "return", ";",
4046 true_rtx, -2, 0, 0);
4048 fprintf (outf, "}\n\n");
4049 return;
4052 fprintf (outf, "{\n");
4054 /* Find attributes that are worth caching in the conditions. */
4055 cached_attr_count = 0;
4056 attrs_seen_more_than_once = 0;
4057 for (av = attr->first_value; av; av = av->next)
4059 attrs_seen_once = 0;
4060 find_attrs_to_cache (av->value, true);
4062 /* Remove those that aren't worth caching from the array. */
4063 for (i = 0, j = 0; i < cached_attr_count; i++)
4064 if ((attrs_seen_more_than_once & (1U << i)) != 0)
4066 const char *name = cached_attrs[i];
4067 struct attr_desc *cached_attr;
4068 if (i != j)
4069 cached_attrs[j] = name;
4070 cached_attr = find_attr (&name, 0);
4071 gcc_assert (cached_attr && cached_attr->is_const == 0);
4072 if (cached_attr->enum_name)
4073 fprintf (outf, " enum %s", cached_attr->enum_name);
4074 else if (!cached_attr->is_numeric)
4075 fprintf (outf, " enum attr_%s", cached_attr->name);
4076 else
4077 fprintf (outf, " int");
4078 fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
4079 j++;
4081 cached_attr_count = j;
4082 if (cached_attr_count)
4083 fprintf (outf, "\n");
4085 fprintf (outf, " switch (recog_memoized (insn))\n");
4086 fprintf (outf, " {\n");
4088 for (av = attr->first_value; av; av = av->next)
4089 if (av != common_av)
4090 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4092 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4093 fprintf (outf, " }\n}\n\n");
4094 cached_attr_count = 0;
4097 /* Given an AND tree of known true terms (because we are inside an `if' with
4098 that as the condition or are in an `else' clause) and an expression,
4099 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4100 the bulk of the work. */
4102 static rtx
4103 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4105 rtx term;
4107 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4109 if (GET_CODE (known_true) == AND)
4111 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4112 insn_code, insn_index);
4113 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4114 insn_code, insn_index);
4116 else
4118 term = known_true;
4119 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4122 return exp;
4125 /* Write out a series of tests and assignment statements to perform tests and
4126 sets of an attribute value. We are passed an indentation amount and prefix
4127 and suffix strings to write around each attribute value (e.g., "return"
4128 and ";"). */
4130 static void
4131 write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
4132 const char *prefix, const char *suffix, rtx known_true,
4133 int insn_code, int insn_index, unsigned int attrs_cached)
4135 if (GET_CODE (value) == COND)
4137 /* Assume the default value will be the default of the COND unless we
4138 find an always true expression. */
4139 rtx default_val = XEXP (value, 1);
4140 rtx our_known_true = known_true;
4141 rtx newexp;
4142 int first_if = 1;
4143 int i;
4145 if (cached_attr_count)
4147 attrs_seen_once = 0;
4148 attrs_seen_more_than_once = 0;
4149 for (i = 0; i < XVECLEN (value, 0); i += 2)
4150 find_attrs_to_cache (XVECEXP (value, 0, i), false);
4151 attrs_to_cache |= attrs_seen_more_than_once;
4154 for (i = 0; i < XVECLEN (value, 0); i += 2)
4156 rtx testexp;
4157 rtx inner_true;
4159 /* Reset our_known_true after some time to not accumulate
4160 too much cruft (slowing down genattrtab). */
4161 if ((i & 31) == 0)
4162 our_known_true = known_true;
4163 testexp = eliminate_known_true (our_known_true,
4164 XVECEXP (value, 0, i),
4165 insn_code, insn_index);
4166 newexp = attr_rtx (NOT, testexp);
4167 newexp = insert_right_side (AND, our_known_true, newexp,
4168 insn_code, insn_index);
4170 /* If the test expression is always true or if the next `known_true'
4171 expression is always false, this is the last case, so break
4172 out and let this value be the `else' case. */
4173 if (testexp == true_rtx || newexp == false_rtx)
4175 default_val = XVECEXP (value, 0, i + 1);
4176 break;
4179 /* Compute the expression to pass to our recursive call as being
4180 known true. */
4181 inner_true = insert_right_side (AND, our_known_true,
4182 testexp, insn_code, insn_index);
4184 /* If this is always false, skip it. */
4185 if (inner_true == false_rtx)
4186 continue;
4188 attrs_cached_inside = attrs_cached;
4189 attrs_cached_after = attrs_cached;
4190 write_indent (outf, indent);
4191 fprintf (outf, "%sif ", first_if ? "" : "else ");
4192 first_if = 0;
4193 write_test_expr (outf, testexp, attrs_cached,
4194 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4195 attrs_cached = attrs_cached_after;
4196 fprintf (outf, "\n");
4197 write_indent (outf, indent + 2);
4198 fprintf (outf, "{\n");
4200 write_attr_set (outf, attr, indent + 4,
4201 XVECEXP (value, 0, i + 1), prefix, suffix,
4202 inner_true, insn_code, insn_index,
4203 attrs_cached_inside);
4204 write_indent (outf, indent + 2);
4205 fprintf (outf, "}\n");
4206 our_known_true = newexp;
4209 if (! first_if)
4211 write_indent (outf, indent);
4212 fprintf (outf, "else\n");
4213 write_indent (outf, indent + 2);
4214 fprintf (outf, "{\n");
4217 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4218 prefix, suffix, our_known_true, insn_code, insn_index,
4219 attrs_cached);
4221 if (! first_if)
4223 write_indent (outf, indent + 2);
4224 fprintf (outf, "}\n");
4227 else
4229 write_indent (outf, indent);
4230 fprintf (outf, "%s ", prefix);
4231 write_attr_value (outf, attr, value);
4232 fprintf (outf, "%s\n", suffix);
4236 /* Write a series of case statements for every instruction in list IE.
4237 INDENT is the amount of indentation to write before each case. */
4239 static void
4240 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4242 for (; ie != 0; ie = ie->next)
4243 if (ie->def->insn_code != -1)
4245 write_indent (outf, indent);
4246 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4247 fprintf (outf, "case %d: /* define_peephole, line %d */\n",
4248 ie->def->insn_code, ie->def->lineno);
4249 else
4250 fprintf (outf, "case %d: /* %s */\n",
4251 ie->def->insn_code, XSTR (ie->def->def, 0));
4255 /* Write out the computation for one attribute value. */
4257 static void
4258 write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
4259 int write_case_lines, const char *prefix, const char *suffix,
4260 int indent, rtx known_true)
4262 if (av->num_insns == 0)
4263 return;
4265 if (av->has_asm_insn)
4267 write_indent (outf, indent);
4268 fprintf (outf, "case -1:\n");
4269 write_indent (outf, indent + 2);
4270 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4271 write_indent (outf, indent + 2);
4272 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
4273 write_indent (outf, indent + 2);
4274 fprintf (outf, " fatal_insn_not_found (insn);\n");
4277 if (write_case_lines)
4278 write_insn_cases (outf, av->first_insn, indent);
4279 else
4281 write_indent (outf, indent);
4282 fprintf (outf, "default:\n");
4285 /* See what we have to do to output this value. */
4286 must_extract = must_constrain = address_used = 0;
4287 walk_attr_value (av->value);
4289 if (must_constrain)
4291 write_indent (outf, indent + 2);
4292 fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4294 else if (must_extract)
4296 write_indent (outf, indent + 2);
4297 fprintf (outf, "extract_insn_cached (insn);\n");
4300 attrs_to_cache = 0;
4301 if (av->num_insns == 1)
4302 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4303 known_true, av->first_insn->def->insn_code,
4304 av->first_insn->def->insn_index, 0);
4305 else
4306 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4307 known_true, -2, 0, 0);
4309 if (strncmp (prefix, "return", 6))
4311 write_indent (outf, indent + 2);
4312 fprintf (outf, "break;\n");
4314 fprintf (outf, "\n");
4317 /* Utilities to write in various forms. */
4319 static void
4320 write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
4322 if (attr->is_numeric)
4324 int num = atoi (s);
4326 fprintf (outf, "%d", num);
4328 if (num > 9 || num < 0)
4329 fprintf (outf, " /* %#x */", num);
4331 else
4333 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4334 fprintf (outf, "_");
4335 write_upcase (outf, s);
4339 static void
4340 write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
4342 int op;
4344 switch (GET_CODE (value))
4346 case CONST_STRING:
4347 write_attr_valueq (outf, attr, XSTR (value, 0));
4348 break;
4350 case CONST_INT:
4351 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4352 break;
4354 case SYMBOL_REF:
4355 fprint_c_condition (outf, XSTR (value, 0));
4356 break;
4358 case ATTR:
4360 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4361 if (attr->enum_name)
4362 fprintf (outf, "(enum %s)", attr->enum_name);
4363 else if (!attr->is_numeric)
4364 fprintf (outf, "(enum attr_%s)", attr->name);
4365 else if (!attr2->is_numeric)
4366 fprintf (outf, "(int)");
4368 fprintf (outf, "get_attr_%s (%s)", attr2->name,
4369 (attr2->is_const ? "" : "insn"));
4371 break;
4373 case PLUS:
4374 op = '+';
4375 goto do_operator;
4376 case MINUS:
4377 op = '-';
4378 goto do_operator;
4379 case MULT:
4380 op = '*';
4381 goto do_operator;
4382 case DIV:
4383 op = '/';
4384 goto do_operator;
4385 case MOD:
4386 op = '%';
4387 goto do_operator;
4389 do_operator:
4390 write_attr_value (outf, attr, XEXP (value, 0));
4391 fputc (' ', outf);
4392 fputc (op, outf);
4393 fputc (' ', outf);
4394 write_attr_value (outf, attr, XEXP (value, 1));
4395 break;
4397 default:
4398 gcc_unreachable ();
4402 static void
4403 write_upcase (FILE *outf, const char *str)
4405 while (*str)
4407 /* The argument of TOUPPER should not have side effects. */
4408 fputc (TOUPPER(*str), outf);
4409 str++;
4413 static void
4414 write_indent (FILE *outf, int indent)
4416 for (; indent > 8; indent -= 8)
4417 fprintf (outf, "\t");
4419 for (; indent; indent--)
4420 fprintf (outf, " ");
4423 /* Write a subroutine that is given an insn that requires a delay slot, a
4424 delay slot ordinal, and a candidate insn. It returns nonzero if the
4425 candidate can be placed in the specified delay slot of the insn.
4427 We can write as many as three subroutines. `eligible_for_delay'
4428 handles normal delay slots, `eligible_for_annul_true' indicates that
4429 the specified insn can be annulled if the branch is true, and likewise
4430 for `eligible_for_annul_false'.
4432 KIND is a string distinguishing these three cases ("delay", "annul_true",
4433 or "annul_false"). */
4435 static void
4436 write_eligible_delay (FILE *outf, const char *kind)
4438 struct delay_desc *delay;
4439 int max_slots;
4440 char str[50];
4441 const char *pstr;
4442 struct attr_desc *attr;
4443 struct attr_value *av, *common_av;
4444 int i;
4446 /* Compute the maximum number of delay slots required. We use the delay
4447 ordinal times this number plus one, plus the slot number as an index into
4448 the appropriate predicate to test. */
4450 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4451 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4452 max_slots = XVECLEN (delay->def, 1) / 3;
4454 /* Write function prelude. */
4456 fprintf (outf, "int\n");
4457 fprintf (outf, "eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4458 " rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4459 kind);
4460 fprintf (outf, "{\n");
4461 fprintf (outf, " rtx insn;\n");
4462 fprintf (outf, "\n");
4463 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
4464 fprintf (outf, "\n");
4465 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4466 converts a compound instruction into a loop. */
4467 fprintf (outf, " if (!INSN_P (candidate_insn))\n");
4468 fprintf (outf, " return 0;\n");
4469 fprintf (outf, "\n");
4471 /* If more than one delay type, find out which type the delay insn is. */
4473 if (num_delays > 1)
4475 attr = find_attr (&delay_type_str, 0);
4476 gcc_assert (attr);
4477 common_av = find_most_used (attr);
4479 fprintf (outf, " insn = delay_insn;\n");
4480 fprintf (outf, " switch (recog_memoized (insn))\n");
4481 fprintf (outf, " {\n");
4483 sprintf (str, " * %d;\n break;", max_slots);
4484 for (av = attr->first_value; av; av = av->next)
4485 if (av != common_av)
4486 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4488 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4489 fprintf (outf, " }\n\n");
4491 /* Ensure matched. Otherwise, shouldn't have been called. */
4492 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
4495 /* If just one type of delay slot, write simple switch. */
4496 if (num_delays == 1 && max_slots == 1)
4498 fprintf (outf, " insn = candidate_insn;\n");
4499 fprintf (outf, " switch (recog_memoized (insn))\n");
4500 fprintf (outf, " {\n");
4502 attr = find_attr (&delay_1_0_str, 0);
4503 gcc_assert (attr);
4504 common_av = find_most_used (attr);
4506 for (av = attr->first_value; av; av = av->next)
4507 if (av != common_av)
4508 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4510 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4511 fprintf (outf, " }\n");
4514 else
4516 /* Write a nested CASE. The first indicates which condition we need to
4517 test, and the inner CASE tests the condition. */
4518 fprintf (outf, " insn = candidate_insn;\n");
4519 fprintf (outf, " switch (slot)\n");
4520 fprintf (outf, " {\n");
4522 for (delay = delays; delay; delay = delay->next)
4523 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4525 fprintf (outf, " case %d:\n",
4526 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4527 fprintf (outf, " switch (recog_memoized (insn))\n");
4528 fprintf (outf, "\t{\n");
4530 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4531 pstr = str;
4532 attr = find_attr (&pstr, 0);
4533 gcc_assert (attr);
4534 common_av = find_most_used (attr);
4536 for (av = attr->first_value; av; av = av->next)
4537 if (av != common_av)
4538 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4540 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4541 fprintf (outf, " }\n");
4544 fprintf (outf, " default:\n");
4545 fprintf (outf, " gcc_unreachable ();\n");
4546 fprintf (outf, " }\n");
4549 fprintf (outf, "}\n\n");
4552 /* This page contains miscellaneous utility routines. */
4554 /* Given a pointer to a (char *), return a malloc'ed string containing the
4555 next comma-separated element. Advance the pointer to after the string
4556 scanned, or the end-of-string. Return NULL if at end of string. */
4558 static char *
4559 next_comma_elt (const char **pstr)
4561 const char *start;
4563 start = scan_comma_elt (pstr);
4565 if (start == NULL)
4566 return NULL;
4568 return attr_string (start, *pstr - start);
4571 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4572 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4573 replaced by a pointer to a canonical copy of the string. */
4575 static struct attr_desc *
4576 find_attr (const char **name_p, int create)
4578 struct attr_desc *attr;
4579 int index;
4580 const char *name = *name_p;
4582 /* Before we resort to using `strcmp', see if the string address matches
4583 anywhere. In most cases, it should have been canonicalized to do so. */
4584 if (name == alternative_name)
4585 return NULL;
4587 index = name[0] & (MAX_ATTRS_INDEX - 1);
4588 for (attr = attrs[index]; attr; attr = attr->next)
4589 if (name == attr->name)
4590 return attr;
4592 /* Otherwise, do it the slow way. */
4593 for (attr = attrs[index]; attr; attr = attr->next)
4594 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4596 *name_p = attr->name;
4597 return attr;
4600 if (! create)
4601 return NULL;
4603 attr = oballoc (struct attr_desc);
4604 attr->name = DEF_ATTR_STRING (name);
4605 attr->enum_name = 0;
4606 attr->first_value = attr->default_val = NULL;
4607 attr->is_numeric = attr->is_const = attr->is_special = 0;
4608 attr->next = attrs[index];
4609 attrs[index] = attr;
4611 *name_p = attr->name;
4613 return attr;
4616 /* Create internal attribute with the given default value. */
4618 static void
4619 make_internal_attr (const char *name, rtx value, int special)
4621 struct attr_desc *attr;
4623 attr = find_attr (&name, 1);
4624 gcc_assert (!attr->default_val);
4626 attr->is_numeric = 1;
4627 attr->is_const = 0;
4628 attr->is_special = (special & ATTR_SPECIAL) != 0;
4629 attr->default_val = get_attr_value (value, attr, -2);
4632 /* Find the most used value of an attribute. */
4634 static struct attr_value *
4635 find_most_used (struct attr_desc *attr)
4637 struct attr_value *av;
4638 struct attr_value *most_used;
4639 int nuses;
4641 most_used = NULL;
4642 nuses = -1;
4644 for (av = attr->first_value; av; av = av->next)
4645 if (av->num_insns > nuses)
4646 nuses = av->num_insns, most_used = av;
4648 return most_used;
4651 /* Return (attr_value "n") */
4653 static rtx
4654 make_numeric_value (int n)
4656 static rtx int_values[20];
4657 rtx exp;
4658 char *p;
4660 gcc_assert (n >= 0);
4662 if (n < 20 && int_values[n])
4663 return int_values[n];
4665 p = attr_printf (MAX_DIGITS, "%d", n);
4666 exp = attr_rtx (CONST_STRING, p);
4668 if (n < 20)
4669 int_values[n] = exp;
4671 return exp;
4674 static rtx
4675 copy_rtx_unchanging (rtx orig)
4677 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4678 return orig;
4680 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4681 return orig;
4684 /* Determine if an insn has a constant number of delay slots, i.e., the
4685 number of delay slots is not a function of the length of the insn. */
4687 static void
4688 write_const_num_delay_slots (FILE *outf)
4690 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4691 struct attr_value *av;
4693 if (attr)
4695 fprintf (outf, "int\nconst_num_delay_slots (rtx insn)\n");
4696 fprintf (outf, "{\n");
4697 fprintf (outf, " switch (recog_memoized (insn))\n");
4698 fprintf (outf, " {\n");
4700 for (av = attr->first_value; av; av = av->next)
4702 length_used = 0;
4703 walk_attr_value (av->value);
4704 if (length_used)
4705 write_insn_cases (outf, av->first_insn, 4);
4708 fprintf (outf, " default:\n");
4709 fprintf (outf, " return 1;\n");
4710 fprintf (outf, " }\n}\n\n");
4714 /* Synthetic attributes used by insn-automata.c and the scheduler.
4715 These are primarily concerned with (define_insn_reservation)
4716 patterns. */
4718 struct insn_reserv
4720 struct insn_reserv *next;
4722 const char *name;
4723 int default_latency;
4724 rtx condexp;
4726 /* Sequence number of this insn. */
4727 int insn_num;
4729 /* Whether a (define_bypass) construct names this insn in its
4730 output list. */
4731 bool bypassed;
4734 static struct insn_reserv *all_insn_reservs = 0;
4735 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4736 static size_t n_insn_reservs;
4738 /* Store information from a DEFINE_INSN_RESERVATION for future
4739 attribute generation. */
4740 static void
4741 gen_insn_reserv (rtx def)
4743 struct insn_reserv *decl = oballoc (struct insn_reserv);
4745 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4746 decl->default_latency = XINT (def, 1);
4747 decl->condexp = check_attr_test (XEXP (def, 2), 0, 0);
4748 decl->insn_num = n_insn_reservs;
4749 decl->bypassed = false;
4750 decl->next = 0;
4752 *last_insn_reserv_p = decl;
4753 last_insn_reserv_p = &decl->next;
4754 n_insn_reservs++;
4757 /* Store information from a DEFINE_BYPASS for future attribute
4758 generation. The only thing we care about is the list of output
4759 insns, which will later be used to tag reservation structures with
4760 a 'bypassed' bit. */
4762 struct bypass_list
4764 struct bypass_list *next;
4765 const char *pattern;
4768 static struct bypass_list *all_bypasses;
4769 static size_t n_bypasses;
4771 static void
4772 gen_bypass_1 (const char *s, size_t len)
4774 struct bypass_list *b;
4776 if (len == 0)
4777 return;
4779 s = attr_string (s, len);
4780 for (b = all_bypasses; b; b = b->next)
4781 if (s == b->pattern)
4782 return; /* already got that one */
4784 b = oballoc (struct bypass_list);
4785 b->pattern = s;
4786 b->next = all_bypasses;
4787 all_bypasses = b;
4788 n_bypasses++;
4791 static void
4792 gen_bypass (rtx def)
4794 const char *p, *base;
4796 for (p = base = XSTR (def, 1); *p; p++)
4797 if (*p == ',')
4799 gen_bypass_1 (base, p - base);
4801 p++;
4802 while (ISSPACE (*p));
4803 base = p;
4805 gen_bypass_1 (base, p - base);
4808 /* Find and mark all of the bypassed insns. */
4809 static void
4810 process_bypasses (void)
4812 struct bypass_list *b;
4813 struct insn_reserv *r;
4815 /* The reservation list is likely to be much longer than the bypass
4816 list. */
4817 for (r = all_insn_reservs; r; r = r->next)
4818 for (b = all_bypasses; b; b = b->next)
4819 if (fnmatch (b->pattern, r->name, 0) == 0)
4820 r->bypassed = true;
4823 /* Check that attribute NAME is used in define_insn_reservation condition
4824 EXP. Return true if it is. */
4825 static bool
4826 check_tune_attr (const char *name, rtx exp)
4828 switch (GET_CODE (exp))
4830 case AND:
4831 if (check_tune_attr (name, XEXP (exp, 0)))
4832 return true;
4833 return check_tune_attr (name, XEXP (exp, 1));
4835 case IOR:
4836 return (check_tune_attr (name, XEXP (exp, 0))
4837 && check_tune_attr (name, XEXP (exp, 1)));
4839 case EQ_ATTR:
4840 return XSTR (exp, 0) == name;
4842 default:
4843 return false;
4847 /* Try to find a const attribute (usually cpu or tune) that is used
4848 in all define_insn_reservation conditions. */
4849 static struct attr_desc *
4850 find_tune_attr (rtx exp)
4852 struct attr_desc *attr;
4854 switch (GET_CODE (exp))
4856 case AND:
4857 case IOR:
4858 attr = find_tune_attr (XEXP (exp, 0));
4859 if (attr)
4860 return attr;
4861 return find_tune_attr (XEXP (exp, 1));
4863 case EQ_ATTR:
4864 if (XSTR (exp, 0) == alternative_name)
4865 return NULL;
4867 attr = find_attr (&XSTR (exp, 0), 0);
4868 gcc_assert (attr);
4870 if (attr->is_const && !attr->is_special)
4872 struct insn_reserv *decl;
4874 for (decl = all_insn_reservs; decl; decl = decl->next)
4875 if (! check_tune_attr (attr->name, decl->condexp))
4876 return NULL;
4877 return attr;
4879 return NULL;
4881 default:
4882 return NULL;
4886 /* Create all of the attributes that describe automaton properties.
4887 Write the DFA and latency function prototypes to the files that
4888 need to have them, and write the init_sched_attrs(). */
4890 static void
4891 make_automaton_attrs (void)
4893 int i;
4894 struct insn_reserv *decl;
4895 rtx code_exp, lats_exp, byps_exp;
4896 struct attr_desc *tune_attr;
4898 if (n_insn_reservs == 0)
4899 return;
4901 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4902 if (tune_attr != NULL)
4904 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4905 struct attr_value *val;
4906 bool first = true;
4908 gcc_assert (tune_attr->is_const
4909 && !tune_attr->is_special
4910 && !tune_attr->is_numeric);
4912 /* Write the prototypes for all DFA functions. */
4913 for (val = tune_attr->first_value; val; val = val->next)
4915 if (val == tune_attr->default_val)
4916 continue;
4917 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4918 fprintf (dfa_file,
4919 "extern int internal_dfa_insn_code_%s (rtx);\n",
4920 XSTR (val->value, 0));
4922 fprintf (dfa_file, "\n");
4924 /* Write the prototypes for all latency functions. */
4925 for (val = tune_attr->first_value; val; val = val->next)
4927 if (val == tune_attr->default_val)
4928 continue;
4929 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4930 fprintf (latency_file,
4931 "extern int insn_default_latency_%s (rtx);\n",
4932 XSTR (val->value, 0));
4934 fprintf (latency_file, "\n");
4936 /* Write the prototypes for all automaton functions. */
4937 for (val = tune_attr->first_value; val; val = val->next)
4939 if (val == tune_attr->default_val)
4940 continue;
4941 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4942 fprintf (attr_file,
4943 "extern int internal_dfa_insn_code_%s (rtx);\n"
4944 "extern int insn_default_latency_%s (rtx);\n",
4945 XSTR (val->value, 0), XSTR (val->value, 0));
4947 fprintf (attr_file, "\n");
4948 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx);\n");
4949 fprintf (attr_file, "int (*insn_default_latency) (rtx);\n");
4950 fprintf (attr_file, "\n");
4951 fprintf (attr_file, "void\n");
4952 fprintf (attr_file, "init_sched_attrs (void)\n");
4953 fprintf (attr_file, "{\n");
4955 for (val = tune_attr->first_value; val; val = val->next)
4957 int j;
4958 char *name;
4959 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
4961 if (val == tune_attr->default_val)
4962 continue;
4963 for (decl = all_insn_reservs, i = 0;
4964 decl;
4965 decl = decl->next)
4967 rtx ctest = test;
4968 rtx condexp
4969 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
4970 if (condexp == false_rtx)
4971 continue;
4972 if (condexp == true_rtx)
4973 break;
4974 condexps[i] = condexp;
4975 condexps[i + 1] = make_numeric_value (decl->insn_num);
4976 condexps[i + 2] = make_numeric_value (decl->default_latency);
4977 i += 3;
4980 code_exp = rtx_alloc (COND);
4981 lats_exp = rtx_alloc (COND);
4983 j = i / 3 * 2;
4984 XVEC (code_exp, 0) = rtvec_alloc (j);
4985 XVEC (lats_exp, 0) = rtvec_alloc (j);
4987 if (decl)
4989 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
4990 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
4992 else
4994 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
4995 XEXP (lats_exp, 1) = make_numeric_value (0);
4998 while (i > 0)
5000 i -= 3;
5001 j -= 2;
5002 XVECEXP (code_exp, 0, j) = condexps[i];
5003 XVECEXP (lats_exp, 0, j) = condexps[i];
5005 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
5006 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5009 name = XNEWVEC (char,
5010 sizeof ("*internal_dfa_insn_code_")
5011 + strlen (XSTR (val->value, 0)));
5012 strcpy (name, "*internal_dfa_insn_code_");
5013 strcat (name, XSTR (val->value, 0));
5014 make_internal_attr (name, code_exp, ATTR_NONE);
5015 strcpy (name, "*insn_default_latency_");
5016 strcat (name, XSTR (val->value, 0));
5017 make_internal_attr (name, lats_exp, ATTR_NONE);
5018 XDELETEVEC (name);
5020 if (first)
5022 fprintf (attr_file, " if (");
5023 first = false;
5025 else
5026 fprintf (attr_file, " else if (");
5027 write_test_expr (attr_file, test, 0, 0);
5028 fprintf (attr_file, ")\n");
5029 fprintf (attr_file, " {\n");
5030 fprintf (attr_file, " internal_dfa_insn_code\n");
5031 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
5032 XSTR (val->value, 0));
5033 fprintf (attr_file, " insn_default_latency\n");
5034 fprintf (attr_file, " = insn_default_latency_%s;\n",
5035 XSTR (val->value, 0));
5036 fprintf (attr_file, " }\n");
5039 fprintf (attr_file, " else\n");
5040 fprintf (attr_file, " gcc_unreachable ();\n");
5041 fprintf (attr_file, "}\n");
5042 fprintf (attr_file, "\n");
5044 XDELETEVEC (condexps);
5046 else
5048 code_exp = rtx_alloc (COND);
5049 lats_exp = rtx_alloc (COND);
5051 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5052 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5054 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5055 XEXP (lats_exp, 1) = make_numeric_value (0);
5057 for (decl = all_insn_reservs, i = 0;
5058 decl;
5059 decl = decl->next, i += 2)
5061 XVECEXP (code_exp, 0, i) = decl->condexp;
5062 XVECEXP (lats_exp, 0, i) = decl->condexp;
5064 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5065 XVECEXP (lats_exp, 0, i+1)
5066 = make_numeric_value (decl->default_latency);
5068 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5069 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
5072 if (n_bypasses == 0)
5073 byps_exp = make_numeric_value (0);
5074 else
5076 process_bypasses ();
5078 byps_exp = rtx_alloc (COND);
5079 XVEC (byps_exp, 0) = rtvec_alloc (n_bypasses * 2);
5080 XEXP (byps_exp, 1) = make_numeric_value (0);
5081 for (decl = all_insn_reservs, i = 0;
5082 decl;
5083 decl = decl->next)
5084 if (decl->bypassed)
5086 XVECEXP (byps_exp, 0, i) = decl->condexp;
5087 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5088 i += 2;
5092 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5095 static void
5096 write_header (FILE *outf)
5098 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5099 " from the machine description file `md'. */\n\n");
5101 fprintf (outf, "#include \"config.h\"\n");
5102 fprintf (outf, "#include \"system.h\"\n");
5103 fprintf (outf, "#include \"coretypes.h\"\n");
5104 fprintf (outf, "#include \"tm.h\"\n");
5105 fprintf (outf, "#include \"rtl.h\"\n");
5106 fprintf (outf, "#include \"insn-attr.h\"\n");
5107 fprintf (outf, "#include \"tm_p.h\"\n");
5108 fprintf (outf, "#include \"insn-config.h\"\n");
5109 fprintf (outf, "#include \"recog.h\"\n");
5110 fprintf (outf, "#include \"regs.h\"\n");
5111 fprintf (outf, "#include \"real.h\"\n");
5112 fprintf (outf, "#include \"output.h\"\n");
5113 fprintf (outf, "#include \"toplev.h\"\n");
5114 fprintf (outf, "#include \"flags.h\"\n");
5115 fprintf (outf, "#include \"function.h\"\n");
5116 fprintf (outf, "\n");
5117 fprintf (outf, "#define operands recog_data.operand\n\n");
5120 static FILE *
5121 open_outfile (const char *file_name)
5123 FILE *outf;
5124 outf = fopen (file_name, "w");
5125 if (! outf)
5126 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5127 write_header (outf);
5128 return outf;
5131 static bool
5132 handle_arg (const char *arg)
5134 switch (arg[1])
5136 case 'A':
5137 attr_file_name = &arg[2];
5138 return true;
5139 case 'D':
5140 dfa_file_name = &arg[2];
5141 return true;
5142 case 'L':
5143 latency_file_name = &arg[2];
5144 return true;
5145 default:
5146 return false;
5151 main (int argc, char **argv)
5153 rtx desc;
5154 struct attr_desc *attr;
5155 struct insn_def *id;
5156 rtx tem;
5157 int i;
5159 progname = "genattrtab";
5161 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5162 return FATAL_EXIT_CODE;
5164 attr_file = open_outfile (attr_file_name);
5165 dfa_file = open_outfile (dfa_file_name);
5166 latency_file = open_outfile (latency_file_name);
5168 obstack_init (hash_obstack);
5169 obstack_init (temp_obstack);
5171 /* Set up true and false rtx's */
5172 true_rtx = rtx_alloc (CONST_INT);
5173 XWINT (true_rtx, 0) = 1;
5174 false_rtx = rtx_alloc (CONST_INT);
5175 XWINT (false_rtx, 0) = 0;
5176 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5177 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5179 alternative_name = DEF_ATTR_STRING ("alternative");
5180 length_str = DEF_ATTR_STRING ("length");
5181 delay_type_str = DEF_ATTR_STRING ("*delay_type");
5182 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5183 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5185 /* Read the machine description. */
5187 while (1)
5189 int lineno;
5191 desc = read_md_rtx (&lineno, &insn_code_number);
5192 if (desc == NULL)
5193 break;
5195 switch (GET_CODE (desc))
5197 case DEFINE_INSN:
5198 case DEFINE_PEEPHOLE:
5199 case DEFINE_ASM_ATTRIBUTES:
5200 gen_insn (desc, lineno);
5201 break;
5203 case DEFINE_ATTR:
5204 case DEFINE_ENUM_ATTR:
5205 gen_attr (desc, lineno);
5206 break;
5208 case DEFINE_DELAY:
5209 gen_delay (desc, lineno);
5210 break;
5212 case DEFINE_INSN_RESERVATION:
5213 gen_insn_reserv (desc);
5214 break;
5216 case DEFINE_BYPASS:
5217 gen_bypass (desc);
5218 break;
5220 default:
5221 break;
5223 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
5224 insn_index_number++;
5227 if (have_error)
5228 return FATAL_EXIT_CODE;
5230 insn_code_number++;
5232 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5233 if (! got_define_asm_attributes)
5235 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5236 XVEC (tem, 0) = rtvec_alloc (0);
5237 gen_insn (tem, 0);
5240 /* Expand DEFINE_DELAY information into new attribute. */
5241 if (num_delays)
5242 expand_delays ();
5244 /* Make `insn_alternatives'. */
5245 insn_alternatives = oballocvec (int, insn_code_number);
5246 for (id = defs; id; id = id->next)
5247 if (id->insn_code >= 0)
5248 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
5250 /* Make `insn_n_alternatives'. */
5251 insn_n_alternatives = oballocvec (int, insn_code_number);
5252 for (id = defs; id; id = id->next)
5253 if (id->insn_code >= 0)
5254 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5256 /* Construct extra attributes for automata. */
5257 make_automaton_attrs ();
5259 /* Prepare to write out attribute subroutines by checking everything stored
5260 away and building the attribute cases. */
5262 check_defs ();
5264 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5265 for (attr = attrs[i]; attr; attr = attr->next)
5266 attr->default_val->value
5267 = check_attr_value (attr->default_val->value, attr);
5269 if (have_error)
5270 return FATAL_EXIT_CODE;
5272 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5273 for (attr = attrs[i]; attr; attr = attr->next)
5274 fill_attr (attr);
5276 /* Construct extra attributes for `length'. */
5277 make_length_attrs ();
5279 /* Perform any possible optimizations to speed up compilation. */
5280 optimize_attrs ();
5282 /* Now write out all the `gen_attr_...' routines. Do these before the
5283 special routines so that they get defined before they are used. */
5285 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5286 for (attr = attrs[i]; attr; attr = attr->next)
5288 FILE *outf;
5290 #define IS_ATTR_GROUP(X) (!strncmp(attr->name,X,strlen(X)))
5291 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5292 outf = dfa_file;
5293 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5294 outf = latency_file;
5295 else
5296 outf = attr_file;
5297 #undef IS_ATTR_GROUP
5299 if (! attr->is_special && ! attr->is_const)
5300 write_attr_get (outf, attr);
5303 /* Write out delay eligibility information, if DEFINE_DELAY present.
5304 (The function to compute the number of delay slots will be written
5305 below.) */
5306 if (num_delays)
5308 write_eligible_delay (attr_file, "delay");
5309 if (have_annul_true)
5310 write_eligible_delay (attr_file, "annul_true");
5311 if (have_annul_false)
5312 write_eligible_delay (attr_file, "annul_false");
5315 /* Write out constant delay slot info. */
5316 write_const_num_delay_slots (attr_file);
5318 write_length_unit_log (attr_file);
5320 if (fclose (attr_file) != 0)
5321 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5322 if (fclose (dfa_file) != 0)
5323 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5324 if (fclose (latency_file) != 0)
5325 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5327 return SUCCESS_EXIT_CODE;