* cpplib.pot: Regenerate.
[official-gcc.git] / gcc / genattrtab.c
blob2a3ee33f3e6984f303c68be2fb657ddfd24c6fd0
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_INT:
678 case CONST_DOUBLE:
679 case CONST_VECTOR:
680 case SYMBOL_REF:
681 case MATCH_TEST:
682 case CODE_LABEL:
683 case PC:
684 case CC0:
685 return orig;
687 default:
688 break;
691 copy = rtx_alloc (code);
692 PUT_MODE (copy, GET_MODE (orig));
693 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
694 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
695 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
697 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
699 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
701 switch (*format_ptr++)
703 case 'e':
704 XEXP (copy, i) = XEXP (orig, i);
705 if (XEXP (orig, i) != NULL)
706 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
707 break;
709 case 'E':
710 case 'V':
711 XVEC (copy, i) = XVEC (orig, i);
712 if (XVEC (orig, i) != NULL)
714 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
715 for (j = 0; j < XVECLEN (copy, i); j++)
716 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
718 break;
720 case 'n':
721 case 'i':
722 XINT (copy, i) = XINT (orig, i);
723 break;
725 case 'w':
726 XWINT (copy, i) = XWINT (orig, i);
727 break;
729 case 's':
730 case 'S':
731 XSTR (copy, i) = XSTR (orig, i);
732 break;
734 default:
735 gcc_unreachable ();
738 return copy;
741 /* Given a test expression for an attribute, ensure it is validly formed.
742 IS_CONST indicates whether the expression is constant for each compiler
743 run (a constant expression may not test any particular insn).
745 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
746 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
747 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
749 Update the string address in EQ_ATTR expression to be the same used
750 in the attribute (or `alternative_name') to speed up subsequent
751 `find_attr' calls and eliminate most `strcmp' calls.
753 Return the new expression, if any. */
755 static rtx
756 check_attr_test (rtx exp, int is_const, int lineno)
758 struct attr_desc *attr;
759 struct attr_value *av;
760 const char *name_ptr, *p;
761 rtx orexp, newexp;
763 switch (GET_CODE (exp))
765 case EQ_ATTR:
766 /* Handle negation test. */
767 if (XSTR (exp, 1)[0] == '!')
768 return check_attr_test (attr_rtx (NOT,
769 attr_eq (XSTR (exp, 0),
770 &XSTR (exp, 1)[1])),
771 is_const, lineno);
773 else if (n_comma_elts (XSTR (exp, 1)) == 1)
775 attr = find_attr (&XSTR (exp, 0), 0);
776 if (attr == NULL)
778 if (! strcmp (XSTR (exp, 0), "alternative"))
779 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
780 else
781 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
784 if (is_const && ! attr->is_const)
785 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
786 XSTR (exp, 0));
788 /* Copy this just to make it permanent,
789 so expressions using it can be permanent too. */
790 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
792 /* It shouldn't be possible to simplify the value given to a
793 constant attribute, so don't expand this until it's time to
794 write the test expression. */
795 if (attr->is_const)
796 ATTR_IND_SIMPLIFIED_P (exp) = 1;
798 if (attr->is_numeric)
800 for (p = XSTR (exp, 1); *p; p++)
801 if (! ISDIGIT (*p))
802 fatal ("attribute `%s' takes only numeric values",
803 XSTR (exp, 0));
805 else
807 for (av = attr->first_value; av; av = av->next)
808 if (GET_CODE (av->value) == CONST_STRING
809 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
810 break;
812 if (av == NULL)
813 fatal ("unknown value `%s' for `%s' attribute",
814 XSTR (exp, 1), XSTR (exp, 0));
817 else
819 if (! strcmp (XSTR (exp, 0), "alternative"))
821 int set = 0;
823 name_ptr = XSTR (exp, 1);
824 while ((p = next_comma_elt (&name_ptr)) != NULL)
825 set |= 1 << atoi (p);
827 return mk_attr_alt (set);
829 else
831 /* Make an IOR tree of the possible values. */
832 orexp = false_rtx;
833 name_ptr = XSTR (exp, 1);
834 while ((p = next_comma_elt (&name_ptr)) != NULL)
836 newexp = attr_eq (XSTR (exp, 0), p);
837 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
840 return check_attr_test (orexp, is_const, lineno);
843 break;
845 case ATTR_FLAG:
846 break;
848 case CONST_INT:
849 /* Either TRUE or FALSE. */
850 if (XWINT (exp, 0))
851 return true_rtx;
852 else
853 return false_rtx;
855 case IOR:
856 case AND:
857 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
858 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
859 break;
861 case NOT:
862 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
863 break;
865 case MATCH_TEST:
866 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0));
867 ATTR_IND_SIMPLIFIED_P (exp) = 1;
868 break;
870 case MATCH_OPERAND:
871 if (is_const)
872 fatal ("RTL operator \"%s\" not valid in constant attribute test",
873 GET_RTX_NAME (GET_CODE (exp)));
874 /* These cases can't be simplified. */
875 ATTR_IND_SIMPLIFIED_P (exp) = 1;
876 break;
878 case LE: case LT: case GT: case GE:
879 case LEU: case LTU: case GTU: case GEU:
880 case NE: case EQ:
881 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
882 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
883 exp = attr_rtx (GET_CODE (exp),
884 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
885 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
886 /* These cases can't be simplified. */
887 ATTR_IND_SIMPLIFIED_P (exp) = 1;
888 break;
890 case SYMBOL_REF:
891 if (is_const)
893 /* These cases are valid for constant attributes, but can't be
894 simplified. */
895 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
896 ATTR_IND_SIMPLIFIED_P (exp) = 1;
897 break;
899 default:
900 fatal ("RTL operator \"%s\" not valid in attribute test",
901 GET_RTX_NAME (GET_CODE (exp)));
904 return exp;
907 /* Given an expression, ensure that it is validly formed and that all named
908 attribute values are valid for the given attribute. Issue a fatal error
909 if not. If no attribute is specified, assume a numeric attribute.
911 Return a perhaps modified replacement expression for the value. */
913 static rtx
914 check_attr_value (rtx exp, struct attr_desc *attr)
916 struct attr_value *av;
917 const char *p;
918 int i;
920 switch (GET_CODE (exp))
922 case CONST_INT:
923 if (attr && ! attr->is_numeric)
925 error_with_line (attr->lineno,
926 "CONST_INT not valid for non-numeric attribute %s",
927 attr->name);
928 break;
931 if (INTVAL (exp) < 0)
933 error_with_line (attr->lineno,
934 "negative numeric value specified for attribute %s",
935 attr->name);
936 break;
938 break;
940 case CONST_STRING:
941 if (! strcmp (XSTR (exp, 0), "*"))
942 break;
944 if (attr == 0 || attr->is_numeric)
946 p = XSTR (exp, 0);
947 for (; *p; p++)
948 if (! ISDIGIT (*p))
950 error_with_line (attr ? attr->lineno : 0,
951 "non-numeric value for numeric attribute %s",
952 attr ? attr->name : "internal");
953 break;
955 break;
958 for (av = attr->first_value; av; av = av->next)
959 if (GET_CODE (av->value) == CONST_STRING
960 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
961 break;
963 if (av == NULL)
964 error_with_line (attr->lineno,
965 "unknown value `%s' for `%s' attribute",
966 XSTR (exp, 0), attr ? attr->name : "internal");
967 break;
969 case IF_THEN_ELSE:
970 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
971 attr ? attr->is_const : 0,
972 attr ? attr->lineno : 0);
973 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
974 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
975 break;
977 case PLUS:
978 case MINUS:
979 case MULT:
980 case DIV:
981 case MOD:
982 if (attr && !attr->is_numeric)
984 error_with_line (attr->lineno,
985 "invalid operation `%s' for non-numeric"
986 " attribute value", GET_RTX_NAME (GET_CODE (exp)));
987 break;
989 /* Fall through. */
991 case IOR:
992 case AND:
993 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
994 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
995 break;
997 case FFS:
998 case CLZ:
999 case CTZ:
1000 case POPCOUNT:
1001 case PARITY:
1002 case BSWAP:
1003 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1004 break;
1006 case COND:
1007 if (XVECLEN (exp, 0) % 2 != 0)
1009 error_with_line (attr->lineno,
1010 "first operand of COND must have even length");
1011 break;
1014 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1016 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1017 attr ? attr->is_const : 0,
1018 attr ? attr->lineno : 0);
1019 XVECEXP (exp, 0, i + 1)
1020 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1023 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1024 break;
1026 case ATTR:
1028 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1029 if (attr2 == NULL)
1030 error_with_line (attr ? attr->lineno : 0,
1031 "unknown attribute `%s' in ATTR",
1032 XSTR (exp, 0));
1033 else if (attr && attr->is_const && ! attr2->is_const)
1034 error_with_line (attr->lineno,
1035 "non-constant attribute `%s' referenced from `%s'",
1036 XSTR (exp, 0), attr->name);
1037 else if (attr
1038 && attr->is_numeric != attr2->is_numeric)
1039 error_with_line (attr->lineno,
1040 "numeric attribute mismatch calling `%s' from `%s'",
1041 XSTR (exp, 0), attr->name);
1043 break;
1045 case SYMBOL_REF:
1046 /* A constant SYMBOL_REF is valid as a constant attribute test and
1047 is expanded later by make_canonical into a COND. In a non-constant
1048 attribute test, it is left be. */
1049 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1051 default:
1052 error_with_line (attr ? attr->lineno : 0,
1053 "invalid operation `%s' for attribute value",
1054 GET_RTX_NAME (GET_CODE (exp)));
1055 break;
1058 return exp;
1061 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1062 It becomes a COND with each test being (eq_attr "alternative" "n") */
1064 static rtx
1065 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1067 int num_alt = id->num_alternatives;
1068 rtx condexp;
1069 int i;
1071 if (XVECLEN (exp, 1) != num_alt)
1073 error_with_line (id->lineno,
1074 "bad number of entries in SET_ATTR_ALTERNATIVE");
1075 return NULL_RTX;
1078 /* Make a COND with all tests but the last. Select the last value via the
1079 default. */
1080 condexp = rtx_alloc (COND);
1081 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1083 for (i = 0; i < num_alt - 1; i++)
1085 const char *p;
1086 p = attr_numeral (i);
1088 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1089 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1092 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1094 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1097 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1098 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1100 static rtx
1101 convert_set_attr (rtx exp, struct insn_def *id)
1103 rtx newexp;
1104 const char *name_ptr;
1105 char *p;
1106 int n;
1108 /* See how many alternative specified. */
1109 n = n_comma_elts (XSTR (exp, 1));
1110 if (n == 1)
1111 return attr_rtx (SET,
1112 attr_rtx (ATTR, XSTR (exp, 0)),
1113 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1115 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1116 XSTR (newexp, 0) = XSTR (exp, 0);
1117 XVEC (newexp, 1) = rtvec_alloc (n);
1119 /* Process each comma-separated name. */
1120 name_ptr = XSTR (exp, 1);
1121 n = 0;
1122 while ((p = next_comma_elt (&name_ptr)) != NULL)
1123 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1125 return convert_set_attr_alternative (newexp, id);
1128 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1129 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1130 expressions. */
1132 static void
1133 check_defs (void)
1135 struct insn_def *id;
1136 struct attr_desc *attr;
1137 int i;
1138 rtx value;
1140 for (id = defs; id; id = id->next)
1142 if (XVEC (id->def, id->vec_idx) == NULL)
1143 continue;
1145 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1147 value = XVECEXP (id->def, id->vec_idx, i);
1148 switch (GET_CODE (value))
1150 case SET:
1151 if (GET_CODE (XEXP (value, 0)) != ATTR)
1153 error_with_line (id->lineno, "bad attribute set");
1154 value = NULL_RTX;
1156 break;
1158 case SET_ATTR_ALTERNATIVE:
1159 value = convert_set_attr_alternative (value, id);
1160 break;
1162 case SET_ATTR:
1163 value = convert_set_attr (value, id);
1164 break;
1166 default:
1167 error_with_line (id->lineno, "invalid attribute code %s",
1168 GET_RTX_NAME (GET_CODE (value)));
1169 value = NULL_RTX;
1171 if (value == NULL_RTX)
1172 continue;
1174 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1176 error_with_line (id->lineno, "unknown attribute %s",
1177 XSTR (XEXP (value, 0), 0));
1178 continue;
1181 XVECEXP (id->def, id->vec_idx, i) = value;
1182 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1187 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1188 expressions by converting them into a COND. This removes cases from this
1189 program. Also, replace an attribute value of "*" with the default attribute
1190 value. */
1192 static rtx
1193 make_canonical (struct attr_desc *attr, rtx exp)
1195 int i;
1196 rtx newexp;
1198 switch (GET_CODE (exp))
1200 case CONST_INT:
1201 exp = make_numeric_value (INTVAL (exp));
1202 break;
1204 case CONST_STRING:
1205 if (! strcmp (XSTR (exp, 0), "*"))
1207 if (attr == 0 || attr->default_val == 0)
1208 fatal ("(attr_value \"*\") used in invalid context");
1209 exp = attr->default_val->value;
1211 else
1212 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1214 break;
1216 case SYMBOL_REF:
1217 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1218 break;
1219 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1220 This makes the COND something that won't be considered an arbitrary
1221 expression by walk_attr_value. */
1222 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1223 exp = check_attr_value (exp, attr);
1224 break;
1226 case IF_THEN_ELSE:
1227 newexp = rtx_alloc (COND);
1228 XVEC (newexp, 0) = rtvec_alloc (2);
1229 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1230 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1232 XEXP (newexp, 1) = XEXP (exp, 2);
1234 exp = newexp;
1235 /* Fall through to COND case since this is now a COND. */
1237 case COND:
1239 int allsame = 1;
1240 rtx defval;
1242 /* First, check for degenerate COND. */
1243 if (XVECLEN (exp, 0) == 0)
1244 return make_canonical (attr, XEXP (exp, 1));
1245 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1247 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1249 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1250 XVECEXP (exp, 0, i + 1)
1251 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1252 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1253 allsame = 0;
1255 if (allsame)
1256 return defval;
1258 break;
1260 default:
1261 break;
1264 return exp;
1267 static rtx
1268 copy_boolean (rtx exp)
1270 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1271 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1272 copy_boolean (XEXP (exp, 1)));
1273 if (GET_CODE (exp) == MATCH_OPERAND)
1275 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1276 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1278 else if (GET_CODE (exp) == EQ_ATTR)
1280 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1281 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1284 return exp;
1287 /* Given a value and an attribute description, return a `struct attr_value *'
1288 that represents that value. This is either an existing structure, if the
1289 value has been previously encountered, or a newly-created structure.
1291 `insn_code' is the code of an insn whose attribute has the specified
1292 value (-2 if not processing an insn). We ensure that all insns for
1293 a given value have the same number of alternatives if the value checks
1294 alternatives. */
1296 static struct attr_value *
1297 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1299 struct attr_value *av;
1300 int num_alt = 0;
1302 value = make_canonical (attr, value);
1303 if (compares_alternatives_p (value))
1305 if (insn_code < 0 || insn_alternatives == NULL)
1306 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1307 else
1308 num_alt = insn_alternatives[insn_code];
1311 for (av = attr->first_value; av; av = av->next)
1312 if (rtx_equal_p (value, av->value)
1313 && (num_alt == 0 || av->first_insn == NULL
1314 || insn_alternatives[av->first_insn->def->insn_code]))
1315 return av;
1317 av = oballoc (struct attr_value);
1318 av->value = value;
1319 av->next = attr->first_value;
1320 attr->first_value = av;
1321 av->first_insn = NULL;
1322 av->num_insns = 0;
1323 av->has_asm_insn = 0;
1325 return av;
1328 /* After all DEFINE_DELAYs have been read in, create internal attributes
1329 to generate the required routines.
1331 First, we compute the number of delay slots for each insn (as a COND of
1332 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1333 delay type is specified, we compute a similar function giving the
1334 DEFINE_DELAY ordinal for each insn.
1336 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1337 tells whether a given insn can be in that delay slot.
1339 Normal attribute filling and optimization expands these to contain the
1340 information needed to handle delay slots. */
1342 static void
1343 expand_delays (void)
1345 struct delay_desc *delay;
1346 rtx condexp;
1347 rtx newexp;
1348 int i;
1349 char *p;
1351 /* First, generate data for `num_delay_slots' function. */
1353 condexp = rtx_alloc (COND);
1354 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1355 XEXP (condexp, 1) = make_numeric_value (0);
1357 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1359 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1360 XVECEXP (condexp, 0, i + 1)
1361 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1364 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1366 /* If more than one delay type, do the same for computing the delay type. */
1367 if (num_delays > 1)
1369 condexp = rtx_alloc (COND);
1370 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1371 XEXP (condexp, 1) = make_numeric_value (0);
1373 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1375 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1376 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1379 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1382 /* For each delay possibility and delay slot, compute an eligibility
1383 attribute for non-annulled insns and for each type of annulled (annul
1384 if true and annul if false). */
1385 for (delay = delays; delay; delay = delay->next)
1387 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1389 condexp = XVECEXP (delay->def, 1, i);
1390 if (condexp == 0)
1391 condexp = false_rtx;
1392 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1393 make_numeric_value (1), make_numeric_value (0));
1395 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1396 "*delay_%d_%d", delay->num, i / 3);
1397 make_internal_attr (p, newexp, ATTR_SPECIAL);
1399 if (have_annul_true)
1401 condexp = XVECEXP (delay->def, 1, i + 1);
1402 if (condexp == 0) condexp = false_rtx;
1403 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1404 make_numeric_value (1),
1405 make_numeric_value (0));
1406 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1407 "*annul_true_%d_%d", delay->num, i / 3);
1408 make_internal_attr (p, newexp, ATTR_SPECIAL);
1411 if (have_annul_false)
1413 condexp = XVECEXP (delay->def, 1, i + 2);
1414 if (condexp == 0) condexp = false_rtx;
1415 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1416 make_numeric_value (1),
1417 make_numeric_value (0));
1418 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1419 "*annul_false_%d_%d", delay->num, i / 3);
1420 make_internal_attr (p, newexp, ATTR_SPECIAL);
1426 /* Once all attributes and insns have been read and checked, we construct for
1427 each attribute value a list of all the insns that have that value for
1428 the attribute. */
1430 static void
1431 fill_attr (struct attr_desc *attr)
1433 struct attr_value *av;
1434 struct insn_ent *ie;
1435 struct insn_def *id;
1436 int i;
1437 rtx value;
1439 /* Don't fill constant attributes. The value is independent of
1440 any particular insn. */
1441 if (attr->is_const)
1442 return;
1444 for (id = defs; id; id = id->next)
1446 /* If no value is specified for this insn for this attribute, use the
1447 default. */
1448 value = NULL;
1449 if (XVEC (id->def, id->vec_idx))
1450 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1451 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1452 attr->name))
1453 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1455 if (value == NULL)
1456 av = attr->default_val;
1457 else
1458 av = get_attr_value (value, attr, id->insn_code);
1460 ie = oballoc (struct insn_ent);
1461 ie->def = id;
1462 insert_insn_ent (av, ie);
1466 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1467 test that checks relative positions of insns (uses MATCH_DUP or PC).
1468 If so, replace it with what is obtained by passing the expression to
1469 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1470 recursively on each value (including the default value). Otherwise,
1471 return the value returned by NO_ADDRESS_FN applied to EXP. */
1473 static rtx
1474 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1475 rtx (*address_fn) (rtx))
1477 int i;
1478 rtx newexp;
1480 if (GET_CODE (exp) == COND)
1482 /* See if any tests use addresses. */
1483 address_used = 0;
1484 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1485 walk_attr_value (XVECEXP (exp, 0, i));
1487 if (address_used)
1488 return (*address_fn) (exp);
1490 /* Make a new copy of this COND, replacing each element. */
1491 newexp = rtx_alloc (COND);
1492 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1493 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1495 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1496 XVECEXP (newexp, 0, i + 1)
1497 = substitute_address (XVECEXP (exp, 0, i + 1),
1498 no_address_fn, address_fn);
1501 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1502 no_address_fn, address_fn);
1504 return newexp;
1507 else if (GET_CODE (exp) == IF_THEN_ELSE)
1509 address_used = 0;
1510 walk_attr_value (XEXP (exp, 0));
1511 if (address_used)
1512 return (*address_fn) (exp);
1514 return attr_rtx (IF_THEN_ELSE,
1515 substitute_address (XEXP (exp, 0),
1516 no_address_fn, address_fn),
1517 substitute_address (XEXP (exp, 1),
1518 no_address_fn, address_fn),
1519 substitute_address (XEXP (exp, 2),
1520 no_address_fn, address_fn));
1523 return (*no_address_fn) (exp);
1526 /* Make new attributes from the `length' attribute. The following are made,
1527 each corresponding to a function called from `shorten_branches' or
1528 `get_attr_length':
1530 *insn_default_length This is the length of the insn to be returned
1531 by `get_attr_length' before `shorten_branches'
1532 has been called. In each case where the length
1533 depends on relative addresses, the largest
1534 possible is used. This routine is also used
1535 to compute the initial size of the insn.
1537 *insn_variable_length_p This returns 1 if the insn's length depends
1538 on relative addresses, zero otherwise.
1540 *insn_current_length This is only called when it is known that the
1541 insn has a variable length and returns the
1542 current length, based on relative addresses.
1545 static void
1546 make_length_attrs (void)
1548 static const char *new_names[] =
1550 "*insn_default_length",
1551 "*insn_min_length",
1552 "*insn_variable_length_p",
1553 "*insn_current_length"
1555 static rtx (*const no_address_fn[]) (rtx)
1556 = {identity_fn,identity_fn, zero_fn, zero_fn};
1557 static rtx (*const address_fn[]) (rtx)
1558 = {max_fn, min_fn, one_fn, identity_fn};
1559 size_t i;
1560 struct attr_desc *length_attr, *new_attr;
1561 struct attr_value *av, *new_av;
1562 struct insn_ent *ie, *new_ie;
1564 /* See if length attribute is defined. If so, it must be numeric. Make
1565 it special so we don't output anything for it. */
1566 length_attr = find_attr (&length_str, 0);
1567 if (length_attr == 0)
1568 return;
1570 if (! length_attr->is_numeric)
1571 fatal ("length attribute must be numeric");
1573 length_attr->is_const = 0;
1574 length_attr->is_special = 1;
1576 /* Make each new attribute, in turn. */
1577 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1579 make_internal_attr (new_names[i],
1580 substitute_address (length_attr->default_val->value,
1581 no_address_fn[i], address_fn[i]),
1582 ATTR_NONE);
1583 new_attr = find_attr (&new_names[i], 0);
1584 for (av = length_attr->first_value; av; av = av->next)
1585 for (ie = av->first_insn; ie; ie = ie->next)
1587 new_av = get_attr_value (substitute_address (av->value,
1588 no_address_fn[i],
1589 address_fn[i]),
1590 new_attr, ie->def->insn_code);
1591 new_ie = oballoc (struct insn_ent);
1592 new_ie->def = ie->def;
1593 insert_insn_ent (new_av, new_ie);
1598 /* Utility functions called from above routine. */
1600 static rtx
1601 identity_fn (rtx exp)
1603 return exp;
1606 static rtx
1607 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1609 return make_numeric_value (0);
1612 static rtx
1613 one_fn (rtx exp ATTRIBUTE_UNUSED)
1615 return make_numeric_value (1);
1618 static rtx
1619 max_fn (rtx exp)
1621 int unknown;
1622 return make_numeric_value (max_attr_value (exp, &unknown));
1625 static rtx
1626 min_fn (rtx exp)
1628 int unknown;
1629 return make_numeric_value (min_attr_value (exp, &unknown));
1632 static void
1633 write_length_unit_log (FILE *outf)
1635 struct attr_desc *length_attr = find_attr (&length_str, 0);
1636 struct attr_value *av;
1637 struct insn_ent *ie;
1638 unsigned int length_unit_log, length_or;
1639 int unknown = 0;
1641 if (length_attr == 0)
1642 return;
1643 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1644 for (av = length_attr->first_value; av; av = av->next)
1645 for (ie = av->first_insn; ie; ie = ie->next)
1646 length_or |= or_attr_value (av->value, &unknown);
1648 if (unknown)
1649 length_unit_log = 0;
1650 else
1652 length_or = ~length_or;
1653 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1654 length_unit_log++;
1656 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1659 /* Compute approximate cost of the expression. Used to decide whether
1660 expression is cheap enough for inline. */
1661 static int
1662 attr_rtx_cost (rtx x)
1664 int cost = 1;
1665 enum rtx_code code;
1666 if (!x)
1667 return 0;
1668 code = GET_CODE (x);
1669 switch (code)
1671 case MATCH_OPERAND:
1672 if (XSTR (x, 1)[0])
1673 return 10;
1674 else
1675 return 1;
1677 case EQ_ATTR_ALT:
1678 return 1;
1680 case EQ_ATTR:
1681 /* Alternatives don't result into function call. */
1682 if (!strcmp_check (XSTR (x, 0), alternative_name))
1683 return 1;
1684 else
1685 return 5;
1686 default:
1688 int i, j;
1689 const char *fmt = GET_RTX_FORMAT (code);
1690 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1692 switch (fmt[i])
1694 case 'V':
1695 case 'E':
1696 for (j = 0; j < XVECLEN (x, i); j++)
1697 cost += attr_rtx_cost (XVECEXP (x, i, j));
1698 break;
1699 case 'e':
1700 cost += attr_rtx_cost (XEXP (x, i));
1701 break;
1705 break;
1707 return cost;
1710 /* Take a COND expression and see if any of the conditions in it can be
1711 simplified. If any are known true or known false for the particular insn
1712 code, the COND can be further simplified.
1714 Also call ourselves on any COND operations that are values of this COND.
1716 We do not modify EXP; rather, we make and return a new rtx. */
1718 static rtx
1719 simplify_cond (rtx exp, int insn_code, int insn_index)
1721 int i, j;
1722 /* We store the desired contents here,
1723 then build a new expression if they don't match EXP. */
1724 rtx defval = XEXP (exp, 1);
1725 rtx new_defval = XEXP (exp, 1);
1726 int len = XVECLEN (exp, 0);
1727 rtx *tests = XNEWVEC (rtx, len);
1728 int allsame = 1;
1729 rtx ret;
1731 /* This lets us free all storage allocated below, if appropriate. */
1732 obstack_finish (rtl_obstack);
1734 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1736 /* See if default value needs simplification. */
1737 if (GET_CODE (defval) == COND)
1738 new_defval = simplify_cond (defval, insn_code, insn_index);
1740 /* Simplify the subexpressions, and see what tests we can get rid of. */
1742 for (i = 0; i < len; i += 2)
1744 rtx newtest, newval;
1746 /* Simplify this test. */
1747 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1748 tests[i] = newtest;
1750 newval = tests[i + 1];
1751 /* See if this value may need simplification. */
1752 if (GET_CODE (newval) == COND)
1753 newval = simplify_cond (newval, insn_code, insn_index);
1755 /* Look for ways to delete or combine this test. */
1756 if (newtest == true_rtx)
1758 /* If test is true, make this value the default
1759 and discard this + any following tests. */
1760 len = i;
1761 defval = tests[i + 1];
1762 new_defval = newval;
1765 else if (newtest == false_rtx)
1767 /* If test is false, discard it and its value. */
1768 for (j = i; j < len - 2; j++)
1769 tests[j] = tests[j + 2];
1770 i -= 2;
1771 len -= 2;
1774 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1776 /* If this value and the value for the prev test are the same,
1777 merge the tests. */
1779 tests[i - 2]
1780 = insert_right_side (IOR, tests[i - 2], newtest,
1781 insn_code, insn_index);
1783 /* Delete this test/value. */
1784 for (j = i; j < len - 2; j++)
1785 tests[j] = tests[j + 2];
1786 len -= 2;
1787 i -= 2;
1790 else
1791 tests[i + 1] = newval;
1794 /* If the last test in a COND has the same value
1795 as the default value, that test isn't needed. */
1797 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1798 len -= 2;
1800 /* See if we changed anything. */
1801 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1802 allsame = 0;
1803 else
1804 for (i = 0; i < len; i++)
1805 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1807 allsame = 0;
1808 break;
1811 if (len == 0)
1813 if (GET_CODE (defval) == COND)
1814 ret = simplify_cond (defval, insn_code, insn_index);
1815 else
1816 ret = defval;
1818 else if (allsame)
1819 ret = exp;
1820 else
1822 rtx newexp = rtx_alloc (COND);
1824 XVEC (newexp, 0) = rtvec_alloc (len);
1825 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1826 XEXP (newexp, 1) = new_defval;
1827 ret = newexp;
1829 free (tests);
1830 return ret;
1833 /* Remove an insn entry from an attribute value. */
1835 static void
1836 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1838 struct insn_ent *previe;
1840 if (av->first_insn == ie)
1841 av->first_insn = ie->next;
1842 else
1844 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1846 previe->next = ie->next;
1849 av->num_insns--;
1850 if (ie->def->insn_code == -1)
1851 av->has_asm_insn = 0;
1853 num_insn_ents--;
1856 /* Insert an insn entry in an attribute value list. */
1858 static void
1859 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1861 ie->next = av->first_insn;
1862 av->first_insn = ie;
1863 av->num_insns++;
1864 if (ie->def->insn_code == -1)
1865 av->has_asm_insn = 1;
1867 num_insn_ents++;
1870 /* This is a utility routine to take an expression that is a tree of either
1871 AND or IOR expressions and insert a new term. The new term will be
1872 inserted at the right side of the first node whose code does not match
1873 the root. A new node will be created with the root's code. Its left
1874 side will be the old right side and its right side will be the new
1875 term.
1877 If the `term' is itself a tree, all its leaves will be inserted. */
1879 static rtx
1880 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1882 rtx newexp;
1884 /* Avoid consing in some special cases. */
1885 if (code == AND && term == true_rtx)
1886 return exp;
1887 if (code == AND && term == false_rtx)
1888 return false_rtx;
1889 if (code == AND && exp == true_rtx)
1890 return term;
1891 if (code == AND && exp == false_rtx)
1892 return false_rtx;
1893 if (code == IOR && term == true_rtx)
1894 return true_rtx;
1895 if (code == IOR && term == false_rtx)
1896 return exp;
1897 if (code == IOR && exp == true_rtx)
1898 return true_rtx;
1899 if (code == IOR && exp == false_rtx)
1900 return term;
1901 if (attr_equal_p (exp, term))
1902 return exp;
1904 if (GET_CODE (term) == code)
1906 exp = insert_right_side (code, exp, XEXP (term, 0),
1907 insn_code, insn_index);
1908 exp = insert_right_side (code, exp, XEXP (term, 1),
1909 insn_code, insn_index);
1911 return exp;
1914 if (GET_CODE (exp) == code)
1916 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1917 term, insn_code, insn_index);
1918 if (new_rtx != XEXP (exp, 1))
1919 /* Make a copy of this expression and call recursively. */
1920 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1921 else
1922 newexp = exp;
1924 else
1926 /* Insert the new term. */
1927 newexp = attr_rtx (code, exp, term);
1930 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1933 /* If we have an expression which AND's a bunch of
1934 (not (eq_attrq "alternative" "n"))
1935 terms, we may have covered all or all but one of the possible alternatives.
1936 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1938 This routine is passed an expression and either AND or IOR. It returns a
1939 bitmask indicating which alternatives are mentioned within EXP. */
1941 static int
1942 compute_alternative_mask (rtx exp, enum rtx_code code)
1944 const char *string;
1945 if (GET_CODE (exp) == code)
1946 return compute_alternative_mask (XEXP (exp, 0), code)
1947 | compute_alternative_mask (XEXP (exp, 1), code);
1949 else if (code == AND && GET_CODE (exp) == NOT
1950 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1951 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1952 string = XSTR (XEXP (exp, 0), 1);
1954 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1955 && XSTR (exp, 0) == alternative_name)
1956 string = XSTR (exp, 1);
1958 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1960 if (code == AND && XINT (exp, 1))
1961 return XINT (exp, 0);
1963 if (code == IOR && !XINT (exp, 1))
1964 return XINT (exp, 0);
1966 return 0;
1968 else
1969 return 0;
1971 if (string[1] == 0)
1972 return 1 << (string[0] - '0');
1973 return 1 << atoi (string);
1976 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1977 attribute with the value represented by that bit. */
1979 static rtx
1980 make_alternative_compare (int mask)
1982 return mk_attr_alt (mask);
1985 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1986 of "attr" for this insn code. From that value, we can compute a test
1987 showing when the EQ_ATTR will be true. This routine performs that
1988 computation. If a test condition involves an address, we leave the EQ_ATTR
1989 intact because addresses are only valid for the `length' attribute.
1991 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1992 it refers. VALUE is the value of that attribute for the insn
1993 corresponding to INSN_CODE and INSN_INDEX. */
1995 static rtx
1996 evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
1997 int insn_code, int insn_index)
1999 rtx orexp, andexp;
2000 rtx right;
2001 rtx newexp;
2002 int i;
2004 while (GET_CODE (value) == ATTR)
2006 struct attr_value *av = NULL;
2008 attr = find_attr (&XSTR (value, 0), 0);
2010 if (insn_code_values)
2012 struct attr_value_list *iv;
2013 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2014 if (iv->attr == attr)
2016 av = iv->av;
2017 break;
2020 else
2022 struct insn_ent *ie;
2023 for (av = attr->first_value; av; av = av->next)
2024 for (ie = av->first_insn; ie; ie = ie->next)
2025 if (ie->def->insn_code == insn_code)
2026 goto got_av;
2028 if (av)
2030 got_av:
2031 value = av->value;
2035 switch (GET_CODE (value))
2037 case CONST_STRING:
2038 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
2039 newexp = true_rtx;
2040 else
2041 newexp = false_rtx;
2042 break;
2044 case SYMBOL_REF:
2046 const char *prefix;
2047 char *string, *p;
2049 gcc_assert (GET_CODE (exp) == EQ_ATTR);
2050 prefix = attr->enum_name ? attr->enum_name : attr->name;
2051 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
2052 for (p = string; *p; p++)
2053 *p = TOUPPER (*p);
2055 newexp = attr_rtx (EQ, value,
2056 attr_rtx (SYMBOL_REF,
2057 DEF_ATTR_STRING (string)));
2058 break;
2061 case COND:
2062 /* We construct an IOR of all the cases for which the
2063 requested attribute value is present. Since we start with
2064 FALSE, if it is not present, FALSE will be returned.
2066 Each case is the AND of the NOT's of the previous conditions with the
2067 current condition; in the default case the current condition is TRUE.
2069 For each possible COND value, call ourselves recursively.
2071 The extra TRUE and FALSE expressions will be eliminated by another
2072 call to the simplification routine. */
2074 orexp = false_rtx;
2075 andexp = true_rtx;
2077 for (i = 0; i < XVECLEN (value, 0); i += 2)
2079 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2080 insn_code, insn_index);
2082 right = insert_right_side (AND, andexp, this_cond,
2083 insn_code, insn_index);
2084 right = insert_right_side (AND, right,
2085 evaluate_eq_attr (exp, attr,
2086 XVECEXP (value, 0,
2087 i + 1),
2088 insn_code, insn_index),
2089 insn_code, insn_index);
2090 orexp = insert_right_side (IOR, orexp, right,
2091 insn_code, insn_index);
2093 /* Add this condition into the AND expression. */
2094 newexp = attr_rtx (NOT, this_cond);
2095 andexp = insert_right_side (AND, andexp, newexp,
2096 insn_code, insn_index);
2099 /* Handle the default case. */
2100 right = insert_right_side (AND, andexp,
2101 evaluate_eq_attr (exp, attr, XEXP (value, 1),
2102 insn_code, insn_index),
2103 insn_code, insn_index);
2104 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2105 break;
2107 default:
2108 gcc_unreachable ();
2111 /* If uses an address, must return original expression. But set the
2112 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2114 address_used = 0;
2115 walk_attr_value (newexp);
2117 if (address_used)
2119 if (! ATTR_IND_SIMPLIFIED_P (exp))
2120 return copy_rtx_unchanging (exp);
2121 return exp;
2123 else
2124 return newexp;
2127 /* This routine is called when an AND of a term with a tree of AND's is
2128 encountered. If the term or its complement is present in the tree, it
2129 can be replaced with TRUE or FALSE, respectively.
2131 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2132 be true and hence are complementary.
2134 There is one special case: If we see
2135 (and (not (eq_attr "att" "v1"))
2136 (eq_attr "att" "v2"))
2137 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2138 replace the term, not anything in the AND tree. So we pass a pointer to
2139 the term. */
2141 static rtx
2142 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2144 rtx left, right;
2145 rtx newexp;
2146 rtx temp;
2147 int left_eliminates_term, right_eliminates_term;
2149 if (GET_CODE (exp) == AND)
2151 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2152 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2153 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2155 newexp = attr_rtx (AND, left, right);
2157 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2161 else if (GET_CODE (exp) == IOR)
2163 /* For the IOR case, we do the same as above, except that we can
2164 only eliminate `term' if both sides of the IOR would do so. */
2165 temp = *pterm;
2166 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2167 left_eliminates_term = (temp == true_rtx);
2169 temp = *pterm;
2170 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2171 right_eliminates_term = (temp == true_rtx);
2173 if (left_eliminates_term && right_eliminates_term)
2174 *pterm = true_rtx;
2176 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2178 newexp = attr_rtx (IOR, left, right);
2180 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2184 /* Check for simplifications. Do some extra checking here since this
2185 routine is called so many times. */
2187 if (exp == *pterm)
2188 return true_rtx;
2190 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2191 return false_rtx;
2193 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2194 return false_rtx;
2196 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2198 if (attr_alt_subset_p (*pterm, exp))
2199 return true_rtx;
2201 if (attr_alt_subset_of_compl_p (*pterm, exp))
2202 return false_rtx;
2204 if (attr_alt_subset_p (exp, *pterm))
2205 *pterm = true_rtx;
2207 return exp;
2210 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2212 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2213 return exp;
2215 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2216 return true_rtx;
2217 else
2218 return false_rtx;
2221 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2222 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2224 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2225 return exp;
2227 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2228 return false_rtx;
2229 else
2230 return true_rtx;
2233 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2234 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2236 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2237 return exp;
2239 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2240 return false_rtx;
2241 else
2242 *pterm = true_rtx;
2245 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2247 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2248 return true_rtx;
2251 else if (GET_CODE (exp) == NOT)
2253 if (attr_equal_p (XEXP (exp, 0), *pterm))
2254 return false_rtx;
2257 else if (GET_CODE (*pterm) == NOT)
2259 if (attr_equal_p (XEXP (*pterm, 0), exp))
2260 return false_rtx;
2263 else if (attr_equal_p (exp, *pterm))
2264 return true_rtx;
2266 return exp;
2269 /* Similar to `simplify_and_tree', but for IOR trees. */
2271 static rtx
2272 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2274 rtx left, right;
2275 rtx newexp;
2276 rtx temp;
2277 int left_eliminates_term, right_eliminates_term;
2279 if (GET_CODE (exp) == IOR)
2281 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2282 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2283 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2285 newexp = attr_rtx (GET_CODE (exp), left, right);
2287 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2291 else if (GET_CODE (exp) == AND)
2293 /* For the AND case, we do the same as above, except that we can
2294 only eliminate `term' if both sides of the AND would do so. */
2295 temp = *pterm;
2296 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2297 left_eliminates_term = (temp == false_rtx);
2299 temp = *pterm;
2300 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2301 right_eliminates_term = (temp == false_rtx);
2303 if (left_eliminates_term && right_eliminates_term)
2304 *pterm = false_rtx;
2306 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2308 newexp = attr_rtx (GET_CODE (exp), left, right);
2310 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2314 if (attr_equal_p (exp, *pterm))
2315 return false_rtx;
2317 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2318 return true_rtx;
2320 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2321 return true_rtx;
2323 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2324 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2325 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2326 *pterm = false_rtx;
2328 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2329 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2330 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2331 return false_rtx;
2333 return exp;
2336 /* Simplify test expression and use temporary obstack in order to avoid
2337 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2338 and avoid unnecessary copying if possible. */
2340 static rtx
2341 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2343 rtx x;
2344 struct obstack *old;
2345 if (ATTR_IND_SIMPLIFIED_P (exp))
2346 return exp;
2347 old = rtl_obstack;
2348 rtl_obstack = temp_obstack;
2349 x = simplify_test_exp (exp, insn_code, insn_index);
2350 rtl_obstack = old;
2351 if (x == exp || rtl_obstack == temp_obstack)
2352 return x;
2353 return attr_copy_rtx (x);
2356 /* Returns true if S1 is a subset of S2. */
2358 static bool
2359 attr_alt_subset_p (rtx s1, rtx s2)
2361 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2363 case (0 << 1) | 0:
2364 return !(XINT (s1, 0) &~ XINT (s2, 0));
2366 case (0 << 1) | 1:
2367 return !(XINT (s1, 0) & XINT (s2, 0));
2369 case (1 << 1) | 0:
2370 return false;
2372 case (1 << 1) | 1:
2373 return !(XINT (s2, 0) &~ XINT (s1, 0));
2375 default:
2376 gcc_unreachable ();
2380 /* Returns true if S1 is a subset of complement of S2. */
2382 static bool
2383 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2385 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2387 case (0 << 1) | 0:
2388 return !(XINT (s1, 0) & XINT (s2, 0));
2390 case (0 << 1) | 1:
2391 return !(XINT (s1, 0) & ~XINT (s2, 0));
2393 case (1 << 1) | 0:
2394 return !(XINT (s2, 0) &~ XINT (s1, 0));
2396 case (1 << 1) | 1:
2397 return false;
2399 default:
2400 gcc_unreachable ();
2404 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2406 static rtx
2407 attr_alt_intersection (rtx s1, rtx s2)
2409 rtx result = rtx_alloc (EQ_ATTR_ALT);
2411 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2413 case (0 << 1) | 0:
2414 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2415 break;
2416 case (0 << 1) | 1:
2417 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2418 break;
2419 case (1 << 1) | 0:
2420 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2421 break;
2422 case (1 << 1) | 1:
2423 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2424 break;
2425 default:
2426 gcc_unreachable ();
2428 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2430 return result;
2433 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2435 static rtx
2436 attr_alt_union (rtx s1, rtx s2)
2438 rtx result = rtx_alloc (EQ_ATTR_ALT);
2440 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2442 case (0 << 1) | 0:
2443 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2444 break;
2445 case (0 << 1) | 1:
2446 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2447 break;
2448 case (1 << 1) | 0:
2449 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2450 break;
2451 case (1 << 1) | 1:
2452 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2453 break;
2454 default:
2455 gcc_unreachable ();
2458 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2459 return result;
2462 /* Return EQ_ATTR_ALT expression representing complement of S. */
2464 static rtx
2465 attr_alt_complement (rtx s)
2467 rtx result = rtx_alloc (EQ_ATTR_ALT);
2469 XINT (result, 0) = XINT (s, 0);
2470 XINT (result, 1) = 1 - XINT (s, 1);
2472 return result;
2475 /* Return EQ_ATTR_ALT expression representing set containing elements set
2476 in E. */
2478 static rtx
2479 mk_attr_alt (int e)
2481 rtx result = rtx_alloc (EQ_ATTR_ALT);
2483 XINT (result, 0) = e;
2484 XINT (result, 1) = 0;
2486 return result;
2489 /* Given an expression, see if it can be simplified for a particular insn
2490 code based on the values of other attributes being tested. This can
2491 eliminate nested get_attr_... calls.
2493 Note that if an endless recursion is specified in the patterns, the
2494 optimization will loop. However, it will do so in precisely the cases where
2495 an infinite recursion loop could occur during compilation. It's better that
2496 it occurs here! */
2498 static rtx
2499 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2501 rtx left, right;
2502 struct attr_desc *attr;
2503 struct attr_value *av;
2504 struct insn_ent *ie;
2505 struct attr_value_list *iv;
2506 int i;
2507 rtx newexp = exp;
2508 bool left_alt, right_alt;
2510 /* Don't re-simplify something we already simplified. */
2511 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2512 return exp;
2514 switch (GET_CODE (exp))
2516 case AND:
2517 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2518 if (left == false_rtx)
2519 return false_rtx;
2520 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2521 if (right == false_rtx)
2522 return false_rtx;
2524 if (GET_CODE (left) == EQ_ATTR_ALT
2525 && GET_CODE (right) == EQ_ATTR_ALT)
2527 exp = attr_alt_intersection (left, right);
2528 return simplify_test_exp (exp, insn_code, insn_index);
2531 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2532 present on both sides, apply the distributive law since this will
2533 yield simplifications. */
2534 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2535 && compute_alternative_mask (left, IOR)
2536 && compute_alternative_mask (right, IOR))
2538 if (GET_CODE (left) == IOR)
2540 rtx tem = left;
2541 left = right;
2542 right = tem;
2545 newexp = attr_rtx (IOR,
2546 attr_rtx (AND, left, XEXP (right, 0)),
2547 attr_rtx (AND, left, XEXP (right, 1)));
2549 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2552 /* Try with the term on both sides. */
2553 right = simplify_and_tree (right, &left, insn_code, insn_index);
2554 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2555 left = simplify_and_tree (left, &right, insn_code, insn_index);
2557 if (left == false_rtx || right == false_rtx)
2558 return false_rtx;
2559 else if (left == true_rtx)
2561 return right;
2563 else if (right == true_rtx)
2565 return left;
2567 /* See if all or all but one of the insn's alternatives are specified
2568 in this tree. Optimize if so. */
2570 if (GET_CODE (left) == NOT)
2571 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2572 && XSTR (XEXP (left, 0), 0) == alternative_name);
2573 else
2574 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2575 && XINT (left, 1));
2577 if (GET_CODE (right) == NOT)
2578 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2579 && XSTR (XEXP (right, 0), 0) == alternative_name);
2580 else
2581 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2582 && XINT (right, 1));
2584 if (insn_code >= 0
2585 && (GET_CODE (left) == AND
2586 || left_alt
2587 || GET_CODE (right) == AND
2588 || right_alt))
2590 i = compute_alternative_mask (exp, AND);
2591 if (i & ~insn_alternatives[insn_code])
2592 fatal ("invalid alternative specified for pattern number %d",
2593 insn_index);
2595 /* If all alternatives are excluded, this is false. */
2596 i ^= insn_alternatives[insn_code];
2597 if (i == 0)
2598 return false_rtx;
2599 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2601 /* If just one excluded, AND a comparison with that one to the
2602 front of the tree. The others will be eliminated by
2603 optimization. We do not want to do this if the insn has one
2604 alternative and we have tested none of them! */
2605 left = make_alternative_compare (i);
2606 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2607 newexp = attr_rtx (AND, left, right);
2609 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2613 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2615 newexp = attr_rtx (AND, left, right);
2616 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2618 break;
2620 case IOR:
2621 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2622 if (left == true_rtx)
2623 return true_rtx;
2624 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2625 if (right == true_rtx)
2626 return true_rtx;
2628 if (GET_CODE (left) == EQ_ATTR_ALT
2629 && GET_CODE (right) == EQ_ATTR_ALT)
2631 exp = attr_alt_union (left, right);
2632 return simplify_test_exp (exp, insn_code, insn_index);
2635 right = simplify_or_tree (right, &left, insn_code, insn_index);
2636 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2637 left = simplify_or_tree (left, &right, insn_code, insn_index);
2639 if (right == true_rtx || left == true_rtx)
2640 return true_rtx;
2641 else if (left == false_rtx)
2643 return right;
2645 else if (right == false_rtx)
2647 return left;
2650 /* Test for simple cases where the distributive law is useful. I.e.,
2651 convert (ior (and (x) (y))
2652 (and (x) (z)))
2653 to (and (x)
2654 (ior (y) (z)))
2657 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2658 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2660 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2662 left = XEXP (left, 0);
2663 right = newexp;
2664 newexp = attr_rtx (AND, left, right);
2665 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2668 /* Similarly,
2669 convert (ior (and (y) (x))
2670 (and (z) (x)))
2671 to (and (ior (y) (z))
2672 (x))
2673 Note that we want the common term to stay at the end.
2676 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2677 && attr_equal_p (XEXP (left, 1), XEXP (right, 1)))
2679 newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0));
2681 left = newexp;
2682 right = XEXP (right, 1);
2683 newexp = attr_rtx (AND, left, right);
2684 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2687 /* See if all or all but one of the insn's alternatives are specified
2688 in this tree. Optimize if so. */
2690 else if (insn_code >= 0
2691 && (GET_CODE (left) == IOR
2692 || (GET_CODE (left) == EQ_ATTR_ALT
2693 && !XINT (left, 1))
2694 || (GET_CODE (left) == EQ_ATTR
2695 && XSTR (left, 0) == alternative_name)
2696 || GET_CODE (right) == IOR
2697 || (GET_CODE (right) == EQ_ATTR_ALT
2698 && !XINT (right, 1))
2699 || (GET_CODE (right) == EQ_ATTR
2700 && XSTR (right, 0) == alternative_name)))
2702 i = compute_alternative_mask (exp, IOR);
2703 if (i & ~insn_alternatives[insn_code])
2704 fatal ("invalid alternative specified for pattern number %d",
2705 insn_index);
2707 /* If all alternatives are included, this is true. */
2708 i ^= insn_alternatives[insn_code];
2709 if (i == 0)
2710 return true_rtx;
2711 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2713 /* If just one excluded, IOR a comparison with that one to the
2714 front of the tree. The others will be eliminated by
2715 optimization. We do not want to do this if the insn has one
2716 alternative and we have tested none of them! */
2717 left = make_alternative_compare (i);
2718 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2719 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2721 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2725 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2727 newexp = attr_rtx (IOR, left, right);
2728 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2730 break;
2732 case NOT:
2733 if (GET_CODE (XEXP (exp, 0)) == NOT)
2735 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2736 insn_code, insn_index);
2737 return left;
2740 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2741 if (GET_CODE (left) == NOT)
2742 return XEXP (left, 0);
2744 if (left == false_rtx)
2745 return true_rtx;
2746 if (left == true_rtx)
2747 return false_rtx;
2749 if (GET_CODE (left) == EQ_ATTR_ALT)
2751 exp = attr_alt_complement (left);
2752 return simplify_test_exp (exp, insn_code, insn_index);
2755 /* Try to apply De`Morgan's laws. */
2756 if (GET_CODE (left) == IOR)
2758 newexp = attr_rtx (AND,
2759 attr_rtx (NOT, XEXP (left, 0)),
2760 attr_rtx (NOT, XEXP (left, 1)));
2762 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2764 else if (GET_CODE (left) == AND)
2766 newexp = attr_rtx (IOR,
2767 attr_rtx (NOT, XEXP (left, 0)),
2768 attr_rtx (NOT, XEXP (left, 1)));
2770 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2772 else if (left != XEXP (exp, 0))
2774 newexp = attr_rtx (NOT, left);
2776 break;
2778 case EQ_ATTR_ALT:
2779 if (!XINT (exp, 0))
2780 return XINT (exp, 1) ? true_rtx : false_rtx;
2781 break;
2783 case EQ_ATTR:
2784 if (XSTR (exp, 0) == alternative_name)
2786 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2787 break;
2790 /* Look at the value for this insn code in the specified attribute.
2791 We normally can replace this comparison with the condition that
2792 would give this insn the values being tested for. */
2793 if (insn_code >= 0
2794 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2796 rtx x;
2798 av = NULL;
2799 if (insn_code_values)
2801 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2802 if (iv->attr == attr)
2804 av = iv->av;
2805 break;
2808 else
2810 for (av = attr->first_value; av; av = av->next)
2811 for (ie = av->first_insn; ie; ie = ie->next)
2812 if (ie->def->insn_code == insn_code)
2813 goto got_av;
2816 if (av)
2818 got_av:
2819 x = evaluate_eq_attr (exp, attr, av->value,
2820 insn_code, insn_index);
2821 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2822 if (attr_rtx_cost(x) < 7)
2823 return x;
2826 break;
2828 default:
2829 break;
2832 /* We have already simplified this expression. Simplifying it again
2833 won't buy anything unless we weren't given a valid insn code
2834 to process (i.e., we are canonicalizing something.). */
2835 if (insn_code != -2
2836 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2837 return copy_rtx_unchanging (newexp);
2839 return newexp;
2842 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2843 otherwise return 0. */
2845 static int
2846 tests_attr_p (rtx p, struct attr_desc *attr)
2848 const char *fmt;
2849 int i, ie, j, je;
2851 if (GET_CODE (p) == EQ_ATTR)
2853 if (XSTR (p, 0) != attr->name)
2854 return 0;
2855 return 1;
2858 fmt = GET_RTX_FORMAT (GET_CODE (p));
2859 ie = GET_RTX_LENGTH (GET_CODE (p));
2860 for (i = 0; i < ie; i++)
2862 switch (*fmt++)
2864 case 'e':
2865 if (tests_attr_p (XEXP (p, i), attr))
2866 return 1;
2867 break;
2869 case 'E':
2870 je = XVECLEN (p, i);
2871 for (j = 0; j < je; ++j)
2872 if (tests_attr_p (XVECEXP (p, i, j), attr))
2873 return 1;
2874 break;
2878 return 0;
2881 /* Calculate a topological sorting of all attributes so that
2882 all attributes only depend on attributes in front of it.
2883 Place the result in *RET (which is a pointer to an array of
2884 attr_desc pointers), and return the size of that array. */
2886 static int
2887 get_attr_order (struct attr_desc ***ret)
2889 int i, j;
2890 int num = 0;
2891 struct attr_desc *attr;
2892 struct attr_desc **all, **sorted;
2893 char *handled;
2894 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2895 for (attr = attrs[i]; attr; attr = attr->next)
2896 num++;
2897 all = XNEWVEC (struct attr_desc *, num);
2898 sorted = XNEWVEC (struct attr_desc *, num);
2899 handled = XCNEWVEC (char, num);
2900 num = 0;
2901 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2902 for (attr = attrs[i]; attr; attr = attr->next)
2903 all[num++] = attr;
2905 j = 0;
2906 for (i = 0; i < num; i++)
2907 if (all[i]->is_const)
2908 handled[i] = 1, sorted[j++] = all[i];
2910 /* We have only few attributes hence we can live with the inner
2911 loop being O(n^2), unlike the normal fast variants of topological
2912 sorting. */
2913 while (j < num)
2915 for (i = 0; i < num; i++)
2916 if (!handled[i])
2918 /* Let's see if I depends on anything interesting. */
2919 int k;
2920 for (k = 0; k < num; k++)
2921 if (!handled[k])
2923 struct attr_value *av;
2924 for (av = all[i]->first_value; av; av = av->next)
2925 if (av->num_insns != 0)
2926 if (tests_attr_p (av->value, all[k]))
2927 break;
2929 if (av)
2930 /* Something in I depends on K. */
2931 break;
2933 if (k == num)
2935 /* Nothing in I depended on anything intersting, so
2936 it's done. */
2937 handled[i] = 1;
2938 sorted[j++] = all[i];
2943 if (DEBUG)
2944 for (j = 0; j < num; j++)
2946 struct attr_desc *attr2;
2947 struct attr_value *av;
2949 attr = sorted[j];
2950 fprintf (stderr, "%s depends on: ", attr->name);
2951 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
2952 for (attr2 = attrs[i]; attr2; attr2 = attr2->next)
2953 if (!attr2->is_const)
2954 for (av = attr->first_value; av; av = av->next)
2955 if (av->num_insns != 0)
2956 if (tests_attr_p (av->value, attr2))
2958 fprintf (stderr, "%s, ", attr2->name);
2959 break;
2961 fprintf (stderr, "\n");
2964 free (all);
2965 *ret = sorted;
2966 return num;
2969 /* Optimize the attribute lists by seeing if we can determine conditional
2970 values from the known values of other attributes. This will save subroutine
2971 calls during the compilation. */
2973 static void
2974 optimize_attrs (void)
2976 struct attr_desc *attr;
2977 struct attr_value *av;
2978 struct insn_ent *ie;
2979 rtx newexp;
2980 int i;
2981 struct attr_value_list *ivbuf;
2982 struct attr_value_list *iv;
2983 struct attr_desc **topsort;
2984 int topnum;
2986 /* For each insn code, make a list of all the insn_ent's for it,
2987 for all values for all attributes. */
2989 if (num_insn_ents == 0)
2990 return;
2992 /* Make 2 extra elements, for "code" values -2 and -1. */
2993 insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
2995 /* Offset the table address so we can index by -2 or -1. */
2996 insn_code_values += 2;
2998 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
3000 /* Create the chain of insn*attr values such that we see dependend
3001 attributes after their dependencies. As we use a stack via the
3002 next pointers start from the end of the topological order. */
3003 topnum = get_attr_order (&topsort);
3004 for (i = topnum - 1; i >= 0; i--)
3005 for (av = topsort[i]->first_value; av; av = av->next)
3006 for (ie = av->first_insn; ie; ie = ie->next)
3008 iv->attr = topsort[i];
3009 iv->av = av;
3010 iv->ie = ie;
3011 iv->next = insn_code_values[ie->def->insn_code];
3012 insn_code_values[ie->def->insn_code] = iv;
3013 iv++;
3015 free (topsort);
3017 /* Sanity check on num_insn_ents. */
3018 gcc_assert (iv == ivbuf + num_insn_ents);
3020 /* Process one insn code at a time. */
3021 for (i = -2; i < insn_code_number; i++)
3023 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3024 We use it to mean "already simplified for this insn". */
3025 for (iv = insn_code_values[i]; iv; iv = iv->next)
3026 clear_struct_flag (iv->av->value);
3028 for (iv = insn_code_values[i]; iv; iv = iv->next)
3030 struct obstack *old = rtl_obstack;
3032 attr = iv->attr;
3033 av = iv->av;
3034 ie = iv->ie;
3035 if (GET_CODE (av->value) != COND)
3036 continue;
3038 rtl_obstack = temp_obstack;
3039 newexp = av->value;
3040 while (GET_CODE (newexp) == COND)
3042 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
3043 ie->def->insn_index);
3044 if (newexp2 == newexp)
3045 break;
3046 newexp = newexp2;
3049 rtl_obstack = old;
3050 /* If we created a new value for this instruction, and it's
3051 cheaper than the old value, and overall cheap, use that
3052 one as specific value for the current instruction.
3053 The last test is to avoid exploding the get_attr_ function
3054 sizes for no much gain. */
3055 if (newexp != av->value
3056 && attr_rtx_cost (newexp) < attr_rtx_cost (av->value)
3057 && attr_rtx_cost (newexp) < 26
3060 newexp = attr_copy_rtx (newexp);
3061 remove_insn_ent (av, ie);
3062 av = get_attr_value (newexp, attr, ie->def->insn_code);
3063 iv->av = av;
3064 insert_insn_ent (av, ie);
3069 free (ivbuf);
3070 free (insn_code_values - 2);
3071 insn_code_values = NULL;
3074 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3076 static void
3077 clear_struct_flag (rtx x)
3079 int i;
3080 int j;
3081 enum rtx_code code;
3082 const char *fmt;
3084 ATTR_CURR_SIMPLIFIED_P (x) = 0;
3085 if (ATTR_IND_SIMPLIFIED_P (x))
3086 return;
3088 code = GET_CODE (x);
3090 switch (code)
3092 case REG:
3093 case CONST_INT:
3094 case CONST_DOUBLE:
3095 case CONST_VECTOR:
3096 case MATCH_TEST:
3097 case SYMBOL_REF:
3098 case CODE_LABEL:
3099 case PC:
3100 case CC0:
3101 case EQ_ATTR:
3102 case ATTR_FLAG:
3103 return;
3105 default:
3106 break;
3109 /* Compare the elements. If any pair of corresponding elements
3110 fail to match, return 0 for the whole things. */
3112 fmt = GET_RTX_FORMAT (code);
3113 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3115 switch (fmt[i])
3117 case 'V':
3118 case 'E':
3119 for (j = 0; j < XVECLEN (x, i); j++)
3120 clear_struct_flag (XVECEXP (x, i, j));
3121 break;
3123 case 'e':
3124 clear_struct_flag (XEXP (x, i));
3125 break;
3130 /* Add attribute value NAME to the beginning of ATTR's list. */
3132 static void
3133 add_attr_value (struct attr_desc *attr, const char *name)
3135 struct attr_value *av;
3137 av = oballoc (struct attr_value);
3138 av->value = attr_rtx (CONST_STRING, name);
3139 av->next = attr->first_value;
3140 attr->first_value = av;
3141 av->first_insn = NULL;
3142 av->num_insns = 0;
3143 av->has_asm_insn = 0;
3146 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3148 static void
3149 gen_attr (rtx exp, int lineno)
3151 struct enum_type *et;
3152 struct enum_value *ev;
3153 struct attr_desc *attr;
3154 const char *name_ptr;
3155 char *p;
3157 /* Make a new attribute structure. Check for duplicate by looking at
3158 attr->default_val, since it is initialized by this routine. */
3159 attr = find_attr (&XSTR (exp, 0), 1);
3160 if (attr->default_val)
3162 error_with_line (lineno, "duplicate definition for attribute %s",
3163 attr->name);
3164 message_with_line (attr->lineno, "previous definition");
3165 return;
3167 attr->lineno = lineno;
3169 if (GET_CODE (exp) == DEFINE_ENUM_ATTR)
3171 attr->enum_name = XSTR (exp, 1);
3172 et = lookup_enum_type (XSTR (exp, 1));
3173 if (!et || !et->md_p)
3174 error_with_line (lineno, "No define_enum called `%s' defined",
3175 attr->name);
3176 if (et)
3177 for (ev = et->values; ev; ev = ev->next)
3178 add_attr_value (attr, ev->name);
3180 else if (*XSTR (exp, 1) == '\0')
3181 attr->is_numeric = 1;
3182 else
3184 name_ptr = XSTR (exp, 1);
3185 while ((p = next_comma_elt (&name_ptr)) != NULL)
3186 add_attr_value (attr, p);
3189 if (GET_CODE (XEXP (exp, 2)) == CONST)
3191 attr->is_const = 1;
3192 if (attr->is_numeric)
3193 error_with_line (lineno,
3194 "constant attributes may not take numeric values");
3196 /* Get rid of the CONST node. It is allowed only at top-level. */
3197 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3200 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3201 error_with_line (lineno, "`length' attribute must take numeric values");
3203 /* Set up the default value. */
3204 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3205 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3208 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3209 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3210 number of alternatives as this should be checked elsewhere. */
3212 static int
3213 count_alternatives (rtx exp)
3215 int i, j, n;
3216 const char *fmt;
3218 if (GET_CODE (exp) == MATCH_OPERAND)
3219 return n_comma_elts (XSTR (exp, 2));
3221 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3222 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3223 switch (*fmt++)
3225 case 'e':
3226 case 'u':
3227 n = count_alternatives (XEXP (exp, i));
3228 if (n)
3229 return n;
3230 break;
3232 case 'E':
3233 case 'V':
3234 if (XVEC (exp, i) != NULL)
3235 for (j = 0; j < XVECLEN (exp, i); j++)
3237 n = count_alternatives (XVECEXP (exp, i, j));
3238 if (n)
3239 return n;
3243 return 0;
3246 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3247 `alternative' attribute. */
3249 static int
3250 compares_alternatives_p (rtx exp)
3252 int i, j;
3253 const char *fmt;
3255 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3256 return 1;
3258 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3259 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3260 switch (*fmt++)
3262 case 'e':
3263 case 'u':
3264 if (compares_alternatives_p (XEXP (exp, i)))
3265 return 1;
3266 break;
3268 case 'E':
3269 for (j = 0; j < XVECLEN (exp, i); j++)
3270 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3271 return 1;
3272 break;
3275 return 0;
3278 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3280 static void
3281 gen_insn (rtx exp, int lineno)
3283 struct insn_def *id;
3285 id = oballoc (struct insn_def);
3286 id->next = defs;
3287 defs = id;
3288 id->def = exp;
3289 id->lineno = lineno;
3291 switch (GET_CODE (exp))
3293 case DEFINE_INSN:
3294 id->insn_code = insn_code_number;
3295 id->insn_index = insn_index_number;
3296 id->num_alternatives = count_alternatives (exp);
3297 if (id->num_alternatives == 0)
3298 id->num_alternatives = 1;
3299 id->vec_idx = 4;
3300 break;
3302 case DEFINE_PEEPHOLE:
3303 id->insn_code = insn_code_number;
3304 id->insn_index = insn_index_number;
3305 id->num_alternatives = count_alternatives (exp);
3306 if (id->num_alternatives == 0)
3307 id->num_alternatives = 1;
3308 id->vec_idx = 3;
3309 break;
3311 case DEFINE_ASM_ATTRIBUTES:
3312 id->insn_code = -1;
3313 id->insn_index = -1;
3314 id->num_alternatives = 1;
3315 id->vec_idx = 0;
3316 got_define_asm_attributes = 1;
3317 break;
3319 default:
3320 gcc_unreachable ();
3324 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3325 true or annul false is specified, and make a `struct delay_desc'. */
3327 static void
3328 gen_delay (rtx def, int lineno)
3330 struct delay_desc *delay;
3331 int i;
3333 if (XVECLEN (def, 1) % 3 != 0)
3335 error_with_line (lineno,
3336 "number of elements in DEFINE_DELAY must"
3337 " be multiple of three");
3338 return;
3341 for (i = 0; i < XVECLEN (def, 1); i += 3)
3343 if (XVECEXP (def, 1, i + 1))
3344 have_annul_true = 1;
3345 if (XVECEXP (def, 1, i + 2))
3346 have_annul_false = 1;
3349 delay = oballoc (struct delay_desc);
3350 delay->def = def;
3351 delay->num = ++num_delays;
3352 delay->next = delays;
3353 delay->lineno = lineno;
3354 delays = delay;
3357 /* Names of attributes that could be possibly cached. */
3358 static const char *cached_attrs[32];
3359 /* Number of such attributes. */
3360 static int cached_attr_count;
3361 /* Bitmasks of possibly cached attributes. */
3362 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3363 static unsigned int attrs_to_cache;
3364 static unsigned int attrs_cached_inside, attrs_cached_after;
3366 /* Finds non-const attributes that could be possibly cached.
3367 When create is TRUE, fills in cached_attrs array.
3368 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3369 bitmasks. */
3371 static void
3372 find_attrs_to_cache (rtx exp, bool create)
3374 int i;
3375 const char *name;
3376 struct attr_desc *attr;
3378 if (exp == NULL)
3379 return;
3381 switch (GET_CODE (exp))
3383 case NOT:
3384 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3385 find_attrs_to_cache (XEXP (exp, 0), create);
3386 return;
3388 case EQ_ATTR:
3389 name = XSTR (exp, 0);
3390 if (name == alternative_name)
3391 return;
3392 for (i = 0; i < cached_attr_count; i++)
3393 if (name == cached_attrs[i])
3395 if ((attrs_seen_once & (1U << i)) != 0)
3396 attrs_seen_more_than_once |= (1U << i);
3397 else
3398 attrs_seen_once |= (1U << i);
3399 return;
3401 if (!create)
3402 return;
3403 attr = find_attr (&name, 0);
3404 gcc_assert (attr);
3405 if (attr->is_const)
3406 return;
3407 if (cached_attr_count == 32)
3408 return;
3409 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3410 attrs_seen_once |= (1U << cached_attr_count);
3411 cached_attr_count++;
3412 return;
3414 case AND:
3415 case IOR:
3416 find_attrs_to_cache (XEXP (exp, 0), create);
3417 find_attrs_to_cache (XEXP (exp, 1), create);
3418 return;
3420 case COND:
3421 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3422 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3423 return;
3425 default:
3426 return;
3430 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3431 We use AND and IOR both for logical and bit-wise operations, so
3432 interpret them as logical unless they are inside a comparison expression. */
3434 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3435 #define FLG_BITWISE 1
3436 /* Set if cached attribute will be known initialized in else 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_AFTER 2
3440 /* Set if cached attribute will be known initialized in then block after
3441 this condition. This is true for LHS of toplevel && and || and
3442 even for RHS of &&, but not for RHS of ||. */
3443 #define FLG_INSIDE 4
3444 /* Cleared when an operand of &&. */
3445 #define FLG_OUTSIDE_AND 8
3447 static unsigned int
3448 write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags)
3450 int comparison_operator = 0;
3451 RTX_CODE code;
3452 struct attr_desc *attr;
3454 /* In order not to worry about operator precedence, surround our part of
3455 the expression with parentheses. */
3457 fprintf (outf, "(");
3458 code = GET_CODE (exp);
3459 switch (code)
3461 /* Binary operators. */
3462 case GEU: case GTU:
3463 case LEU: case LTU:
3464 fprintf (outf, "(unsigned) ");
3465 /* Fall through. */
3467 case EQ: case NE:
3468 case GE: case GT:
3469 case LE: case LT:
3470 comparison_operator = FLG_BITWISE;
3472 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3473 case AND: case IOR: case XOR:
3474 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3475 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3477 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3478 write_test_expr (outf, XEXP (exp, 0), attrs_cached,
3479 flags | comparison_operator);
3481 else
3483 if (code == AND)
3484 flags &= ~FLG_OUTSIDE_AND;
3485 if (GET_CODE (XEXP (exp, 0)) == code
3486 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3487 || (GET_CODE (XEXP (exp, 0)) == NOT
3488 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3489 attrs_cached
3490 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3491 else
3492 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3494 switch (code)
3496 case EQ:
3497 fprintf (outf, " == ");
3498 break;
3499 case NE:
3500 fprintf (outf, " != ");
3501 break;
3502 case GE:
3503 fprintf (outf, " >= ");
3504 break;
3505 case GT:
3506 fprintf (outf, " > ");
3507 break;
3508 case GEU:
3509 fprintf (outf, " >= (unsigned) ");
3510 break;
3511 case GTU:
3512 fprintf (outf, " > (unsigned) ");
3513 break;
3514 case LE:
3515 fprintf (outf, " <= ");
3516 break;
3517 case LT:
3518 fprintf (outf, " < ");
3519 break;
3520 case LEU:
3521 fprintf (outf, " <= (unsigned) ");
3522 break;
3523 case LTU:
3524 fprintf (outf, " < (unsigned) ");
3525 break;
3526 case PLUS:
3527 fprintf (outf, " + ");
3528 break;
3529 case MINUS:
3530 fprintf (outf, " - ");
3531 break;
3532 case MULT:
3533 fprintf (outf, " * ");
3534 break;
3535 case DIV:
3536 fprintf (outf, " / ");
3537 break;
3538 case MOD:
3539 fprintf (outf, " %% ");
3540 break;
3541 case AND:
3542 if (flags & FLG_BITWISE)
3543 fprintf (outf, " & ");
3544 else
3545 fprintf (outf, " && ");
3546 break;
3547 case IOR:
3548 if (flags & FLG_BITWISE)
3549 fprintf (outf, " | ");
3550 else
3551 fprintf (outf, " || ");
3552 break;
3553 case XOR:
3554 fprintf (outf, " ^ ");
3555 break;
3556 case ASHIFT:
3557 fprintf (outf, " << ");
3558 break;
3559 case LSHIFTRT:
3560 case ASHIFTRT:
3561 fprintf (outf, " >> ");
3562 break;
3563 default:
3564 gcc_unreachable ();
3567 if (code == AND)
3569 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3570 cached_x is only known to be initialized in then block. */
3571 flags &= ~FLG_AFTER;
3573 else if (code == IOR)
3575 if (flags & FLG_OUTSIDE_AND)
3576 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3577 cached_x is only known to be initialized in else block
3578 and else if conditions. */
3579 flags &= ~FLG_INSIDE;
3580 else
3581 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3582 && something_else)
3583 cached_x is not know to be initialized anywhere. */
3584 flags &= ~(FLG_AFTER | FLG_INSIDE);
3586 if ((code == AND || code == IOR)
3587 && (GET_CODE (XEXP (exp, 1)) == code
3588 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3589 || (GET_CODE (XEXP (exp, 1)) == NOT
3590 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3591 attrs_cached
3592 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags);
3593 else
3594 write_test_expr (outf, XEXP (exp, 1), attrs_cached,
3595 flags | comparison_operator);
3596 break;
3598 case NOT:
3599 /* Special-case (not (eq_attrq "alternative" "x")) */
3600 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3602 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3604 fprintf (outf, "which_alternative != %s",
3605 XSTR (XEXP (exp, 0), 1));
3606 break;
3609 fprintf (outf, "! ");
3610 attrs_cached =
3611 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3612 break;
3615 /* Otherwise, fall through to normal unary operator. */
3617 /* Unary operators. */
3618 case ABS: case NEG:
3619 switch (code)
3621 case NOT:
3622 if (flags & FLG_BITWISE)
3623 fprintf (outf, "~ ");
3624 else
3625 fprintf (outf, "! ");
3626 break;
3627 case ABS:
3628 fprintf (outf, "abs ");
3629 break;
3630 case NEG:
3631 fprintf (outf, "-");
3632 break;
3633 default:
3634 gcc_unreachable ();
3637 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3638 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags);
3639 break;
3641 case EQ_ATTR_ALT:
3643 int set = XINT (exp, 0), bit = 0;
3645 if (flags & FLG_BITWISE)
3646 fatal ("EQ_ATTR_ALT not valid inside comparison");
3648 if (!set)
3649 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3651 if (!(set & (set - 1)))
3653 if (!(set & 0xffff))
3655 bit += 16;
3656 set >>= 16;
3658 if (!(set & 0xff))
3660 bit += 8;
3661 set >>= 8;
3663 if (!(set & 0xf))
3665 bit += 4;
3666 set >>= 4;
3668 if (!(set & 0x3))
3670 bit += 2;
3671 set >>= 2;
3673 if (!(set & 1))
3674 bit++;
3676 fprintf (outf, "which_alternative %s= %d",
3677 XINT (exp, 1) ? "!" : "=", bit);
3679 else
3681 fprintf (outf, "%s((1 << which_alternative) & %#x)",
3682 XINT (exp, 1) ? "!" : "", set);
3685 break;
3687 /* Comparison test of an attribute with a value. Most of these will
3688 have been removed by optimization. Handle "alternative"
3689 specially and give error if EQ_ATTR present inside a comparison. */
3690 case EQ_ATTR:
3691 if (flags & FLG_BITWISE)
3692 fatal ("EQ_ATTR not valid inside comparison");
3694 if (XSTR (exp, 0) == alternative_name)
3696 fprintf (outf, "which_alternative == %s", XSTR (exp, 1));
3697 break;
3700 attr = find_attr (&XSTR (exp, 0), 0);
3701 gcc_assert (attr);
3703 /* Now is the time to expand the value of a constant attribute. */
3704 if (attr->is_const)
3706 write_test_expr (outf,
3707 evaluate_eq_attr (exp, attr,
3708 attr->default_val->value,
3709 -2, -2),
3710 attrs_cached, 0);
3712 else
3714 int i;
3715 for (i = 0; i < cached_attr_count; i++)
3716 if (attr->name == cached_attrs[i])
3717 break;
3718 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3719 fprintf (outf, "cached_%s", attr->name);
3720 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3722 fprintf (outf, "(cached_%s = get_attr_%s (insn))",
3723 attr->name, attr->name);
3724 if (flags & FLG_AFTER)
3725 attrs_cached_after |= (1U << i);
3726 if (flags & FLG_INSIDE)
3727 attrs_cached_inside |= (1U << i);
3728 attrs_cached |= (1U << i);
3730 else
3731 fprintf (outf, "get_attr_%s (insn)", attr->name);
3732 fprintf (outf, " == ");
3733 write_attr_valueq (outf, attr, XSTR (exp, 1));
3735 break;
3737 /* Comparison test of flags for define_delays. */
3738 case ATTR_FLAG:
3739 if (flags & FLG_BITWISE)
3740 fatal ("ATTR_FLAG not valid inside comparison");
3741 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3742 break;
3744 /* See if an operand matches a predicate. */
3745 case MATCH_OPERAND:
3746 /* If only a mode is given, just ensure the mode matches the operand.
3747 If neither a mode nor predicate is given, error. */
3748 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3750 if (GET_MODE (exp) == VOIDmode)
3751 fatal ("null MATCH_OPERAND specified as test");
3752 else
3753 fprintf (outf, "GET_MODE (operands[%d]) == %smode",
3754 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3756 else
3757 fprintf (outf, "%s (operands[%d], %smode)",
3758 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3759 break;
3761 /* Constant integer. */
3762 case CONST_INT:
3763 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3764 break;
3766 case MATCH_TEST:
3767 fprint_c_condition (outf, XSTR (exp, 0));
3768 if (flags & FLG_BITWISE)
3769 fprintf (outf, " != 0");
3770 break;
3772 /* A random C expression. */
3773 case SYMBOL_REF:
3774 fprint_c_condition (outf, XSTR (exp, 0));
3775 break;
3777 /* The address of the branch target. */
3778 case MATCH_DUP:
3779 fprintf (outf,
3780 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3781 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3782 break;
3784 case PC:
3785 /* The address of the current insn. We implement this actually as the
3786 address of the current insn for backward branches, but the last
3787 address of the next insn for forward branches, and both with
3788 adjustments that account for the worst-case possible stretching of
3789 intervening alignments between this insn and its destination. */
3790 fprintf (outf, "insn_current_reference_address (insn)");
3791 break;
3793 case CONST_STRING:
3794 fprintf (outf, "%s", XSTR (exp, 0));
3795 break;
3797 case IF_THEN_ELSE:
3798 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0);
3799 fprintf (outf, " ? ");
3800 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3801 fprintf (outf, " : ");
3802 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3803 break;
3805 default:
3806 fatal ("bad RTX code `%s' in attribute calculation\n",
3807 GET_RTX_NAME (code));
3810 fprintf (outf, ")");
3811 return attrs_cached;
3814 /* Given an attribute value, return the maximum CONST_STRING argument
3815 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3817 static int
3818 max_attr_value (rtx exp, int *unknownp)
3820 int current_max;
3821 int i, n;
3823 switch (GET_CODE (exp))
3825 case CONST_STRING:
3826 current_max = atoi (XSTR (exp, 0));
3827 break;
3829 case COND:
3830 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3831 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3833 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3834 if (n > current_max)
3835 current_max = n;
3837 break;
3839 case IF_THEN_ELSE:
3840 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3841 n = max_attr_value (XEXP (exp, 2), unknownp);
3842 if (n > current_max)
3843 current_max = n;
3844 break;
3846 default:
3847 *unknownp = 1;
3848 current_max = INT_MAX;
3849 break;
3852 return current_max;
3855 /* Given an attribute value, return the minimum CONST_STRING argument
3856 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3858 static int
3859 min_attr_value (rtx exp, int *unknownp)
3861 int current_min;
3862 int i, n;
3864 switch (GET_CODE (exp))
3866 case CONST_STRING:
3867 current_min = atoi (XSTR (exp, 0));
3868 break;
3870 case COND:
3871 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3872 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3874 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3875 if (n < current_min)
3876 current_min = n;
3878 break;
3880 case IF_THEN_ELSE:
3881 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3882 n = min_attr_value (XEXP (exp, 2), unknownp);
3883 if (n < current_min)
3884 current_min = n;
3885 break;
3887 default:
3888 *unknownp = 1;
3889 current_min = INT_MAX;
3890 break;
3893 return current_min;
3896 /* Given an attribute value, return the result of ORing together all
3897 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3898 if the numeric value is not known. */
3900 static int
3901 or_attr_value (rtx exp, int *unknownp)
3903 int current_or;
3904 int i;
3906 switch (GET_CODE (exp))
3908 case CONST_STRING:
3909 current_or = atoi (XSTR (exp, 0));
3910 break;
3912 case COND:
3913 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3914 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3915 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3916 break;
3918 case IF_THEN_ELSE:
3919 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3920 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3921 break;
3923 default:
3924 *unknownp = 1;
3925 current_or = -1;
3926 break;
3929 return current_or;
3932 /* Scan an attribute value, possibly a conditional, and record what actions
3933 will be required to do any conditional tests in it.
3935 Specifically, set
3936 `must_extract' if we need to extract the insn operands
3937 `must_constrain' if we must compute `which_alternative'
3938 `address_used' if an address expression was used
3939 `length_used' if an (eq_attr "length" ...) was used
3942 static void
3943 walk_attr_value (rtx exp)
3945 int i, j;
3946 const char *fmt;
3947 RTX_CODE code;
3949 if (exp == NULL)
3950 return;
3952 code = GET_CODE (exp);
3953 switch (code)
3955 case SYMBOL_REF:
3956 if (! ATTR_IND_SIMPLIFIED_P (exp))
3957 /* Since this is an arbitrary expression, it can look at anything.
3958 However, constant expressions do not depend on any particular
3959 insn. */
3960 must_extract = must_constrain = 1;
3961 return;
3963 case MATCH_OPERAND:
3964 must_extract = 1;
3965 return;
3967 case MATCH_TEST:
3968 case EQ_ATTR_ALT:
3969 must_extract = must_constrain = 1;
3970 break;
3972 case EQ_ATTR:
3973 if (XSTR (exp, 0) == alternative_name)
3974 must_extract = must_constrain = 1;
3975 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3976 length_used = 1;
3977 return;
3979 case MATCH_DUP:
3980 must_extract = 1;
3981 address_used = 1;
3982 return;
3984 case PC:
3985 address_used = 1;
3986 return;
3988 case ATTR_FLAG:
3989 return;
3991 default:
3992 break;
3995 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3996 switch (*fmt++)
3998 case 'e':
3999 case 'u':
4000 walk_attr_value (XEXP (exp, i));
4001 break;
4003 case 'E':
4004 if (XVEC (exp, i) != NULL)
4005 for (j = 0; j < XVECLEN (exp, i); j++)
4006 walk_attr_value (XVECEXP (exp, i, j));
4007 break;
4011 /* Write out a function to obtain the attribute for a given INSN. */
4013 static void
4014 write_attr_get (FILE *outf, struct attr_desc *attr)
4016 struct attr_value *av, *common_av;
4017 int i, j;
4019 /* Find the most used attribute value. Handle that as the `default' of the
4020 switch we will generate. */
4021 common_av = find_most_used (attr);
4023 /* Write out start of function, then all values with explicit `case' lines,
4024 then a `default', then the value with the most uses. */
4025 if (attr->enum_name)
4026 fprintf (outf, "enum %s\n", attr->enum_name);
4027 else if (!attr->is_numeric)
4028 fprintf (outf, "enum attr_%s\n", attr->name);
4029 else
4030 fprintf (outf, "int\n");
4032 /* If the attribute name starts with a star, the remainder is the name of
4033 the subroutine to use, instead of `get_attr_...'. */
4034 if (attr->name[0] == '*')
4035 fprintf (outf, "%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
4036 else if (attr->is_const == 0)
4037 fprintf (outf, "get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
4038 else
4040 fprintf (outf, "get_attr_%s (void)\n", attr->name);
4041 fprintf (outf, "{\n");
4043 for (av = attr->first_value; av; av = av->next)
4044 if (av->num_insns == 1)
4045 write_attr_set (outf, attr, 2, av->value, "return", ";",
4046 true_rtx, av->first_insn->def->insn_code,
4047 av->first_insn->def->insn_index, 0);
4048 else if (av->num_insns != 0)
4049 write_attr_set (outf, attr, 2, av->value, "return", ";",
4050 true_rtx, -2, 0, 0);
4052 fprintf (outf, "}\n\n");
4053 return;
4056 fprintf (outf, "{\n");
4058 /* Find attributes that are worth caching in the conditions. */
4059 cached_attr_count = 0;
4060 attrs_seen_more_than_once = 0;
4061 for (av = attr->first_value; av; av = av->next)
4063 attrs_seen_once = 0;
4064 find_attrs_to_cache (av->value, true);
4066 /* Remove those that aren't worth caching from the array. */
4067 for (i = 0, j = 0; i < cached_attr_count; i++)
4068 if ((attrs_seen_more_than_once & (1U << i)) != 0)
4070 const char *name = cached_attrs[i];
4071 struct attr_desc *cached_attr;
4072 if (i != j)
4073 cached_attrs[j] = name;
4074 cached_attr = find_attr (&name, 0);
4075 gcc_assert (cached_attr && cached_attr->is_const == 0);
4076 if (cached_attr->enum_name)
4077 fprintf (outf, " enum %s", cached_attr->enum_name);
4078 else if (!cached_attr->is_numeric)
4079 fprintf (outf, " enum attr_%s", cached_attr->name);
4080 else
4081 fprintf (outf, " int");
4082 fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name);
4083 j++;
4085 cached_attr_count = j;
4086 if (cached_attr_count)
4087 fprintf (outf, "\n");
4089 fprintf (outf, " switch (recog_memoized (insn))\n");
4090 fprintf (outf, " {\n");
4092 for (av = attr->first_value; av; av = av->next)
4093 if (av != common_av)
4094 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4096 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4097 fprintf (outf, " }\n}\n\n");
4098 cached_attr_count = 0;
4101 /* Given an AND tree of known true terms (because we are inside an `if' with
4102 that as the condition or are in an `else' clause) and an expression,
4103 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4104 the bulk of the work. */
4106 static rtx
4107 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
4109 rtx term;
4111 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4113 if (GET_CODE (known_true) == AND)
4115 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4116 insn_code, insn_index);
4117 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4118 insn_code, insn_index);
4120 else
4122 term = known_true;
4123 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4126 return exp;
4129 /* Write out a series of tests and assignment statements to perform tests and
4130 sets of an attribute value. We are passed an indentation amount and prefix
4131 and suffix strings to write around each attribute value (e.g., "return"
4132 and ";"). */
4134 static void
4135 write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value,
4136 const char *prefix, const char *suffix, rtx known_true,
4137 int insn_code, int insn_index, unsigned int attrs_cached)
4139 if (GET_CODE (value) == COND)
4141 /* Assume the default value will be the default of the COND unless we
4142 find an always true expression. */
4143 rtx default_val = XEXP (value, 1);
4144 rtx our_known_true = known_true;
4145 rtx newexp;
4146 int first_if = 1;
4147 int i;
4149 if (cached_attr_count)
4151 attrs_seen_once = 0;
4152 attrs_seen_more_than_once = 0;
4153 for (i = 0; i < XVECLEN (value, 0); i += 2)
4154 find_attrs_to_cache (XVECEXP (value, 0, i), false);
4155 attrs_to_cache |= attrs_seen_more_than_once;
4158 for (i = 0; i < XVECLEN (value, 0); i += 2)
4160 rtx testexp;
4161 rtx inner_true;
4163 /* Reset our_known_true after some time to not accumulate
4164 too much cruft (slowing down genattrtab). */
4165 if ((i & 31) == 0)
4166 our_known_true = known_true;
4167 testexp = eliminate_known_true (our_known_true,
4168 XVECEXP (value, 0, i),
4169 insn_code, insn_index);
4170 newexp = attr_rtx (NOT, testexp);
4171 newexp = insert_right_side (AND, our_known_true, newexp,
4172 insn_code, insn_index);
4174 /* If the test expression is always true or if the next `known_true'
4175 expression is always false, this is the last case, so break
4176 out and let this value be the `else' case. */
4177 if (testexp == true_rtx || newexp == false_rtx)
4179 default_val = XVECEXP (value, 0, i + 1);
4180 break;
4183 /* Compute the expression to pass to our recursive call as being
4184 known true. */
4185 inner_true = insert_right_side (AND, our_known_true,
4186 testexp, insn_code, insn_index);
4188 /* If this is always false, skip it. */
4189 if (inner_true == false_rtx)
4190 continue;
4192 attrs_cached_inside = attrs_cached;
4193 attrs_cached_after = attrs_cached;
4194 write_indent (outf, indent);
4195 fprintf (outf, "%sif ", first_if ? "" : "else ");
4196 first_if = 0;
4197 write_test_expr (outf, testexp, attrs_cached,
4198 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
4199 attrs_cached = attrs_cached_after;
4200 fprintf (outf, "\n");
4201 write_indent (outf, indent + 2);
4202 fprintf (outf, "{\n");
4204 write_attr_set (outf, attr, indent + 4,
4205 XVECEXP (value, 0, i + 1), prefix, suffix,
4206 inner_true, insn_code, insn_index,
4207 attrs_cached_inside);
4208 write_indent (outf, indent + 2);
4209 fprintf (outf, "}\n");
4210 our_known_true = newexp;
4213 if (! first_if)
4215 write_indent (outf, indent);
4216 fprintf (outf, "else\n");
4217 write_indent (outf, indent + 2);
4218 fprintf (outf, "{\n");
4221 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val,
4222 prefix, suffix, our_known_true, insn_code, insn_index,
4223 attrs_cached);
4225 if (! first_if)
4227 write_indent (outf, indent + 2);
4228 fprintf (outf, "}\n");
4231 else
4233 write_indent (outf, indent);
4234 fprintf (outf, "%s ", prefix);
4235 write_attr_value (outf, attr, value);
4236 fprintf (outf, "%s\n", suffix);
4240 /* Write a series of case statements for every instruction in list IE.
4241 INDENT is the amount of indentation to write before each case. */
4243 static void
4244 write_insn_cases (FILE *outf, struct insn_ent *ie, int indent)
4246 for (; ie != 0; ie = ie->next)
4247 if (ie->def->insn_code != -1)
4249 write_indent (outf, indent);
4250 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4251 fprintf (outf, "case %d: /* define_peephole, line %d */\n",
4252 ie->def->insn_code, ie->def->lineno);
4253 else
4254 fprintf (outf, "case %d: /* %s */\n",
4255 ie->def->insn_code, XSTR (ie->def->def, 0));
4259 /* Write out the computation for one attribute value. */
4261 static void
4262 write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av,
4263 int write_case_lines, const char *prefix, const char *suffix,
4264 int indent, rtx known_true)
4266 if (av->num_insns == 0)
4267 return;
4269 if (av->has_asm_insn)
4271 write_indent (outf, indent);
4272 fprintf (outf, "case -1:\n");
4273 write_indent (outf, indent + 2);
4274 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4275 write_indent (outf, indent + 2);
4276 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n");
4277 write_indent (outf, indent + 2);
4278 fprintf (outf, " fatal_insn_not_found (insn);\n");
4281 if (write_case_lines)
4282 write_insn_cases (outf, av->first_insn, indent);
4283 else
4285 write_indent (outf, indent);
4286 fprintf (outf, "default:\n");
4289 /* See what we have to do to output this value. */
4290 must_extract = must_constrain = address_used = 0;
4291 walk_attr_value (av->value);
4293 if (must_constrain)
4295 write_indent (outf, indent + 2);
4296 fprintf (outf, "extract_constrain_insn_cached (insn);\n");
4298 else if (must_extract)
4300 write_indent (outf, indent + 2);
4301 fprintf (outf, "extract_insn_cached (insn);\n");
4304 attrs_to_cache = 0;
4305 if (av->num_insns == 1)
4306 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4307 known_true, av->first_insn->def->insn_code,
4308 av->first_insn->def->insn_index, 0);
4309 else
4310 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix,
4311 known_true, -2, 0, 0);
4313 if (strncmp (prefix, "return", 6))
4315 write_indent (outf, indent + 2);
4316 fprintf (outf, "break;\n");
4318 fprintf (outf, "\n");
4321 /* Utilities to write in various forms. */
4323 static void
4324 write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s)
4326 if (attr->is_numeric)
4328 int num = atoi (s);
4330 fprintf (outf, "%d", num);
4332 if (num > 9 || num < 0)
4333 fprintf (outf, " /* %#x */", num);
4335 else
4337 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name);
4338 fprintf (outf, "_");
4339 write_upcase (outf, s);
4343 static void
4344 write_attr_value (FILE *outf, struct attr_desc *attr, rtx value)
4346 int op;
4348 switch (GET_CODE (value))
4350 case CONST_STRING:
4351 write_attr_valueq (outf, attr, XSTR (value, 0));
4352 break;
4354 case CONST_INT:
4355 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4356 break;
4358 case SYMBOL_REF:
4359 fprint_c_condition (outf, XSTR (value, 0));
4360 break;
4362 case ATTR:
4364 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4365 if (attr->enum_name)
4366 fprintf (outf, "(enum %s)", attr->enum_name);
4367 else if (!attr->is_numeric)
4368 fprintf (outf, "(enum attr_%s)", attr->name);
4369 else if (!attr2->is_numeric)
4370 fprintf (outf, "(int)");
4372 fprintf (outf, "get_attr_%s (%s)", attr2->name,
4373 (attr2->is_const ? "" : "insn"));
4375 break;
4377 case PLUS:
4378 op = '+';
4379 goto do_operator;
4380 case MINUS:
4381 op = '-';
4382 goto do_operator;
4383 case MULT:
4384 op = '*';
4385 goto do_operator;
4386 case DIV:
4387 op = '/';
4388 goto do_operator;
4389 case MOD:
4390 op = '%';
4391 goto do_operator;
4393 do_operator:
4394 write_attr_value (outf, attr, XEXP (value, 0));
4395 fputc (' ', outf);
4396 fputc (op, outf);
4397 fputc (' ', outf);
4398 write_attr_value (outf, attr, XEXP (value, 1));
4399 break;
4401 default:
4402 gcc_unreachable ();
4406 static void
4407 write_upcase (FILE *outf, const char *str)
4409 while (*str)
4411 /* The argument of TOUPPER should not have side effects. */
4412 fputc (TOUPPER(*str), outf);
4413 str++;
4417 static void
4418 write_indent (FILE *outf, int indent)
4420 for (; indent > 8; indent -= 8)
4421 fprintf (outf, "\t");
4423 for (; indent; indent--)
4424 fprintf (outf, " ");
4427 /* Write a subroutine that is given an insn that requires a delay slot, a
4428 delay slot ordinal, and a candidate insn. It returns nonzero if the
4429 candidate can be placed in the specified delay slot of the insn.
4431 We can write as many as three subroutines. `eligible_for_delay'
4432 handles normal delay slots, `eligible_for_annul_true' indicates that
4433 the specified insn can be annulled if the branch is true, and likewise
4434 for `eligible_for_annul_false'.
4436 KIND is a string distinguishing these three cases ("delay", "annul_true",
4437 or "annul_false"). */
4439 static void
4440 write_eligible_delay (FILE *outf, const char *kind)
4442 struct delay_desc *delay;
4443 int max_slots;
4444 char str[50];
4445 const char *pstr;
4446 struct attr_desc *attr;
4447 struct attr_value *av, *common_av;
4448 int i;
4450 /* Compute the maximum number of delay slots required. We use the delay
4451 ordinal times this number plus one, plus the slot number as an index into
4452 the appropriate predicate to test. */
4454 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4455 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4456 max_slots = XVECLEN (delay->def, 1) / 3;
4458 /* Write function prelude. */
4460 fprintf (outf, "int\n");
4461 fprintf (outf, "eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4462 " rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4463 kind);
4464 fprintf (outf, "{\n");
4465 fprintf (outf, " rtx insn;\n");
4466 fprintf (outf, "\n");
4467 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots);
4468 fprintf (outf, "\n");
4469 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4470 converts a compound instruction into a loop. */
4471 fprintf (outf, " if (!INSN_P (candidate_insn))\n");
4472 fprintf (outf, " return 0;\n");
4473 fprintf (outf, "\n");
4475 /* If more than one delay type, find out which type the delay insn is. */
4477 if (num_delays > 1)
4479 attr = find_attr (&delay_type_str, 0);
4480 gcc_assert (attr);
4481 common_av = find_most_used (attr);
4483 fprintf (outf, " insn = delay_insn;\n");
4484 fprintf (outf, " switch (recog_memoized (insn))\n");
4485 fprintf (outf, " {\n");
4487 sprintf (str, " * %d;\n break;", max_slots);
4488 for (av = attr->first_value; av; av = av->next)
4489 if (av != common_av)
4490 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx);
4492 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx);
4493 fprintf (outf, " }\n\n");
4495 /* Ensure matched. Otherwise, shouldn't have been called. */
4496 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots);
4499 /* If just one type of delay slot, write simple switch. */
4500 if (num_delays == 1 && max_slots == 1)
4502 fprintf (outf, " insn = candidate_insn;\n");
4503 fprintf (outf, " switch (recog_memoized (insn))\n");
4504 fprintf (outf, " {\n");
4506 attr = find_attr (&delay_1_0_str, 0);
4507 gcc_assert (attr);
4508 common_av = find_most_used (attr);
4510 for (av = attr->first_value; av; av = av->next)
4511 if (av != common_av)
4512 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx);
4514 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx);
4515 fprintf (outf, " }\n");
4518 else
4520 /* Write a nested CASE. The first indicates which condition we need to
4521 test, and the inner CASE tests the condition. */
4522 fprintf (outf, " insn = candidate_insn;\n");
4523 fprintf (outf, " switch (slot)\n");
4524 fprintf (outf, " {\n");
4526 for (delay = delays; delay; delay = delay->next)
4527 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4529 fprintf (outf, " case %d:\n",
4530 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4531 fprintf (outf, " switch (recog_memoized (insn))\n");
4532 fprintf (outf, "\t{\n");
4534 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4535 pstr = str;
4536 attr = find_attr (&pstr, 0);
4537 gcc_assert (attr);
4538 common_av = find_most_used (attr);
4540 for (av = attr->first_value; av; av = av->next)
4541 if (av != common_av)
4542 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx);
4544 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx);
4545 fprintf (outf, " }\n");
4548 fprintf (outf, " default:\n");
4549 fprintf (outf, " gcc_unreachable ();\n");
4550 fprintf (outf, " }\n");
4553 fprintf (outf, "}\n\n");
4556 /* This page contains miscellaneous utility routines. */
4558 /* Given a pointer to a (char *), return a malloc'ed string containing the
4559 next comma-separated element. Advance the pointer to after the string
4560 scanned, or the end-of-string. Return NULL if at end of string. */
4562 static char *
4563 next_comma_elt (const char **pstr)
4565 const char *start;
4567 start = scan_comma_elt (pstr);
4569 if (start == NULL)
4570 return NULL;
4572 return attr_string (start, *pstr - start);
4575 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4576 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4577 replaced by a pointer to a canonical copy of the string. */
4579 static struct attr_desc *
4580 find_attr (const char **name_p, int create)
4582 struct attr_desc *attr;
4583 int index;
4584 const char *name = *name_p;
4586 /* Before we resort to using `strcmp', see if the string address matches
4587 anywhere. In most cases, it should have been canonicalized to do so. */
4588 if (name == alternative_name)
4589 return NULL;
4591 index = name[0] & (MAX_ATTRS_INDEX - 1);
4592 for (attr = attrs[index]; attr; attr = attr->next)
4593 if (name == attr->name)
4594 return attr;
4596 /* Otherwise, do it the slow way. */
4597 for (attr = attrs[index]; attr; attr = attr->next)
4598 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4600 *name_p = attr->name;
4601 return attr;
4604 if (! create)
4605 return NULL;
4607 attr = oballoc (struct attr_desc);
4608 attr->name = DEF_ATTR_STRING (name);
4609 attr->enum_name = 0;
4610 attr->first_value = attr->default_val = NULL;
4611 attr->is_numeric = attr->is_const = attr->is_special = 0;
4612 attr->next = attrs[index];
4613 attrs[index] = attr;
4615 *name_p = attr->name;
4617 return attr;
4620 /* Create internal attribute with the given default value. */
4622 static void
4623 make_internal_attr (const char *name, rtx value, int special)
4625 struct attr_desc *attr;
4627 attr = find_attr (&name, 1);
4628 gcc_assert (!attr->default_val);
4630 attr->is_numeric = 1;
4631 attr->is_const = 0;
4632 attr->is_special = (special & ATTR_SPECIAL) != 0;
4633 attr->default_val = get_attr_value (value, attr, -2);
4636 /* Find the most used value of an attribute. */
4638 static struct attr_value *
4639 find_most_used (struct attr_desc *attr)
4641 struct attr_value *av;
4642 struct attr_value *most_used;
4643 int nuses;
4645 most_used = NULL;
4646 nuses = -1;
4648 for (av = attr->first_value; av; av = av->next)
4649 if (av->num_insns > nuses)
4650 nuses = av->num_insns, most_used = av;
4652 return most_used;
4655 /* Return (attr_value "n") */
4657 static rtx
4658 make_numeric_value (int n)
4660 static rtx int_values[20];
4661 rtx exp;
4662 char *p;
4664 gcc_assert (n >= 0);
4666 if (n < 20 && int_values[n])
4667 return int_values[n];
4669 p = attr_printf (MAX_DIGITS, "%d", n);
4670 exp = attr_rtx (CONST_STRING, p);
4672 if (n < 20)
4673 int_values[n] = exp;
4675 return exp;
4678 static rtx
4679 copy_rtx_unchanging (rtx orig)
4681 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4682 return orig;
4684 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4685 return orig;
4688 /* Determine if an insn has a constant number of delay slots, i.e., the
4689 number of delay slots is not a function of the length of the insn. */
4691 static void
4692 write_const_num_delay_slots (FILE *outf)
4694 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4695 struct attr_value *av;
4697 if (attr)
4699 fprintf (outf, "int\nconst_num_delay_slots (rtx insn)\n");
4700 fprintf (outf, "{\n");
4701 fprintf (outf, " switch (recog_memoized (insn))\n");
4702 fprintf (outf, " {\n");
4704 for (av = attr->first_value; av; av = av->next)
4706 length_used = 0;
4707 walk_attr_value (av->value);
4708 if (length_used)
4709 write_insn_cases (outf, av->first_insn, 4);
4712 fprintf (outf, " default:\n");
4713 fprintf (outf, " return 1;\n");
4714 fprintf (outf, " }\n}\n\n");
4718 /* Synthetic attributes used by insn-automata.c and the scheduler.
4719 These are primarily concerned with (define_insn_reservation)
4720 patterns. */
4722 struct insn_reserv
4724 struct insn_reserv *next;
4726 const char *name;
4727 int default_latency;
4728 rtx condexp;
4730 /* Sequence number of this insn. */
4731 int insn_num;
4733 /* Whether a (define_bypass) construct names this insn in its
4734 output list. */
4735 bool bypassed;
4738 static struct insn_reserv *all_insn_reservs = 0;
4739 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4740 static size_t n_insn_reservs;
4742 /* Store information from a DEFINE_INSN_RESERVATION for future
4743 attribute generation. */
4744 static void
4745 gen_insn_reserv (rtx def)
4747 struct insn_reserv *decl = oballoc (struct insn_reserv);
4749 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4750 decl->default_latency = XINT (def, 1);
4751 decl->condexp = check_attr_test (XEXP (def, 2), 0, 0);
4752 decl->insn_num = n_insn_reservs;
4753 decl->bypassed = false;
4754 decl->next = 0;
4756 *last_insn_reserv_p = decl;
4757 last_insn_reserv_p = &decl->next;
4758 n_insn_reservs++;
4761 /* Store information from a DEFINE_BYPASS for future attribute
4762 generation. The only thing we care about is the list of output
4763 insns, which will later be used to tag reservation structures with
4764 a 'bypassed' bit. */
4766 struct bypass_list
4768 struct bypass_list *next;
4769 const char *pattern;
4772 static struct bypass_list *all_bypasses;
4773 static size_t n_bypasses;
4775 static void
4776 gen_bypass_1 (const char *s, size_t len)
4778 struct bypass_list *b;
4780 if (len == 0)
4781 return;
4783 s = attr_string (s, len);
4784 for (b = all_bypasses; b; b = b->next)
4785 if (s == b->pattern)
4786 return; /* already got that one */
4788 b = oballoc (struct bypass_list);
4789 b->pattern = s;
4790 b->next = all_bypasses;
4791 all_bypasses = b;
4792 n_bypasses++;
4795 static void
4796 gen_bypass (rtx def)
4798 const char *p, *base;
4800 for (p = base = XSTR (def, 1); *p; p++)
4801 if (*p == ',')
4803 gen_bypass_1 (base, p - base);
4805 p++;
4806 while (ISSPACE (*p));
4807 base = p;
4809 gen_bypass_1 (base, p - base);
4812 /* Find and mark all of the bypassed insns. */
4813 static void
4814 process_bypasses (void)
4816 struct bypass_list *b;
4817 struct insn_reserv *r;
4819 /* The reservation list is likely to be much longer than the bypass
4820 list. */
4821 for (r = all_insn_reservs; r; r = r->next)
4822 for (b = all_bypasses; b; b = b->next)
4823 if (fnmatch (b->pattern, r->name, 0) == 0)
4824 r->bypassed = true;
4827 /* Check that attribute NAME is used in define_insn_reservation condition
4828 EXP. Return true if it is. */
4829 static bool
4830 check_tune_attr (const char *name, rtx exp)
4832 switch (GET_CODE (exp))
4834 case AND:
4835 if (check_tune_attr (name, XEXP (exp, 0)))
4836 return true;
4837 return check_tune_attr (name, XEXP (exp, 1));
4839 case IOR:
4840 return (check_tune_attr (name, XEXP (exp, 0))
4841 && check_tune_attr (name, XEXP (exp, 1)));
4843 case EQ_ATTR:
4844 return XSTR (exp, 0) == name;
4846 default:
4847 return false;
4851 /* Try to find a const attribute (usually cpu or tune) that is used
4852 in all define_insn_reservation conditions. */
4853 static struct attr_desc *
4854 find_tune_attr (rtx exp)
4856 struct attr_desc *attr;
4858 switch (GET_CODE (exp))
4860 case AND:
4861 case IOR:
4862 attr = find_tune_attr (XEXP (exp, 0));
4863 if (attr)
4864 return attr;
4865 return find_tune_attr (XEXP (exp, 1));
4867 case EQ_ATTR:
4868 if (XSTR (exp, 0) == alternative_name)
4869 return NULL;
4871 attr = find_attr (&XSTR (exp, 0), 0);
4872 gcc_assert (attr);
4874 if (attr->is_const && !attr->is_special)
4876 struct insn_reserv *decl;
4878 for (decl = all_insn_reservs; decl; decl = decl->next)
4879 if (! check_tune_attr (attr->name, decl->condexp))
4880 return NULL;
4881 return attr;
4883 return NULL;
4885 default:
4886 return NULL;
4890 /* Create all of the attributes that describe automaton properties.
4891 Write the DFA and latency function prototypes to the files that
4892 need to have them, and write the init_sched_attrs(). */
4894 static void
4895 make_automaton_attrs (void)
4897 int i;
4898 struct insn_reserv *decl;
4899 rtx code_exp, lats_exp, byps_exp;
4900 struct attr_desc *tune_attr;
4902 if (n_insn_reservs == 0)
4903 return;
4905 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4906 if (tune_attr != NULL)
4908 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4909 struct attr_value *val;
4910 bool first = true;
4912 gcc_assert (tune_attr->is_const
4913 && !tune_attr->is_special
4914 && !tune_attr->is_numeric);
4916 /* Write the prototypes for all DFA functions. */
4917 for (val = tune_attr->first_value; val; val = val->next)
4919 if (val == tune_attr->default_val)
4920 continue;
4921 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4922 fprintf (dfa_file,
4923 "extern int internal_dfa_insn_code_%s (rtx);\n",
4924 XSTR (val->value, 0));
4926 fprintf (dfa_file, "\n");
4928 /* Write the prototypes for all latency functions. */
4929 for (val = tune_attr->first_value; val; val = val->next)
4931 if (val == tune_attr->default_val)
4932 continue;
4933 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4934 fprintf (latency_file,
4935 "extern int insn_default_latency_%s (rtx);\n",
4936 XSTR (val->value, 0));
4938 fprintf (latency_file, "\n");
4940 /* Write the prototypes for all automaton functions. */
4941 for (val = tune_attr->first_value; val; val = val->next)
4943 if (val == tune_attr->default_val)
4944 continue;
4945 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4946 fprintf (attr_file,
4947 "extern int internal_dfa_insn_code_%s (rtx);\n"
4948 "extern int insn_default_latency_%s (rtx);\n",
4949 XSTR (val->value, 0), XSTR (val->value, 0));
4951 fprintf (attr_file, "\n");
4952 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx);\n");
4953 fprintf (attr_file, "int (*insn_default_latency) (rtx);\n");
4954 fprintf (attr_file, "\n");
4955 fprintf (attr_file, "void\n");
4956 fprintf (attr_file, "init_sched_attrs (void)\n");
4957 fprintf (attr_file, "{\n");
4959 for (val = tune_attr->first_value; val; val = val->next)
4961 int j;
4962 char *name;
4963 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
4965 if (val == tune_attr->default_val)
4966 continue;
4967 for (decl = all_insn_reservs, i = 0;
4968 decl;
4969 decl = decl->next)
4971 rtx ctest = test;
4972 rtx condexp
4973 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
4974 if (condexp == false_rtx)
4975 continue;
4976 if (condexp == true_rtx)
4977 break;
4978 condexps[i] = condexp;
4979 condexps[i + 1] = make_numeric_value (decl->insn_num);
4980 condexps[i + 2] = make_numeric_value (decl->default_latency);
4981 i += 3;
4984 code_exp = rtx_alloc (COND);
4985 lats_exp = rtx_alloc (COND);
4987 j = i / 3 * 2;
4988 XVEC (code_exp, 0) = rtvec_alloc (j);
4989 XVEC (lats_exp, 0) = rtvec_alloc (j);
4991 if (decl)
4993 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
4994 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
4996 else
4998 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
4999 XEXP (lats_exp, 1) = make_numeric_value (0);
5002 while (i > 0)
5004 i -= 3;
5005 j -= 2;
5006 XVECEXP (code_exp, 0, j) = condexps[i];
5007 XVECEXP (lats_exp, 0, j) = condexps[i];
5009 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
5010 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
5013 name = XNEWVEC (char,
5014 sizeof ("*internal_dfa_insn_code_")
5015 + strlen (XSTR (val->value, 0)));
5016 strcpy (name, "*internal_dfa_insn_code_");
5017 strcat (name, XSTR (val->value, 0));
5018 make_internal_attr (name, code_exp, ATTR_NONE);
5019 strcpy (name, "*insn_default_latency_");
5020 strcat (name, XSTR (val->value, 0));
5021 make_internal_attr (name, lats_exp, ATTR_NONE);
5022 XDELETEVEC (name);
5024 if (first)
5026 fprintf (attr_file, " if (");
5027 first = false;
5029 else
5030 fprintf (attr_file, " else if (");
5031 write_test_expr (attr_file, test, 0, 0);
5032 fprintf (attr_file, ")\n");
5033 fprintf (attr_file, " {\n");
5034 fprintf (attr_file, " internal_dfa_insn_code\n");
5035 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n",
5036 XSTR (val->value, 0));
5037 fprintf (attr_file, " insn_default_latency\n");
5038 fprintf (attr_file, " = insn_default_latency_%s;\n",
5039 XSTR (val->value, 0));
5040 fprintf (attr_file, " }\n");
5043 fprintf (attr_file, " else\n");
5044 fprintf (attr_file, " gcc_unreachable ();\n");
5045 fprintf (attr_file, "}\n");
5046 fprintf (attr_file, "\n");
5048 XDELETEVEC (condexps);
5050 else
5052 code_exp = rtx_alloc (COND);
5053 lats_exp = rtx_alloc (COND);
5055 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5056 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
5058 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
5059 XEXP (lats_exp, 1) = make_numeric_value (0);
5061 for (decl = all_insn_reservs, i = 0;
5062 decl;
5063 decl = decl->next, i += 2)
5065 XVECEXP (code_exp, 0, i) = decl->condexp;
5066 XVECEXP (lats_exp, 0, i) = decl->condexp;
5068 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
5069 XVECEXP (lats_exp, 0, i+1)
5070 = make_numeric_value (decl->default_latency);
5072 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
5073 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
5076 if (n_bypasses == 0)
5077 byps_exp = make_numeric_value (0);
5078 else
5080 process_bypasses ();
5082 byps_exp = rtx_alloc (COND);
5083 XVEC (byps_exp, 0) = rtvec_alloc (n_bypasses * 2);
5084 XEXP (byps_exp, 1) = make_numeric_value (0);
5085 for (decl = all_insn_reservs, i = 0;
5086 decl;
5087 decl = decl->next)
5088 if (decl->bypassed)
5090 XVECEXP (byps_exp, 0, i) = decl->condexp;
5091 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
5092 i += 2;
5096 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
5099 static void
5100 write_header (FILE *outf)
5102 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n"
5103 " from the machine description file `md'. */\n\n");
5105 fprintf (outf, "#include \"config.h\"\n");
5106 fprintf (outf, "#include \"system.h\"\n");
5107 fprintf (outf, "#include \"coretypes.h\"\n");
5108 fprintf (outf, "#include \"tm.h\"\n");
5109 fprintf (outf, "#include \"rtl.h\"\n");
5110 fprintf (outf, "#include \"insn-attr.h\"\n");
5111 fprintf (outf, "#include \"tm_p.h\"\n");
5112 fprintf (outf, "#include \"insn-config.h\"\n");
5113 fprintf (outf, "#include \"recog.h\"\n");
5114 fprintf (outf, "#include \"regs.h\"\n");
5115 fprintf (outf, "#include \"real.h\"\n");
5116 fprintf (outf, "#include \"output.h\"\n");
5117 fprintf (outf, "#include \"toplev.h\"\n");
5118 fprintf (outf, "#include \"flags.h\"\n");
5119 fprintf (outf, "#include \"function.h\"\n");
5120 fprintf (outf, "\n");
5121 fprintf (outf, "#define operands recog_data.operand\n\n");
5124 static FILE *
5125 open_outfile (const char *file_name)
5127 FILE *outf;
5128 outf = fopen (file_name, "w");
5129 if (! outf)
5130 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
5131 write_header (outf);
5132 return outf;
5135 static bool
5136 handle_arg (const char *arg)
5138 switch (arg[1])
5140 case 'A':
5141 attr_file_name = &arg[2];
5142 return true;
5143 case 'D':
5144 dfa_file_name = &arg[2];
5145 return true;
5146 case 'L':
5147 latency_file_name = &arg[2];
5148 return true;
5149 default:
5150 return false;
5155 main (int argc, char **argv)
5157 rtx desc;
5158 struct attr_desc *attr;
5159 struct insn_def *id;
5160 rtx tem;
5161 int i;
5163 progname = "genattrtab";
5165 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
5166 return FATAL_EXIT_CODE;
5168 attr_file = open_outfile (attr_file_name);
5169 dfa_file = open_outfile (dfa_file_name);
5170 latency_file = open_outfile (latency_file_name);
5172 obstack_init (hash_obstack);
5173 obstack_init (temp_obstack);
5175 /* Set up true and false rtx's */
5176 true_rtx = rtx_alloc (CONST_INT);
5177 XWINT (true_rtx, 0) = 1;
5178 false_rtx = rtx_alloc (CONST_INT);
5179 XWINT (false_rtx, 0) = 0;
5180 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
5181 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
5183 alternative_name = DEF_ATTR_STRING ("alternative");
5184 length_str = DEF_ATTR_STRING ("length");
5185 delay_type_str = DEF_ATTR_STRING ("*delay_type");
5186 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
5187 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
5189 /* Read the machine description. */
5191 while (1)
5193 int lineno;
5195 desc = read_md_rtx (&lineno, &insn_code_number);
5196 if (desc == NULL)
5197 break;
5199 switch (GET_CODE (desc))
5201 case DEFINE_INSN:
5202 case DEFINE_PEEPHOLE:
5203 case DEFINE_ASM_ATTRIBUTES:
5204 gen_insn (desc, lineno);
5205 break;
5207 case DEFINE_ATTR:
5208 case DEFINE_ENUM_ATTR:
5209 gen_attr (desc, lineno);
5210 break;
5212 case DEFINE_DELAY:
5213 gen_delay (desc, lineno);
5214 break;
5216 case DEFINE_INSN_RESERVATION:
5217 gen_insn_reserv (desc);
5218 break;
5220 case DEFINE_BYPASS:
5221 gen_bypass (desc);
5222 break;
5224 default:
5225 break;
5227 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
5228 insn_index_number++;
5231 if (have_error)
5232 return FATAL_EXIT_CODE;
5234 insn_code_number++;
5236 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5237 if (! got_define_asm_attributes)
5239 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5240 XVEC (tem, 0) = rtvec_alloc (0);
5241 gen_insn (tem, 0);
5244 /* Expand DEFINE_DELAY information into new attribute. */
5245 if (num_delays)
5246 expand_delays ();
5248 /* Make `insn_alternatives'. */
5249 insn_alternatives = oballocvec (int, insn_code_number);
5250 for (id = defs; id; id = id->next)
5251 if (id->insn_code >= 0)
5252 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
5254 /* Make `insn_n_alternatives'. */
5255 insn_n_alternatives = oballocvec (int, insn_code_number);
5256 for (id = defs; id; id = id->next)
5257 if (id->insn_code >= 0)
5258 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5260 /* Construct extra attributes for automata. */
5261 make_automaton_attrs ();
5263 /* Prepare to write out attribute subroutines by checking everything stored
5264 away and building the attribute cases. */
5266 check_defs ();
5268 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5269 for (attr = attrs[i]; attr; attr = attr->next)
5270 attr->default_val->value
5271 = check_attr_value (attr->default_val->value, attr);
5273 if (have_error)
5274 return FATAL_EXIT_CODE;
5276 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5277 for (attr = attrs[i]; attr; attr = attr->next)
5278 fill_attr (attr);
5280 /* Construct extra attributes for `length'. */
5281 make_length_attrs ();
5283 /* Perform any possible optimizations to speed up compilation. */
5284 optimize_attrs ();
5286 /* Now write out all the `gen_attr_...' routines. Do these before the
5287 special routines so that they get defined before they are used. */
5289 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5290 for (attr = attrs[i]; attr; attr = attr->next)
5292 FILE *outf;
5294 #define IS_ATTR_GROUP(X) (!strncmp(attr->name,X,strlen(X)))
5295 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5296 outf = dfa_file;
5297 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5298 outf = latency_file;
5299 else
5300 outf = attr_file;
5301 #undef IS_ATTR_GROUP
5303 if (! attr->is_special && ! attr->is_const)
5304 write_attr_get (outf, attr);
5307 /* Write out delay eligibility information, if DEFINE_DELAY present.
5308 (The function to compute the number of delay slots will be written
5309 below.) */
5310 if (num_delays)
5312 write_eligible_delay (attr_file, "delay");
5313 if (have_annul_true)
5314 write_eligible_delay (attr_file, "annul_true");
5315 if (have_annul_false)
5316 write_eligible_delay (attr_file, "annul_false");
5319 /* Write out constant delay slot info. */
5320 write_const_num_delay_slots (attr_file);
5322 write_length_unit_log (attr_file);
5324 if (fclose (attr_file) != 0)
5325 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno));
5326 if (fclose (dfa_file) != 0)
5327 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno));
5328 if (fclose (latency_file) != 0)
5329 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno));
5331 return SUCCESS_EXIT_CODE;