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