* config/mips/mips.h (ISA_HAS_INT_CONDMOVE): Delete.
[official-gcc.git] / gcc / genattrtab.c
blobf8f3277d76f9092a68cd597544d71bb92b325f30
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
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).
94 `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
95 EQ_ATTR rtx is true if !volatil and false if volatil. */
97 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
98 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
99 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
100 #define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
102 #if 0
103 #define strcmp_check(S1, S2) ((S1) == (S2) \
104 ? 0 \
105 : (strcmp ((S1), (S2)) \
106 ? 1 \
107 : (abort (), 0)))
108 #else
109 #define strcmp_check(S1, S2) ((S1) != (S2))
110 #endif
112 #include "bconfig.h"
113 #include "system.h"
114 #include "coretypes.h"
115 #include "tm.h"
116 #include "rtl.h"
117 #include "ggc.h"
118 #include "gensupport.h"
120 #ifdef HAVE_SYS_RESOURCE_H
121 # include <sys/resource.h>
122 #endif
124 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
125 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
126 #include "obstack.h"
127 #include "errors.h"
129 #include "genattrtab.h"
131 static struct obstack obstack1, obstack2;
132 struct obstack *hash_obstack = &obstack1;
133 struct obstack *temp_obstack = &obstack2;
135 /* enough space to reserve for printing out ints */
136 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
138 /* Define structures used to record attributes and values. */
140 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
141 encountered, we store all the relevant information into a
142 `struct insn_def'. This is done to allow attribute definitions to occur
143 anywhere in the file. */
145 struct insn_def
147 struct insn_def *next; /* Next insn in chain. */
148 rtx def; /* The DEFINE_... */
149 int insn_code; /* Instruction number. */
150 int insn_index; /* Expression numer in file, for errors. */
151 int lineno; /* Line number. */
152 int num_alternatives; /* Number of alternatives. */
153 int vec_idx; /* Index of attribute vector in `def'. */
156 /* Once everything has been read in, we store in each attribute value a list
157 of insn codes that have that value. Here is the structure used for the
158 list. */
160 struct insn_ent
162 struct insn_ent *next; /* Next in chain. */
163 struct insn_def *def; /* Instruction definition. */
166 /* Each value of an attribute (either constant or computed) is assigned a
167 structure which is used as the listhead of the insns that have that
168 value. */
170 struct attr_value
172 rtx value; /* Value of attribute. */
173 struct attr_value *next; /* Next attribute value in chain. */
174 struct insn_ent *first_insn; /* First insn with this value. */
175 int num_insns; /* Number of insns with this value. */
176 int has_asm_insn; /* True if this value used for `asm' insns */
179 /* Structure for each attribute. */
181 struct attr_desc
183 char *name; /* Name of attribute. */
184 struct attr_desc *next; /* Next attribute. */
185 struct attr_value *first_value; /* First value of this attribute. */
186 struct attr_value *default_val; /* Default value for this attribute. */
187 int lineno : 24; /* Line number. */
188 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
189 unsigned negative_ok : 1; /* Allow negative numeric values. */
190 unsigned unsigned_p : 1; /* Make the output function unsigned int. */
191 unsigned is_const : 1; /* Attribute value constant for each run. */
192 unsigned is_special : 1; /* Don't call `write_attr_set'. */
193 unsigned static_p : 1; /* Make the output function static. */
196 #define NULL_ATTR (struct attr_desc *) NULL
198 /* Structure for each DEFINE_DELAY. */
200 struct delay_desc
202 rtx def; /* DEFINE_DELAY expression. */
203 struct delay_desc *next; /* Next DEFINE_DELAY. */
204 int num; /* Number of DEFINE_DELAY, starting at 1. */
205 int lineno; /* Line number. */
208 /* Listheads of above structures. */
210 /* This one is indexed by the first character of the attribute name. */
211 #define MAX_ATTRS_INDEX 256
212 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
213 static struct insn_def *defs;
214 static struct delay_desc *delays;
216 /* Other variables. */
218 static int insn_code_number;
219 static int insn_index_number;
220 static int got_define_asm_attributes;
221 static int must_extract;
222 static int must_constrain;
223 static int address_used;
224 static int length_used;
225 static int num_delays;
226 static int have_annul_true, have_annul_false;
227 static int num_insn_ents;
229 int num_dfa_decls;
231 /* Stores, for each insn code, the number of constraint alternatives. */
233 static int *insn_n_alternatives;
235 /* Stores, for each insn code, a bitmap that has bits on for each possible
236 alternative. */
238 static int *insn_alternatives;
240 /* If nonzero, assume that the `alternative' attr has this value.
241 This is the hashed, unique string for the numeral
242 whose value is chosen alternative. */
244 static const char *current_alternative_string;
246 /* Used to simplify expressions. */
248 static rtx true_rtx, false_rtx;
250 /* Used to reduce calls to `strcmp' */
252 static char *alternative_name;
253 static const char *length_str;
254 static const char *delay_type_str;
255 static const char *delay_1_0_str;
256 static const char *num_delay_slots_str;
258 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
259 called. */
261 int reload_completed = 0;
263 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
264 to define it here. */
266 int optimize = 0;
268 /* Simplify an expression. Only call the routine if there is something to
269 simplify. */
270 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
271 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
272 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
274 /* Simplify (eq_attr ("alternative") ...)
275 when we are working with a particular alternative. */
276 #define SIMPLIFY_ALTERNATIVE(EXP) \
277 if (current_alternative_string \
278 && GET_CODE ((EXP)) == EQ_ATTR \
279 && XSTR ((EXP), 0) == alternative_name) \
280 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
281 ? true_rtx : false_rtx);
283 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
285 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
286 They won't actually be used. */
288 rtx global_rtl[GR_MAX];
289 rtx pic_offset_table_rtx;
291 static void attr_hash_add_rtx (int, rtx);
292 static void attr_hash_add_string (int, char *);
293 static rtx attr_rtx (enum rtx_code, ...);
294 static rtx attr_rtx_1 (enum rtx_code, va_list);
295 static char *attr_string (const char *, int);
296 static rtx check_attr_value (rtx, struct attr_desc *);
297 static rtx convert_set_attr_alternative (rtx, struct insn_def *);
298 static rtx convert_set_attr (rtx, struct insn_def *);
299 static void check_defs (void);
300 static rtx make_canonical (struct attr_desc *, rtx);
301 static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
302 static rtx copy_rtx_unchanging (rtx);
303 static rtx copy_boolean (rtx);
304 static void expand_delays (void);
305 static void fill_attr (struct attr_desc *);
306 static rtx substitute_address (rtx, rtx (*) (rtx), rtx (*) (rtx));
307 static void make_length_attrs (void);
308 static rtx identity_fn (rtx);
309 static rtx zero_fn (rtx);
310 static rtx one_fn (rtx);
311 static rtx max_fn (rtx);
312 static void write_length_unit_log (void);
313 static rtx simplify_cond (rtx, int, int);
314 static void clear_struct_flag (rtx);
315 static void remove_insn_ent (struct attr_value *, struct insn_ent *);
316 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
317 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
318 static rtx make_alternative_compare (int);
319 static int compute_alternative_mask (rtx, enum rtx_code);
320 static rtx evaluate_eq_attr (rtx, rtx, int, int);
321 static rtx simplify_and_tree (rtx, rtx *, int, int);
322 static rtx simplify_or_tree (rtx, rtx *, int, int);
323 static rtx simplify_test_exp (rtx, int, int);
324 static rtx simplify_test_exp_in_temp (rtx, int, int);
325 static void optimize_attrs (void);
326 static void gen_attr (rtx, int);
327 static int count_alternatives (rtx);
328 static int compares_alternatives_p (rtx);
329 static int contained_in_p (rtx, rtx);
330 static void gen_insn (rtx, int);
331 static void gen_delay (rtx, int);
332 static void write_test_expr (rtx, int);
333 static int max_attr_value (rtx, int*);
334 static int or_attr_value (rtx, int*);
335 static void walk_attr_value (rtx);
336 static void write_attr_get (struct attr_desc *);
337 static rtx eliminate_known_true (rtx, rtx, int, int);
338 static void write_attr_set (struct attr_desc *, int, rtx,
339 const char *, const char *, rtx,
340 int, int);
341 static void write_attr_case (struct attr_desc *, struct attr_value *,
342 int, const char *, const char *, int, rtx);
343 static void write_attr_valueq (struct attr_desc *, const char *);
344 static void write_attr_value (struct attr_desc *, rtx);
345 static void write_upcase (const char *);
346 static void write_indent (int);
347 static void write_eligible_delay (const char *);
348 static int write_expr_attr_cache (rtx, struct attr_desc *);
349 static void write_const_num_delay_slots (void);
350 static char *next_comma_elt (const char **);
351 static struct attr_desc *find_attr (const char **, int);
352 static struct attr_value *find_most_used (struct attr_desc *);
353 static rtx attr_eq (const char *, const char *);
354 static const char *attr_numeral (int);
355 static int attr_equal_p (rtx, rtx);
356 static rtx attr_copy_rtx (rtx);
357 static int attr_rtx_cost (rtx);
358 static bool attr_alt_subset_p (rtx, rtx);
359 static bool attr_alt_subset_of_compl_p (rtx, rtx);
360 static rtx attr_alt_intersection (rtx, rtx);
361 static rtx attr_alt_union (rtx, rtx);
362 static rtx attr_alt_complement (rtx);
363 static bool attr_alt_bit_p (rtx, int);
364 static rtx mk_attr_alt (int);
366 #define oballoc(size) obstack_alloc (hash_obstack, size)
368 /* Hash table for sharing RTL and strings. */
370 /* Each hash table slot is a bucket containing a chain of these structures.
371 Strings are given negative hash codes; RTL expressions are given positive
372 hash codes. */
374 struct attr_hash
376 struct attr_hash *next; /* Next structure in the bucket. */
377 int hashcode; /* Hash code of this rtx or string. */
378 union
380 char *str; /* The string (negative hash codes) */
381 rtx rtl; /* or the RTL recorded here. */
382 } u;
385 /* Now here is the hash table. When recording an RTL, it is added to
386 the slot whose index is the hash code mod the table size. Note
387 that the hash table is used for several kinds of RTL (see attr_rtx)
388 and for strings. While all these live in the same table, they are
389 completely independent, and the hash code is computed differently
390 for each. */
392 #define RTL_HASH_SIZE 4093
393 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
395 /* Here is how primitive or already-shared RTL's hash
396 codes are made. */
397 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
399 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
401 static void
402 attr_hash_add_rtx (int hashcode, rtx rtl)
404 struct attr_hash *h;
406 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
407 h->hashcode = hashcode;
408 h->u.rtl = rtl;
409 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
410 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
413 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
415 static void
416 attr_hash_add_string (int hashcode, char *str)
418 struct attr_hash *h;
420 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
421 h->hashcode = -hashcode;
422 h->u.str = str;
423 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
424 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
427 /* Generate an RTL expression, but avoid duplicates.
428 Set the ATTR_PERMANENT_P flag for these permanent objects.
430 In some cases we cannot uniquify; then we return an ordinary
431 impermanent rtx with ATTR_PERMANENT_P clear.
433 Args are as follows:
435 rtx attr_rtx (code, [element1, ..., elementn]) */
437 static rtx
438 attr_rtx_1 (enum rtx_code code, va_list p)
440 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
441 int hashcode;
442 struct attr_hash *h;
443 struct obstack *old_obstack = rtl_obstack;
445 /* For each of several cases, search the hash table for an existing entry.
446 Use that entry if one is found; otherwise create a new RTL and add it
447 to the table. */
449 if (GET_RTX_CLASS (code) == RTX_UNARY)
451 rtx arg0 = va_arg (p, rtx);
453 /* A permanent object cannot point to impermanent ones. */
454 if (! ATTR_PERMANENT_P (arg0))
456 rt_val = rtx_alloc (code);
457 XEXP (rt_val, 0) = arg0;
458 return rt_val;
461 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
462 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
463 if (h->hashcode == hashcode
464 && GET_CODE (h->u.rtl) == code
465 && XEXP (h->u.rtl, 0) == arg0)
466 return h->u.rtl;
468 if (h == 0)
470 rtl_obstack = hash_obstack;
471 rt_val = rtx_alloc (code);
472 XEXP (rt_val, 0) = arg0;
475 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
476 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
477 || GET_RTX_CLASS (code) == RTX_COMPARE
478 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
480 rtx arg0 = va_arg (p, rtx);
481 rtx arg1 = va_arg (p, rtx);
483 /* A permanent object cannot point to impermanent ones. */
484 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
486 rt_val = rtx_alloc (code);
487 XEXP (rt_val, 0) = arg0;
488 XEXP (rt_val, 1) = arg1;
489 return rt_val;
492 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
493 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
494 if (h->hashcode == hashcode
495 && GET_CODE (h->u.rtl) == code
496 && XEXP (h->u.rtl, 0) == arg0
497 && XEXP (h->u.rtl, 1) == arg1)
498 return h->u.rtl;
500 if (h == 0)
502 rtl_obstack = hash_obstack;
503 rt_val = rtx_alloc (code);
504 XEXP (rt_val, 0) = arg0;
505 XEXP (rt_val, 1) = arg1;
508 else if (GET_RTX_LENGTH (code) == 1
509 && GET_RTX_FORMAT (code)[0] == 's')
511 char *arg0 = va_arg (p, char *);
513 arg0 = DEF_ATTR_STRING (arg0);
515 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
516 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
517 if (h->hashcode == hashcode
518 && GET_CODE (h->u.rtl) == code
519 && XSTR (h->u.rtl, 0) == arg0)
520 return h->u.rtl;
522 if (h == 0)
524 rtl_obstack = hash_obstack;
525 rt_val = rtx_alloc (code);
526 XSTR (rt_val, 0) = arg0;
529 else if (GET_RTX_LENGTH (code) == 2
530 && GET_RTX_FORMAT (code)[0] == 's'
531 && GET_RTX_FORMAT (code)[1] == 's')
533 char *arg0 = va_arg (p, char *);
534 char *arg1 = va_arg (p, char *);
536 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
537 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
538 if (h->hashcode == hashcode
539 && GET_CODE (h->u.rtl) == code
540 && XSTR (h->u.rtl, 0) == arg0
541 && XSTR (h->u.rtl, 1) == arg1)
542 return h->u.rtl;
544 if (h == 0)
546 rtl_obstack = hash_obstack;
547 rt_val = rtx_alloc (code);
548 XSTR (rt_val, 0) = arg0;
549 XSTR (rt_val, 1) = arg1;
552 else if (code == CONST_INT)
554 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
555 if (arg0 == 0)
556 return false_rtx;
557 else if (arg0 == 1)
558 return true_rtx;
559 else
560 goto nohash;
562 else
564 int i; /* Array indices... */
565 const char *fmt; /* Current rtx's format... */
566 nohash:
567 rt_val = rtx_alloc (code); /* Allocate the storage space. */
569 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
570 for (i = 0; i < GET_RTX_LENGTH (code); i++)
572 switch (*fmt++)
574 case '0': /* Unused field. */
575 break;
577 case 'i': /* An integer? */
578 XINT (rt_val, i) = va_arg (p, int);
579 break;
581 case 'w': /* A wide integer? */
582 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
583 break;
585 case 's': /* A string? */
586 XSTR (rt_val, i) = va_arg (p, char *);
587 break;
589 case 'e': /* An expression? */
590 case 'u': /* An insn? Same except when printing. */
591 XEXP (rt_val, i) = va_arg (p, rtx);
592 break;
594 case 'E': /* An RTX vector? */
595 XVEC (rt_val, i) = va_arg (p, rtvec);
596 break;
598 default:
599 abort ();
602 return rt_val;
605 rtl_obstack = old_obstack;
606 attr_hash_add_rtx (hashcode, rt_val);
607 ATTR_PERMANENT_P (rt_val) = 1;
608 return rt_val;
611 static rtx
612 attr_rtx (enum rtx_code code, ...)
614 rtx result;
615 va_list p;
617 va_start (p, code);
618 result = attr_rtx_1 (code, p);
619 va_end (p);
620 return result;
623 /* Create a new string printed with the printf line arguments into a space
624 of at most LEN bytes:
626 rtx attr_printf (len, format, [arg1, ..., argn]) */
628 char *
629 attr_printf (unsigned int len, const char *fmt, ...)
631 char str[256];
632 va_list p;
634 va_start (p, fmt);
636 if (len > sizeof str - 1) /* Leave room for \0. */
637 abort ();
639 vsprintf (str, fmt, p);
640 va_end (p);
642 return DEF_ATTR_STRING (str);
645 static rtx
646 attr_eq (const char *name, const char *value)
648 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
651 static const char *
652 attr_numeral (int n)
654 return XSTR (make_numeric_value (n), 0);
657 /* Return a permanent (possibly shared) copy of a string STR (not assumed
658 to be null terminated) with LEN bytes. */
660 static char *
661 attr_string (const char *str, int len)
663 struct attr_hash *h;
664 int hashcode;
665 int i;
666 char *new_str;
668 /* Compute the hash code. */
669 hashcode = (len + 1) * 613 + (unsigned) str[0];
670 for (i = 1; i <= len; i += 2)
671 hashcode = ((hashcode * 613) + (unsigned) str[i]);
672 if (hashcode < 0)
673 hashcode = -hashcode;
675 /* Search the table for the string. */
676 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
677 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
678 && !strncmp (h->u.str, str, len))
679 return h->u.str; /* <-- return if found. */
681 /* Not found; create a permanent copy and add it to the hash table. */
682 new_str = obstack_alloc (hash_obstack, len + 1);
683 memcpy (new_str, str, len);
684 new_str[len] = '\0';
685 attr_hash_add_string (hashcode, new_str);
687 return new_str; /* Return the new string. */
690 /* Check two rtx's for equality of contents,
691 taking advantage of the fact that if both are hashed
692 then they can't be equal unless they are the same object. */
694 static int
695 attr_equal_p (rtx x, rtx y)
697 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
698 && rtx_equal_p (x, y)));
701 /* Copy an attribute value expression,
702 descending to all depths, but not copying any
703 permanent hashed subexpressions. */
705 static rtx
706 attr_copy_rtx (rtx orig)
708 rtx copy;
709 int i, j;
710 RTX_CODE code;
711 const char *format_ptr;
713 /* No need to copy a permanent object. */
714 if (ATTR_PERMANENT_P (orig))
715 return orig;
717 code = GET_CODE (orig);
719 switch (code)
721 case REG:
722 case CONST_INT:
723 case CONST_DOUBLE:
724 case CONST_VECTOR:
725 case SYMBOL_REF:
726 case CODE_LABEL:
727 case PC:
728 case CC0:
729 return orig;
731 default:
732 break;
735 copy = rtx_alloc (code);
736 PUT_MODE (copy, GET_MODE (orig));
737 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
738 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
739 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
740 ATTR_EQ_ATTR_P (copy) = ATTR_EQ_ATTR_P (orig);
742 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
744 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
746 switch (*format_ptr++)
748 case 'e':
749 XEXP (copy, i) = XEXP (orig, i);
750 if (XEXP (orig, i) != NULL)
751 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
752 break;
754 case 'E':
755 case 'V':
756 XVEC (copy, i) = XVEC (orig, i);
757 if (XVEC (orig, i) != NULL)
759 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
760 for (j = 0; j < XVECLEN (copy, i); j++)
761 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
763 break;
765 case 'n':
766 case 'i':
767 XINT (copy, i) = XINT (orig, i);
768 break;
770 case 'w':
771 XWINT (copy, i) = XWINT (orig, i);
772 break;
774 case 's':
775 case 'S':
776 XSTR (copy, i) = XSTR (orig, i);
777 break;
779 default:
780 abort ();
783 return copy;
786 /* Given a test expression for an attribute, ensure it is validly formed.
787 IS_CONST indicates whether the expression is constant for each compiler
788 run (a constant expression may not test any particular insn).
790 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
791 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
792 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
794 Update the string address in EQ_ATTR expression to be the same used
795 in the attribute (or `alternative_name') to speed up subsequent
796 `find_attr' calls and eliminate most `strcmp' calls.
798 Return the new expression, if any. */
801 check_attr_test (rtx exp, int is_const, int lineno)
803 struct attr_desc *attr;
804 struct attr_value *av;
805 const char *name_ptr, *p;
806 rtx orexp, newexp;
808 switch (GET_CODE (exp))
810 case EQ_ATTR:
811 /* Handle negation test. */
812 if (XSTR (exp, 1)[0] == '!')
813 return check_attr_test (attr_rtx (NOT,
814 attr_eq (XSTR (exp, 0),
815 &XSTR (exp, 1)[1])),
816 is_const, lineno);
818 else if (n_comma_elts (XSTR (exp, 1)) == 1)
820 attr = find_attr (&XSTR (exp, 0), 0);
821 if (attr == NULL)
823 if (! strcmp (XSTR (exp, 0), "alternative"))
824 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
825 else
826 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
829 if (is_const && ! attr->is_const)
830 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
831 XSTR (exp, 0));
833 /* Copy this just to make it permanent,
834 so expressions using it can be permanent too. */
835 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
837 /* It shouldn't be possible to simplify the value given to a
838 constant attribute, so don't expand this until it's time to
839 write the test expression. */
840 if (attr->is_const)
841 ATTR_IND_SIMPLIFIED_P (exp) = 1;
843 if (attr->is_numeric)
845 for (p = XSTR (exp, 1); *p; p++)
846 if (! ISDIGIT (*p))
847 fatal ("attribute `%s' takes only numeric values",
848 XSTR (exp, 0));
850 else
852 for (av = attr->first_value; av; av = av->next)
853 if (GET_CODE (av->value) == CONST_STRING
854 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
855 break;
857 if (av == NULL)
858 fatal ("unknown value `%s' for `%s' attribute",
859 XSTR (exp, 1), XSTR (exp, 0));
862 else
864 if (! strcmp (XSTR (exp, 0), "alternative"))
866 int set = 0;
868 name_ptr = XSTR (exp, 1);
869 while ((p = next_comma_elt (&name_ptr)) != NULL)
870 set |= 1 << atoi (p);
872 return mk_attr_alt (set);
874 else
876 /* Make an IOR tree of the possible values. */
877 orexp = false_rtx;
878 name_ptr = XSTR (exp, 1);
879 while ((p = next_comma_elt (&name_ptr)) != NULL)
881 newexp = attr_eq (XSTR (exp, 0), p);
882 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
885 return check_attr_test (orexp, is_const, lineno);
888 break;
890 case ATTR_FLAG:
891 break;
893 case CONST_INT:
894 /* Either TRUE or FALSE. */
895 if (XWINT (exp, 0))
896 return true_rtx;
897 else
898 return false_rtx;
900 case IOR:
901 case AND:
902 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
903 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
904 break;
906 case NOT:
907 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
908 break;
910 case MATCH_OPERAND:
911 if (is_const)
912 fatal ("RTL operator \"%s\" not valid in constant attribute test",
913 GET_RTX_NAME (GET_CODE (exp)));
914 /* These cases can't be simplified. */
915 ATTR_IND_SIMPLIFIED_P (exp) = 1;
916 break;
918 case LE: case LT: case GT: case GE:
919 case LEU: case LTU: case GTU: case GEU:
920 case NE: case EQ:
921 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
922 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
923 exp = attr_rtx (GET_CODE (exp),
924 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
925 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
926 /* These cases can't be simplified. */
927 ATTR_IND_SIMPLIFIED_P (exp) = 1;
928 break;
930 case SYMBOL_REF:
931 if (is_const)
933 /* These cases are valid for constant attributes, but can't be
934 simplified. */
935 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
936 ATTR_IND_SIMPLIFIED_P (exp) = 1;
937 break;
939 default:
940 fatal ("RTL operator \"%s\" not valid in attribute test",
941 GET_RTX_NAME (GET_CODE (exp)));
944 return exp;
947 /* Given an expression, ensure that it is validly formed and that all named
948 attribute values are valid for the given attribute. Issue a fatal error
949 if not. If no attribute is specified, assume a numeric attribute.
951 Return a perhaps modified replacement expression for the value. */
953 static rtx
954 check_attr_value (rtx exp, struct attr_desc *attr)
956 struct attr_value *av;
957 const char *p;
958 int i;
960 switch (GET_CODE (exp))
962 case CONST_INT:
963 if (attr && ! attr->is_numeric)
965 message_with_line (attr->lineno,
966 "CONST_INT not valid for non-numeric attribute %s",
967 attr->name);
968 have_error = 1;
969 break;
972 if (INTVAL (exp) < 0 && ! attr->negative_ok)
974 message_with_line (attr->lineno,
975 "negative numeric value specified for attribute %s",
976 attr->name);
977 have_error = 1;
978 break;
980 break;
982 case CONST_STRING:
983 if (! strcmp (XSTR (exp, 0), "*"))
984 break;
986 if (attr == 0 || attr->is_numeric)
988 p = XSTR (exp, 0);
989 if (attr && attr->negative_ok && *p == '-')
990 p++;
991 for (; *p; p++)
992 if (! ISDIGIT (*p))
994 message_with_line (attr ? attr->lineno : 0,
995 "non-numeric value for numeric attribute %s",
996 attr ? attr->name : "internal");
997 have_error = 1;
998 break;
1000 break;
1003 for (av = attr->first_value; av; av = av->next)
1004 if (GET_CODE (av->value) == CONST_STRING
1005 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1006 break;
1008 if (av == NULL)
1010 message_with_line (attr->lineno,
1011 "unknown value `%s' for `%s' attribute",
1012 XSTR (exp, 0), attr ? attr->name : "internal");
1013 have_error = 1;
1015 break;
1017 case IF_THEN_ELSE:
1018 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1019 attr ? attr->is_const : 0,
1020 attr ? attr->lineno : 0);
1021 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1022 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1023 break;
1025 case PLUS:
1026 case MINUS:
1027 case MULT:
1028 case DIV:
1029 case MOD:
1030 if (attr && !attr->is_numeric)
1032 message_with_line (attr->lineno,
1033 "invalid operation `%s' for non-numeric attribute value",
1034 GET_RTX_NAME (GET_CODE (exp)));
1035 have_error = 1;
1036 break;
1038 /* Fall through. */
1040 case IOR:
1041 case AND:
1042 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1043 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1044 break;
1046 case FFS:
1047 case CLZ:
1048 case CTZ:
1049 case POPCOUNT:
1050 case PARITY:
1051 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1052 break;
1054 case COND:
1055 if (XVECLEN (exp, 0) % 2 != 0)
1057 message_with_line (attr->lineno,
1058 "first operand of COND must have even length");
1059 have_error = 1;
1060 break;
1063 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1065 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1066 attr ? attr->is_const : 0,
1067 attr ? attr->lineno : 0);
1068 XVECEXP (exp, 0, i + 1)
1069 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1072 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1073 break;
1075 case ATTR:
1077 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1078 if (attr2 == NULL)
1080 message_with_line (attr ? attr->lineno : 0,
1081 "unknown attribute `%s' in ATTR",
1082 XSTR (exp, 0));
1083 have_error = 1;
1085 else if (attr && attr->is_const && ! attr2->is_const)
1087 message_with_line (attr->lineno,
1088 "non-constant attribute `%s' referenced from `%s'",
1089 XSTR (exp, 0), attr->name);
1090 have_error = 1;
1092 else if (attr
1093 && (attr->is_numeric != attr2->is_numeric
1094 || (! attr->negative_ok && attr2->negative_ok)))
1096 message_with_line (attr->lineno,
1097 "numeric attribute mismatch calling `%s' from `%s'",
1098 XSTR (exp, 0), attr->name);
1099 have_error = 1;
1102 break;
1104 case SYMBOL_REF:
1105 /* A constant SYMBOL_REF is valid as a constant attribute test and
1106 is expanded later by make_canonical into a COND. In a non-constant
1107 attribute test, it is left be. */
1108 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1110 default:
1111 message_with_line (attr ? attr->lineno : 0,
1112 "invalid operation `%s' for attribute value",
1113 GET_RTX_NAME (GET_CODE (exp)));
1114 have_error = 1;
1115 break;
1118 return exp;
1121 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1122 It becomes a COND with each test being (eq_attr "alternative "n") */
1124 static rtx
1125 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1127 int num_alt = id->num_alternatives;
1128 rtx condexp;
1129 int i;
1131 if (XVECLEN (exp, 1) != num_alt)
1133 message_with_line (id->lineno,
1134 "bad number of entries in SET_ATTR_ALTERNATIVE");
1135 have_error = 1;
1136 return NULL_RTX;
1139 /* Make a COND with all tests but the last. Select the last value via the
1140 default. */
1141 condexp = rtx_alloc (COND);
1142 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1144 for (i = 0; i < num_alt - 1; i++)
1146 const char *p;
1147 p = attr_numeral (i);
1149 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1150 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1153 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1155 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1158 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1159 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1161 static rtx
1162 convert_set_attr (rtx exp, struct insn_def *id)
1164 rtx newexp;
1165 const char *name_ptr;
1166 char *p;
1167 int n;
1169 /* See how many alternative specified. */
1170 n = n_comma_elts (XSTR (exp, 1));
1171 if (n == 1)
1172 return attr_rtx (SET,
1173 attr_rtx (ATTR, XSTR (exp, 0)),
1174 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1176 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1177 XSTR (newexp, 0) = XSTR (exp, 0);
1178 XVEC (newexp, 1) = rtvec_alloc (n);
1180 /* Process each comma-separated name. */
1181 name_ptr = XSTR (exp, 1);
1182 n = 0;
1183 while ((p = next_comma_elt (&name_ptr)) != NULL)
1184 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1186 return convert_set_attr_alternative (newexp, id);
1189 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1190 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1191 expressions. */
1193 static void
1194 check_defs (void)
1196 struct insn_def *id;
1197 struct attr_desc *attr;
1198 int i;
1199 rtx value;
1201 for (id = defs; id; id = id->next)
1203 if (XVEC (id->def, id->vec_idx) == NULL)
1204 continue;
1206 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1208 value = XVECEXP (id->def, id->vec_idx, i);
1209 switch (GET_CODE (value))
1211 case SET:
1212 if (GET_CODE (XEXP (value, 0)) != ATTR)
1214 message_with_line (id->lineno, "bad attribute set");
1215 have_error = 1;
1216 value = NULL_RTX;
1218 break;
1220 case SET_ATTR_ALTERNATIVE:
1221 value = convert_set_attr_alternative (value, id);
1222 break;
1224 case SET_ATTR:
1225 value = convert_set_attr (value, id);
1226 break;
1228 default:
1229 message_with_line (id->lineno, "invalid attribute code %s",
1230 GET_RTX_NAME (GET_CODE (value)));
1231 have_error = 1;
1232 value = NULL_RTX;
1234 if (value == NULL_RTX)
1235 continue;
1237 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1239 message_with_line (id->lineno, "unknown attribute %s",
1240 XSTR (XEXP (value, 0), 0));
1241 have_error = 1;
1242 continue;
1245 XVECEXP (id->def, id->vec_idx, i) = value;
1246 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1251 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1252 expressions by converting them into a COND. This removes cases from this
1253 program. Also, replace an attribute value of "*" with the default attribute
1254 value. */
1256 static rtx
1257 make_canonical (struct attr_desc *attr, rtx exp)
1259 int i;
1260 rtx newexp;
1262 switch (GET_CODE (exp))
1264 case CONST_INT:
1265 exp = make_numeric_value (INTVAL (exp));
1266 break;
1268 case CONST_STRING:
1269 if (! strcmp (XSTR (exp, 0), "*"))
1271 if (attr == 0 || attr->default_val == 0)
1272 fatal ("(attr_value \"*\") used in invalid context");
1273 exp = attr->default_val->value;
1275 else
1276 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1278 break;
1280 case SYMBOL_REF:
1281 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1282 break;
1283 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1284 This makes the COND something that won't be considered an arbitrary
1285 expression by walk_attr_value. */
1286 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1287 exp = check_attr_value (exp, attr);
1288 break;
1290 case IF_THEN_ELSE:
1291 newexp = rtx_alloc (COND);
1292 XVEC (newexp, 0) = rtvec_alloc (2);
1293 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1294 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1296 XEXP (newexp, 1) = XEXP (exp, 2);
1298 exp = newexp;
1299 /* Fall through to COND case since this is now a COND. */
1301 case COND:
1303 int allsame = 1;
1304 rtx defval;
1306 /* First, check for degenerate COND. */
1307 if (XVECLEN (exp, 0) == 0)
1308 return make_canonical (attr, XEXP (exp, 1));
1309 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1311 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1313 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1314 XVECEXP (exp, 0, i + 1)
1315 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1316 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1317 allsame = 0;
1319 if (allsame)
1320 return defval;
1322 break;
1324 default:
1325 break;
1328 return exp;
1331 static rtx
1332 copy_boolean (rtx exp)
1334 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1335 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1336 copy_boolean (XEXP (exp, 1)));
1337 if (GET_CODE (exp) == MATCH_OPERAND)
1339 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1340 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1342 else if (GET_CODE (exp) == EQ_ATTR)
1344 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1345 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1348 return exp;
1351 /* Given a value and an attribute description, return a `struct attr_value *'
1352 that represents that value. This is either an existing structure, if the
1353 value has been previously encountered, or a newly-created structure.
1355 `insn_code' is the code of an insn whose attribute has the specified
1356 value (-2 if not processing an insn). We ensure that all insns for
1357 a given value have the same number of alternatives if the value checks
1358 alternatives. */
1360 static struct attr_value *
1361 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1363 struct attr_value *av;
1364 int num_alt = 0;
1366 value = make_canonical (attr, value);
1367 if (compares_alternatives_p (value))
1369 if (insn_code < 0 || insn_alternatives == NULL)
1370 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1371 else
1372 num_alt = insn_alternatives[insn_code];
1375 for (av = attr->first_value; av; av = av->next)
1376 if (rtx_equal_p (value, av->value)
1377 && (num_alt == 0 || av->first_insn == NULL
1378 || insn_alternatives[av->first_insn->def->insn_code]))
1379 return av;
1381 av = oballoc (sizeof (struct attr_value));
1382 av->value = value;
1383 av->next = attr->first_value;
1384 attr->first_value = av;
1385 av->first_insn = NULL;
1386 av->num_insns = 0;
1387 av->has_asm_insn = 0;
1389 return av;
1392 /* After all DEFINE_DELAYs have been read in, create internal attributes
1393 to generate the required routines.
1395 First, we compute the number of delay slots for each insn (as a COND of
1396 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1397 delay type is specified, we compute a similar function giving the
1398 DEFINE_DELAY ordinal for each insn.
1400 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1401 tells whether a given insn can be in that delay slot.
1403 Normal attribute filling and optimization expands these to contain the
1404 information needed to handle delay slots. */
1406 static void
1407 expand_delays (void)
1409 struct delay_desc *delay;
1410 rtx condexp;
1411 rtx newexp;
1412 int i;
1413 char *p;
1415 /* First, generate data for `num_delay_slots' function. */
1417 condexp = rtx_alloc (COND);
1418 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1419 XEXP (condexp, 1) = make_numeric_value (0);
1421 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1423 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1424 XVECEXP (condexp, 0, i + 1)
1425 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1428 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1430 /* If more than one delay type, do the same for computing the delay type. */
1431 if (num_delays > 1)
1433 condexp = rtx_alloc (COND);
1434 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1435 XEXP (condexp, 1) = make_numeric_value (0);
1437 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1439 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1440 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1443 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1446 /* For each delay possibility and delay slot, compute an eligibility
1447 attribute for non-annulled insns and for each type of annulled (annul
1448 if true and annul if false). */
1449 for (delay = delays; delay; delay = delay->next)
1451 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1453 condexp = XVECEXP (delay->def, 1, i);
1454 if (condexp == 0)
1455 condexp = false_rtx;
1456 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1457 make_numeric_value (1), make_numeric_value (0));
1459 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1460 "*delay_%d_%d", delay->num, i / 3);
1461 make_internal_attr (p, newexp, ATTR_SPECIAL);
1463 if (have_annul_true)
1465 condexp = XVECEXP (delay->def, 1, i + 1);
1466 if (condexp == 0) condexp = false_rtx;
1467 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1468 make_numeric_value (1),
1469 make_numeric_value (0));
1470 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1471 "*annul_true_%d_%d", delay->num, i / 3);
1472 make_internal_attr (p, newexp, ATTR_SPECIAL);
1475 if (have_annul_false)
1477 condexp = XVECEXP (delay->def, 1, i + 2);
1478 if (condexp == 0) condexp = false_rtx;
1479 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1480 make_numeric_value (1),
1481 make_numeric_value (0));
1482 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1483 "*annul_false_%d_%d", delay->num, i / 3);
1484 make_internal_attr (p, newexp, ATTR_SPECIAL);
1490 /* Once all attributes and insns have been read and checked, we construct for
1491 each attribute value a list of all the insns that have that value for
1492 the attribute. */
1494 static void
1495 fill_attr (struct attr_desc *attr)
1497 struct attr_value *av;
1498 struct insn_ent *ie;
1499 struct insn_def *id;
1500 int i;
1501 rtx value;
1503 /* Don't fill constant attributes. The value is independent of
1504 any particular insn. */
1505 if (attr->is_const)
1506 return;
1508 for (id = defs; id; id = id->next)
1510 /* If no value is specified for this insn for this attribute, use the
1511 default. */
1512 value = NULL;
1513 if (XVEC (id->def, id->vec_idx))
1514 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1515 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1516 attr->name))
1517 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1519 if (value == NULL)
1520 av = attr->default_val;
1521 else
1522 av = get_attr_value (value, attr, id->insn_code);
1524 ie = oballoc (sizeof (struct insn_ent));
1525 ie->def = id;
1526 insert_insn_ent (av, ie);
1530 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1531 test that checks relative positions of insns (uses MATCH_DUP or PC).
1532 If so, replace it with what is obtained by passing the expression to
1533 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1534 recursively on each value (including the default value). Otherwise,
1535 return the value returned by NO_ADDRESS_FN applied to EXP. */
1537 static rtx
1538 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1539 rtx (*address_fn) (rtx))
1541 int i;
1542 rtx newexp;
1544 if (GET_CODE (exp) == COND)
1546 /* See if any tests use addresses. */
1547 address_used = 0;
1548 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1549 walk_attr_value (XVECEXP (exp, 0, i));
1551 if (address_used)
1552 return (*address_fn) (exp);
1554 /* Make a new copy of this COND, replacing each element. */
1555 newexp = rtx_alloc (COND);
1556 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1557 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1559 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1560 XVECEXP (newexp, 0, i + 1)
1561 = substitute_address (XVECEXP (exp, 0, i + 1),
1562 no_address_fn, address_fn);
1565 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1566 no_address_fn, address_fn);
1568 return newexp;
1571 else if (GET_CODE (exp) == IF_THEN_ELSE)
1573 address_used = 0;
1574 walk_attr_value (XEXP (exp, 0));
1575 if (address_used)
1576 return (*address_fn) (exp);
1578 return attr_rtx (IF_THEN_ELSE,
1579 substitute_address (XEXP (exp, 0),
1580 no_address_fn, address_fn),
1581 substitute_address (XEXP (exp, 1),
1582 no_address_fn, address_fn),
1583 substitute_address (XEXP (exp, 2),
1584 no_address_fn, address_fn));
1587 return (*no_address_fn) (exp);
1590 /* Make new attributes from the `length' attribute. The following are made,
1591 each corresponding to a function called from `shorten_branches' or
1592 `get_attr_length':
1594 *insn_default_length This is the length of the insn to be returned
1595 by `get_attr_length' before `shorten_branches'
1596 has been called. In each case where the length
1597 depends on relative addresses, the largest
1598 possible is used. This routine is also used
1599 to compute the initial size of the insn.
1601 *insn_variable_length_p This returns 1 if the insn's length depends
1602 on relative addresses, zero otherwise.
1604 *insn_current_length This is only called when it is known that the
1605 insn has a variable length and returns the
1606 current length, based on relative addresses.
1609 static void
1610 make_length_attrs (void)
1612 static const char *new_names[] =
1614 "*insn_default_length",
1615 "*insn_variable_length_p",
1616 "*insn_current_length"
1618 static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn};
1619 static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn};
1620 size_t i;
1621 struct attr_desc *length_attr, *new_attr;
1622 struct attr_value *av, *new_av;
1623 struct insn_ent *ie, *new_ie;
1625 /* See if length attribute is defined. If so, it must be numeric. Make
1626 it special so we don't output anything for it. */
1627 length_attr = find_attr (&length_str, 0);
1628 if (length_attr == 0)
1629 return;
1631 if (! length_attr->is_numeric)
1632 fatal ("length attribute must be numeric");
1634 length_attr->is_const = 0;
1635 length_attr->is_special = 1;
1637 /* Make each new attribute, in turn. */
1638 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1640 make_internal_attr (new_names[i],
1641 substitute_address (length_attr->default_val->value,
1642 no_address_fn[i], address_fn[i]),
1643 ATTR_NONE);
1644 new_attr = find_attr (&new_names[i], 0);
1645 for (av = length_attr->first_value; av; av = av->next)
1646 for (ie = av->first_insn; ie; ie = ie->next)
1648 new_av = get_attr_value (substitute_address (av->value,
1649 no_address_fn[i],
1650 address_fn[i]),
1651 new_attr, ie->def->insn_code);
1652 new_ie = oballoc (sizeof (struct insn_ent));
1653 new_ie->def = ie->def;
1654 insert_insn_ent (new_av, new_ie);
1659 /* Utility functions called from above routine. */
1661 static rtx
1662 identity_fn (rtx exp)
1664 return exp;
1667 static rtx
1668 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1670 return make_numeric_value (0);
1673 static rtx
1674 one_fn (rtx exp ATTRIBUTE_UNUSED)
1676 return make_numeric_value (1);
1679 static rtx
1680 max_fn (rtx exp)
1682 int unknown;
1683 return make_numeric_value (max_attr_value (exp, &unknown));
1686 static void
1687 write_length_unit_log (void)
1689 struct attr_desc *length_attr = find_attr (&length_str, 0);
1690 struct attr_value *av;
1691 struct insn_ent *ie;
1692 unsigned int length_unit_log, length_or;
1693 int unknown = 0;
1695 if (length_attr == 0)
1696 return;
1697 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1698 for (av = length_attr->first_value; av; av = av->next)
1699 for (ie = av->first_insn; ie; ie = ie->next)
1700 length_or |= or_attr_value (av->value, &unknown);
1702 if (unknown)
1703 length_unit_log = 0;
1704 else
1706 length_or = ~length_or;
1707 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1708 length_unit_log++;
1710 printf ("int length_unit_log = %u;\n", length_unit_log);
1713 /* Take a COND expression and see if any of the conditions in it can be
1714 simplified. If any are known true or known false for the particular insn
1715 code, the COND can be further simplified.
1717 Also call ourselves on any COND operations that are values of this COND.
1719 We do not modify EXP; rather, we make and return a new rtx. */
1721 static rtx
1722 simplify_cond (rtx exp, int insn_code, int insn_index)
1724 int i, j;
1725 /* We store the desired contents here,
1726 then build a new expression if they don't match EXP. */
1727 rtx defval = XEXP (exp, 1);
1728 rtx new_defval = XEXP (exp, 1);
1729 int len = XVECLEN (exp, 0);
1730 rtx *tests = xmalloc (len * sizeof (rtx));
1731 int allsame = 1;
1732 rtx ret;
1734 /* This lets us free all storage allocated below, if appropriate. */
1735 obstack_finish (rtl_obstack);
1737 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1739 /* See if default value needs simplification. */
1740 if (GET_CODE (defval) == COND)
1741 new_defval = simplify_cond (defval, insn_code, insn_index);
1743 /* Simplify the subexpressions, and see what tests we can get rid of. */
1745 for (i = 0; i < len; i += 2)
1747 rtx newtest, newval;
1749 /* Simplify this test. */
1750 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1751 tests[i] = newtest;
1753 newval = tests[i + 1];
1754 /* See if this value may need simplification. */
1755 if (GET_CODE (newval) == COND)
1756 newval = simplify_cond (newval, insn_code, insn_index);
1758 /* Look for ways to delete or combine this test. */
1759 if (newtest == true_rtx)
1761 /* If test is true, make this value the default
1762 and discard this + any following tests. */
1763 len = i;
1764 defval = tests[i + 1];
1765 new_defval = newval;
1768 else if (newtest == false_rtx)
1770 /* If test is false, discard it and its value. */
1771 for (j = i; j < len - 2; j++)
1772 tests[j] = tests[j + 2];
1773 i -= 2;
1774 len -= 2;
1777 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1779 /* If this value and the value for the prev test are the same,
1780 merge the tests. */
1782 tests[i - 2]
1783 = insert_right_side (IOR, tests[i - 2], newtest,
1784 insn_code, insn_index);
1786 /* Delete this test/value. */
1787 for (j = i; j < len - 2; j++)
1788 tests[j] = tests[j + 2];
1789 len -= 2;
1790 i -= 2;
1793 else
1794 tests[i + 1] = newval;
1797 /* If the last test in a COND has the same value
1798 as the default value, that test isn't needed. */
1800 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1801 len -= 2;
1803 /* See if we changed anything. */
1804 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1805 allsame = 0;
1806 else
1807 for (i = 0; i < len; i++)
1808 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1810 allsame = 0;
1811 break;
1814 if (len == 0)
1816 if (GET_CODE (defval) == COND)
1817 ret = simplify_cond (defval, insn_code, insn_index);
1818 else
1819 ret = defval;
1821 else if (allsame)
1822 ret = exp;
1823 else
1825 rtx newexp = rtx_alloc (COND);
1827 XVEC (newexp, 0) = rtvec_alloc (len);
1828 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1829 XEXP (newexp, 1) = new_defval;
1830 ret = newexp;
1832 free (tests);
1833 return ret;
1836 /* Remove an insn entry from an attribute value. */
1838 static void
1839 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1841 struct insn_ent *previe;
1843 if (av->first_insn == ie)
1844 av->first_insn = ie->next;
1845 else
1847 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1849 previe->next = ie->next;
1852 av->num_insns--;
1853 if (ie->def->insn_code == -1)
1854 av->has_asm_insn = 0;
1856 num_insn_ents--;
1859 /* Insert an insn entry in an attribute value list. */
1861 static void
1862 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1864 ie->next = av->first_insn;
1865 av->first_insn = ie;
1866 av->num_insns++;
1867 if (ie->def->insn_code == -1)
1868 av->has_asm_insn = 1;
1870 num_insn_ents++;
1873 /* This is a utility routine to take an expression that is a tree of either
1874 AND or IOR expressions and insert a new term. The new term will be
1875 inserted at the right side of the first node whose code does not match
1876 the root. A new node will be created with the root's code. Its left
1877 side will be the old right side and its right side will be the new
1878 term.
1880 If the `term' is itself a tree, all its leaves will be inserted. */
1882 static rtx
1883 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1885 rtx newexp;
1887 /* Avoid consing in some special cases. */
1888 if (code == AND && term == true_rtx)
1889 return exp;
1890 if (code == AND && term == false_rtx)
1891 return false_rtx;
1892 if (code == AND && exp == true_rtx)
1893 return term;
1894 if (code == AND && exp == false_rtx)
1895 return false_rtx;
1896 if (code == IOR && term == true_rtx)
1897 return true_rtx;
1898 if (code == IOR && term == false_rtx)
1899 return exp;
1900 if (code == IOR && exp == true_rtx)
1901 return true_rtx;
1902 if (code == IOR && exp == false_rtx)
1903 return term;
1904 if (attr_equal_p (exp, term))
1905 return exp;
1907 if (GET_CODE (term) == code)
1909 exp = insert_right_side (code, exp, XEXP (term, 0),
1910 insn_code, insn_index);
1911 exp = insert_right_side (code, exp, XEXP (term, 1),
1912 insn_code, insn_index);
1914 return exp;
1917 if (GET_CODE (exp) == code)
1919 rtx new = insert_right_side (code, XEXP (exp, 1),
1920 term, insn_code, insn_index);
1921 if (new != XEXP (exp, 1))
1922 /* Make a copy of this expression and call recursively. */
1923 newexp = attr_rtx (code, XEXP (exp, 0), new);
1924 else
1925 newexp = exp;
1927 else
1929 /* Insert the new term. */
1930 newexp = attr_rtx (code, exp, term);
1933 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1936 /* If we have an expression which AND's a bunch of
1937 (not (eq_attrq "alternative" "n"))
1938 terms, we may have covered all or all but one of the possible alternatives.
1939 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1941 This routine is passed an expression and either AND or IOR. It returns a
1942 bitmask indicating which alternatives are mentioned within EXP. */
1944 static int
1945 compute_alternative_mask (rtx exp, enum rtx_code code)
1947 const char *string;
1948 if (GET_CODE (exp) == code)
1949 return compute_alternative_mask (XEXP (exp, 0), code)
1950 | compute_alternative_mask (XEXP (exp, 1), code);
1952 else if (code == AND && GET_CODE (exp) == NOT
1953 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1954 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1955 string = XSTR (XEXP (exp, 0), 1);
1957 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1958 && XSTR (exp, 0) == alternative_name)
1959 string = XSTR (exp, 1);
1961 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1963 if (code == AND && XINT (exp, 1))
1964 return XINT (exp, 0);
1966 if (code == IOR && !XINT (exp, 1))
1967 return XINT (exp, 0);
1969 return 0;
1971 else
1972 return 0;
1974 if (string[1] == 0)
1975 return 1 << (string[0] - '0');
1976 return 1 << atoi (string);
1979 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1980 attribute with the value represented by that bit. */
1982 static rtx
1983 make_alternative_compare (int mask)
1985 return mk_attr_alt (mask);
1988 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1989 of "attr" for this insn code. From that value, we can compute a test
1990 showing when the EQ_ATTR will be true. This routine performs that
1991 computation. If a test condition involves an address, we leave the EQ_ATTR
1992 intact because addresses are only valid for the `length' attribute.
1994 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1995 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1997 static rtx
1998 evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
2000 rtx orexp, andexp;
2001 rtx right;
2002 rtx newexp;
2003 int i;
2005 if (GET_CODE (value) == CONST_STRING)
2007 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
2008 newexp = true_rtx;
2009 else
2010 newexp = false_rtx;
2012 else if (GET_CODE (value) == SYMBOL_REF)
2014 char *p;
2015 char string[256];
2017 if (GET_CODE (exp) != EQ_ATTR)
2018 abort ();
2020 if (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 > 256)
2021 abort ();
2023 strcpy (string, XSTR (exp, 0));
2024 strcat (string, "_");
2025 strcat (string, XSTR (exp, 1));
2026 for (p = string; *p; p++)
2027 *p = TOUPPER (*p);
2029 newexp = attr_rtx (EQ, value,
2030 attr_rtx (SYMBOL_REF,
2031 DEF_ATTR_STRING (string)));
2033 else if (GET_CODE (value) == COND)
2035 /* We construct an IOR of all the cases for which the requested attribute
2036 value is present. Since we start with FALSE, if it is not present,
2037 FALSE will be returned.
2039 Each case is the AND of the NOT's of the previous conditions with the
2040 current condition; in the default case the current condition is TRUE.
2042 For each possible COND value, call ourselves recursively.
2044 The extra TRUE and FALSE expressions will be eliminated by another
2045 call to the simplification routine. */
2047 orexp = false_rtx;
2048 andexp = true_rtx;
2050 if (current_alternative_string)
2051 clear_struct_flag (value);
2053 for (i = 0; i < XVECLEN (value, 0); i += 2)
2055 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2056 insn_code, insn_index);
2058 SIMPLIFY_ALTERNATIVE (this);
2060 right = insert_right_side (AND, andexp, this,
2061 insn_code, insn_index);
2062 right = insert_right_side (AND, right,
2063 evaluate_eq_attr (exp,
2064 XVECEXP (value, 0,
2065 i + 1),
2066 insn_code, insn_index),
2067 insn_code, insn_index);
2068 orexp = insert_right_side (IOR, orexp, right,
2069 insn_code, insn_index);
2071 /* Add this condition into the AND expression. */
2072 newexp = attr_rtx (NOT, this);
2073 andexp = insert_right_side (AND, andexp, newexp,
2074 insn_code, insn_index);
2077 /* Handle the default case. */
2078 right = insert_right_side (AND, andexp,
2079 evaluate_eq_attr (exp, XEXP (value, 1),
2080 insn_code, insn_index),
2081 insn_code, insn_index);
2082 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2084 else
2085 abort ();
2087 /* If uses an address, must return original expression. But set the
2088 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2090 address_used = 0;
2091 walk_attr_value (newexp);
2093 if (address_used)
2095 /* This had `&& current_alternative_string', which seems to be wrong. */
2096 if (! ATTR_IND_SIMPLIFIED_P (exp))
2097 return copy_rtx_unchanging (exp);
2098 return exp;
2100 else
2101 return newexp;
2104 /* This routine is called when an AND of a term with a tree of AND's is
2105 encountered. If the term or its complement is present in the tree, it
2106 can be replaced with TRUE or FALSE, respectively.
2108 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2109 be true and hence are complementary.
2111 There is one special case: If we see
2112 (and (not (eq_attr "att" "v1"))
2113 (eq_attr "att" "v2"))
2114 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2115 replace the term, not anything in the AND tree. So we pass a pointer to
2116 the term. */
2118 static rtx
2119 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2121 rtx left, right;
2122 rtx newexp;
2123 rtx temp;
2124 int left_eliminates_term, right_eliminates_term;
2126 if (GET_CODE (exp) == AND)
2128 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2129 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2130 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2132 newexp = attr_rtx (AND, left, right);
2134 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2138 else if (GET_CODE (exp) == IOR)
2140 /* For the IOR case, we do the same as above, except that we can
2141 only eliminate `term' if both sides of the IOR would do so. */
2142 temp = *pterm;
2143 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2144 left_eliminates_term = (temp == true_rtx);
2146 temp = *pterm;
2147 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2148 right_eliminates_term = (temp == true_rtx);
2150 if (left_eliminates_term && right_eliminates_term)
2151 *pterm = true_rtx;
2153 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2155 newexp = attr_rtx (IOR, left, right);
2157 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2161 /* Check for simplifications. Do some extra checking here since this
2162 routine is called so many times. */
2164 if (exp == *pterm)
2165 return true_rtx;
2167 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2168 return false_rtx;
2170 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2171 return false_rtx;
2173 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2175 if (attr_alt_subset_p (*pterm, exp))
2176 return true_rtx;
2178 if (attr_alt_subset_of_compl_p (*pterm, exp))
2179 return false_rtx;
2181 if (attr_alt_subset_p (exp, *pterm))
2182 *pterm = true_rtx;
2184 return exp;
2187 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2189 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2190 return exp;
2192 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2193 return true_rtx;
2194 else
2195 return false_rtx;
2198 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2199 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2201 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2202 return exp;
2204 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2205 return false_rtx;
2206 else
2207 return true_rtx;
2210 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2211 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2213 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2214 return exp;
2216 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2217 return false_rtx;
2218 else
2219 *pterm = true_rtx;
2222 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2224 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2225 return true_rtx;
2228 else if (GET_CODE (exp) == NOT)
2230 if (attr_equal_p (XEXP (exp, 0), *pterm))
2231 return false_rtx;
2234 else if (GET_CODE (*pterm) == NOT)
2236 if (attr_equal_p (XEXP (*pterm, 0), exp))
2237 return false_rtx;
2240 else if (attr_equal_p (exp, *pterm))
2241 return true_rtx;
2243 return exp;
2246 /* Similar to `simplify_and_tree', but for IOR trees. */
2248 static rtx
2249 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2251 rtx left, right;
2252 rtx newexp;
2253 rtx temp;
2254 int left_eliminates_term, right_eliminates_term;
2256 if (GET_CODE (exp) == IOR)
2258 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2259 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2260 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2262 newexp = attr_rtx (GET_CODE (exp), left, right);
2264 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2268 else if (GET_CODE (exp) == AND)
2270 /* For the AND case, we do the same as above, except that we can
2271 only eliminate `term' if both sides of the AND would do so. */
2272 temp = *pterm;
2273 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2274 left_eliminates_term = (temp == false_rtx);
2276 temp = *pterm;
2277 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2278 right_eliminates_term = (temp == false_rtx);
2280 if (left_eliminates_term && right_eliminates_term)
2281 *pterm = false_rtx;
2283 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2285 newexp = attr_rtx (GET_CODE (exp), left, right);
2287 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2291 if (attr_equal_p (exp, *pterm))
2292 return false_rtx;
2294 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2295 return true_rtx;
2297 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2298 return true_rtx;
2300 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2301 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2302 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2303 *pterm = false_rtx;
2305 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2306 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2307 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2308 return false_rtx;
2310 return exp;
2313 /* Compute approximate cost of the expression. Used to decide whether
2314 expression is cheap enough for inline. */
2315 static int
2316 attr_rtx_cost (rtx x)
2318 int cost = 0;
2319 enum rtx_code code;
2320 if (!x)
2321 return 0;
2322 code = GET_CODE (x);
2323 switch (code)
2325 case MATCH_OPERAND:
2326 if (XSTR (x, 1)[0])
2327 return 10;
2328 else
2329 return 0;
2331 case EQ_ATTR_ALT:
2332 return 0;
2334 case EQ_ATTR:
2335 /* Alternatives don't result into function call. */
2336 if (!strcmp_check (XSTR (x, 0), alternative_name))
2337 return 0;
2338 else
2339 return 5;
2340 default:
2342 int i, j;
2343 const char *fmt = GET_RTX_FORMAT (code);
2344 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2346 switch (fmt[i])
2348 case 'V':
2349 case 'E':
2350 for (j = 0; j < XVECLEN (x, i); j++)
2351 cost += attr_rtx_cost (XVECEXP (x, i, j));
2352 break;
2353 case 'e':
2354 cost += attr_rtx_cost (XEXP (x, i));
2355 break;
2359 break;
2361 return cost;
2364 /* Simplify test expression and use temporary obstack in order to avoid
2365 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2366 and avoid unnecessary copying if possible. */
2368 static rtx
2369 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2371 rtx x;
2372 struct obstack *old;
2373 if (ATTR_IND_SIMPLIFIED_P (exp))
2374 return exp;
2375 old = rtl_obstack;
2376 rtl_obstack = temp_obstack;
2377 x = simplify_test_exp (exp, insn_code, insn_index);
2378 rtl_obstack = old;
2379 if (x == exp || rtl_obstack == temp_obstack)
2380 return x;
2381 return attr_copy_rtx (x);
2384 /* Returns true if S1 is a subset of S2. */
2386 static bool
2387 attr_alt_subset_p (rtx s1, rtx s2)
2389 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2391 case (0 << 1) | 0:
2392 return !(XINT (s1, 0) &~ XINT (s2, 0));
2394 case (0 << 1) | 1:
2395 return !(XINT (s1, 0) & XINT (s2, 0));
2397 case (1 << 1) | 0:
2398 return false;
2400 case (1 << 1) | 1:
2401 return !(XINT (s2, 0) &~ XINT (s1, 0));
2403 default:
2404 abort ();
2408 /* Returns true if S1 is a subset of complement of S2. */
2410 static bool attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2412 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2414 case (0 << 1) | 0:
2415 return !(XINT (s1, 0) & XINT (s2, 0));
2417 case (0 << 1) | 1:
2418 return !(XINT (s1, 0) & ~XINT (s2, 0));
2420 case (1 << 1) | 0:
2421 return !(XINT (s2, 0) &~ XINT (s1, 0));
2423 case (1 << 1) | 1:
2424 return false;
2426 default:
2427 abort ();
2431 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2433 static rtx
2434 attr_alt_intersection (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 (s1, 0) & ~XINT (s2, 0);
2445 break;
2446 case (1 << 1) | 0:
2447 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2448 break;
2449 case (1 << 1) | 1:
2450 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2451 break;
2452 default:
2453 abort ();
2455 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2457 return result;
2460 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2462 static rtx
2463 attr_alt_union (rtx s1, rtx s2)
2465 rtx result = rtx_alloc (EQ_ATTR_ALT);
2467 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2469 case (0 << 1) | 0:
2470 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2471 break;
2472 case (0 << 1) | 1:
2473 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2474 break;
2475 case (1 << 1) | 0:
2476 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2477 break;
2478 case (1 << 1) | 1:
2479 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2480 break;
2481 default:
2482 abort ();
2485 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2486 return result;
2489 /* Return EQ_ATTR_ALT expression representing complement of S. */
2491 static rtx
2492 attr_alt_complement (rtx s)
2494 rtx result = rtx_alloc (EQ_ATTR_ALT);
2496 XINT (result, 0) = XINT (s, 0);
2497 XINT (result, 1) = 1 - XINT (s, 1);
2499 return result;
2502 /* Tests whether a bit B belongs to the set represented by S. */
2504 static bool
2505 attr_alt_bit_p (rtx s, int b)
2507 return XINT (s, 1) ^ ((XINT (s, 0) >> b) & 1);
2510 /* Return EQ_ATTR_ALT expression representing set containing elements set
2511 in E. */
2513 static rtx
2514 mk_attr_alt (int e)
2516 rtx result = rtx_alloc (EQ_ATTR_ALT);
2518 XINT (result, 0) = e;
2519 XINT (result, 1) = 0;
2521 return result;
2524 /* Given an expression, see if it can be simplified for a particular insn
2525 code based on the values of other attributes being tested. This can
2526 eliminate nested get_attr_... calls.
2528 Note that if an endless recursion is specified in the patterns, the
2529 optimization will loop. However, it will do so in precisely the cases where
2530 an infinite recursion loop could occur during compilation. It's better that
2531 it occurs here! */
2533 static rtx
2534 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2536 rtx left, right;
2537 struct attr_desc *attr;
2538 struct attr_value *av;
2539 struct insn_ent *ie;
2540 int i;
2541 rtx newexp = exp;
2542 bool left_alt, right_alt;
2544 /* Don't re-simplify something we already simplified. */
2545 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2546 return exp;
2548 switch (GET_CODE (exp))
2550 case AND:
2551 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2552 SIMPLIFY_ALTERNATIVE (left);
2553 if (left == false_rtx)
2554 return false_rtx;
2555 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2556 SIMPLIFY_ALTERNATIVE (right);
2557 if (left == false_rtx)
2558 return false_rtx;
2560 if (GET_CODE (left) == EQ_ATTR_ALT
2561 && GET_CODE (right) == EQ_ATTR_ALT)
2563 exp = attr_alt_intersection (left, right);
2564 return simplify_test_exp (exp, insn_code, insn_index);
2567 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2568 present on both sides, apply the distributive law since this will
2569 yield simplifications. */
2570 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2571 && compute_alternative_mask (left, IOR)
2572 && compute_alternative_mask (right, IOR))
2574 if (GET_CODE (left) == IOR)
2576 rtx tem = left;
2577 left = right;
2578 right = tem;
2581 newexp = attr_rtx (IOR,
2582 attr_rtx (AND, left, XEXP (right, 0)),
2583 attr_rtx (AND, left, XEXP (right, 1)));
2585 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2588 /* Try with the term on both sides. */
2589 right = simplify_and_tree (right, &left, insn_code, insn_index);
2590 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2591 left = simplify_and_tree (left, &right, insn_code, insn_index);
2593 if (left == false_rtx || right == false_rtx)
2594 return false_rtx;
2595 else if (left == true_rtx)
2597 return right;
2599 else if (right == true_rtx)
2601 return left;
2603 /* See if all or all but one of the insn's alternatives are specified
2604 in this tree. Optimize if so. */
2606 if (GET_CODE (left) == NOT)
2607 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2608 && XSTR (XEXP (left, 0), 0) == alternative_name);
2609 else
2610 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2611 && XINT (left, 1));
2613 if (GET_CODE (right) == NOT)
2614 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2615 && XSTR (XEXP (right, 0), 0) == alternative_name);
2616 else
2617 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2618 && XINT (right, 1));
2620 if (insn_code >= 0
2621 && (GET_CODE (left) == AND
2622 || left_alt
2623 || GET_CODE (right) == AND
2624 || right_alt))
2626 i = compute_alternative_mask (exp, AND);
2627 if (i & ~insn_alternatives[insn_code])
2628 fatal ("invalid alternative specified for pattern number %d",
2629 insn_index);
2631 /* If all alternatives are excluded, this is false. */
2632 i ^= insn_alternatives[insn_code];
2633 if (i == 0)
2634 return false_rtx;
2635 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2637 /* If just one excluded, AND a comparison with that one to the
2638 front of the tree. The others will be eliminated by
2639 optimization. We do not want to do this if the insn has one
2640 alternative and we have tested none of them! */
2641 left = make_alternative_compare (i);
2642 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2643 newexp = attr_rtx (AND, left, right);
2645 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2649 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2651 newexp = attr_rtx (AND, left, right);
2652 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2654 break;
2656 case IOR:
2657 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2658 SIMPLIFY_ALTERNATIVE (left);
2659 if (left == true_rtx)
2660 return true_rtx;
2661 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2662 SIMPLIFY_ALTERNATIVE (right);
2663 if (right == true_rtx)
2664 return true_rtx;
2666 if (GET_CODE (left) == EQ_ATTR_ALT
2667 && GET_CODE (right) == EQ_ATTR_ALT)
2669 exp = attr_alt_union (left, right);
2670 return simplify_test_exp (exp, insn_code, insn_index);
2673 right = simplify_or_tree (right, &left, insn_code, insn_index);
2674 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2675 left = simplify_or_tree (left, &right, insn_code, insn_index);
2677 if (right == true_rtx || left == true_rtx)
2678 return true_rtx;
2679 else if (left == false_rtx)
2681 return right;
2683 else if (right == false_rtx)
2685 return left;
2688 /* Test for simple cases where the distributive law is useful. I.e.,
2689 convert (ior (and (x) (y))
2690 (and (x) (z)))
2691 to (and (x)
2692 (ior (y) (z)))
2695 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2696 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2698 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2700 left = XEXP (left, 0);
2701 right = newexp;
2702 newexp = attr_rtx (AND, left, right);
2703 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2706 /* See if all or all but one of the insn's alternatives are specified
2707 in this tree. Optimize if so. */
2709 else if (insn_code >= 0
2710 && (GET_CODE (left) == IOR
2711 || (GET_CODE (left) == EQ_ATTR_ALT
2712 && !XINT (left, 1))
2713 || (GET_CODE (left) == EQ_ATTR
2714 && XSTR (left, 0) == alternative_name)
2715 || GET_CODE (right) == IOR
2716 || (GET_CODE (right) == EQ_ATTR_ALT
2717 && !XINT (right, 1))
2718 || (GET_CODE (right) == EQ_ATTR
2719 && XSTR (right, 0) == alternative_name)))
2721 i = compute_alternative_mask (exp, IOR);
2722 if (i & ~insn_alternatives[insn_code])
2723 fatal ("invalid alternative specified for pattern number %d",
2724 insn_index);
2726 /* If all alternatives are included, this is true. */
2727 i ^= insn_alternatives[insn_code];
2728 if (i == 0)
2729 return true_rtx;
2730 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2732 /* If just one excluded, IOR a comparison with that one to the
2733 front of the tree. The others will be eliminated by
2734 optimization. We do not want to do this if the insn has one
2735 alternative and we have tested none of them! */
2736 left = make_alternative_compare (i);
2737 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2738 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2740 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2744 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2746 newexp = attr_rtx (IOR, left, right);
2747 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2749 break;
2751 case NOT:
2752 if (GET_CODE (XEXP (exp, 0)) == NOT)
2754 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2755 insn_code, insn_index);
2756 SIMPLIFY_ALTERNATIVE (left);
2757 return left;
2760 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2761 SIMPLIFY_ALTERNATIVE (left);
2762 if (GET_CODE (left) == NOT)
2763 return XEXP (left, 0);
2765 if (left == false_rtx)
2766 return true_rtx;
2767 if (left == true_rtx)
2768 return false_rtx;
2770 if (GET_CODE (left) == EQ_ATTR_ALT)
2772 exp = attr_alt_complement (left);
2773 return simplify_test_exp (exp, insn_code, insn_index);
2776 /* Try to apply De`Morgan's laws. */
2777 if (GET_CODE (left) == IOR)
2779 newexp = attr_rtx (AND,
2780 attr_rtx (NOT, XEXP (left, 0)),
2781 attr_rtx (NOT, XEXP (left, 1)));
2783 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2785 else if (GET_CODE (left) == AND)
2787 newexp = attr_rtx (IOR,
2788 attr_rtx (NOT, XEXP (left, 0)),
2789 attr_rtx (NOT, XEXP (left, 1)));
2791 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2793 else if (left != XEXP (exp, 0))
2795 newexp = attr_rtx (NOT, left);
2797 break;
2799 case EQ_ATTR_ALT:
2800 if (current_alternative_string)
2801 return attr_alt_bit_p (exp, atoi (current_alternative_string)) ? true_rtx : false_rtx;
2803 if (!XINT (exp, 0))
2804 return XINT (exp, 1) ? true_rtx : false_rtx;
2805 break;
2807 case EQ_ATTR:
2808 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
2809 return (XSTR (exp, 1) == current_alternative_string
2810 ? true_rtx : false_rtx);
2812 if (XSTR (exp, 0) == alternative_name)
2814 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2815 break;
2818 /* Look at the value for this insn code in the specified attribute.
2819 We normally can replace this comparison with the condition that
2820 would give this insn the values being tested for. */
2821 if (XSTR (exp, 0) != alternative_name
2822 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2823 for (av = attr->first_value; av; av = av->next)
2824 for (ie = av->first_insn; ie; ie = ie->next)
2825 if (ie->def->insn_code == insn_code)
2827 rtx x;
2828 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2829 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2830 if (attr_rtx_cost(x) < 20)
2831 return x;
2833 break;
2835 default:
2836 break;
2839 /* We have already simplified this expression. Simplifying it again
2840 won't buy anything unless we weren't given a valid insn code
2841 to process (i.e., we are canonicalizing something.). */
2842 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
2843 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2844 return copy_rtx_unchanging (newexp);
2846 return newexp;
2849 /* Optimize the attribute lists by seeing if we can determine conditional
2850 values from the known values of other attributes. This will save subroutine
2851 calls during the compilation. */
2853 static void
2854 optimize_attrs (void)
2856 struct attr_desc *attr;
2857 struct attr_value *av;
2858 struct insn_ent *ie;
2859 rtx newexp;
2860 int i;
2861 struct attr_value_list
2863 struct attr_value *av;
2864 struct insn_ent *ie;
2865 struct attr_desc *attr;
2866 struct attr_value_list *next;
2868 struct attr_value_list **insn_code_values;
2869 struct attr_value_list *ivbuf;
2870 struct attr_value_list *iv;
2872 /* For each insn code, make a list of all the insn_ent's for it,
2873 for all values for all attributes. */
2875 if (num_insn_ents == 0)
2876 return;
2878 /* Make 2 extra elements, for "code" values -2 and -1. */
2879 insn_code_values = xcalloc ((insn_code_number + 2),
2880 sizeof (struct attr_value_list *));
2882 /* Offset the table address so we can index by -2 or -1. */
2883 insn_code_values += 2;
2885 iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
2887 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2888 for (attr = attrs[i]; attr; attr = attr->next)
2889 for (av = attr->first_value; av; av = av->next)
2890 for (ie = av->first_insn; ie; ie = ie->next)
2892 iv->attr = attr;
2893 iv->av = av;
2894 iv->ie = ie;
2895 iv->next = insn_code_values[ie->def->insn_code];
2896 insn_code_values[ie->def->insn_code] = iv;
2897 iv++;
2900 /* Sanity check on num_insn_ents. */
2901 if (iv != ivbuf + num_insn_ents)
2902 abort ();
2904 /* Process one insn code at a time. */
2905 for (i = -2; i < insn_code_number; i++)
2907 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2908 We use it to mean "already simplified for this insn". */
2909 for (iv = insn_code_values[i]; iv; iv = iv->next)
2910 clear_struct_flag (iv->av->value);
2912 for (iv = insn_code_values[i]; iv; iv = iv->next)
2914 struct obstack *old = rtl_obstack;
2916 attr = iv->attr;
2917 av = iv->av;
2918 ie = iv->ie;
2919 if (GET_CODE (av->value) != COND)
2920 continue;
2922 rtl_obstack = temp_obstack;
2923 newexp = av->value;
2924 while (GET_CODE (newexp) == COND)
2926 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2927 ie->def->insn_index);
2928 if (newexp2 == newexp)
2929 break;
2930 newexp = newexp2;
2933 rtl_obstack = old;
2934 if (newexp != av->value)
2936 newexp = attr_copy_rtx (newexp);
2937 remove_insn_ent (av, ie);
2938 av = get_attr_value (newexp, attr, ie->def->insn_code);
2939 iv->av = av;
2940 insert_insn_ent (av, ie);
2945 free (ivbuf);
2946 free (insn_code_values - 2);
2949 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2951 static void
2952 clear_struct_flag (rtx x)
2954 int i;
2955 int j;
2956 enum rtx_code code;
2957 const char *fmt;
2959 ATTR_CURR_SIMPLIFIED_P (x) = 0;
2960 if (ATTR_IND_SIMPLIFIED_P (x))
2961 return;
2963 code = GET_CODE (x);
2965 switch (code)
2967 case REG:
2968 case CONST_INT:
2969 case CONST_DOUBLE:
2970 case CONST_VECTOR:
2971 case SYMBOL_REF:
2972 case CODE_LABEL:
2973 case PC:
2974 case CC0:
2975 case EQ_ATTR:
2976 case ATTR_FLAG:
2977 return;
2979 default:
2980 break;
2983 /* Compare the elements. If any pair of corresponding elements
2984 fail to match, return 0 for the whole things. */
2986 fmt = GET_RTX_FORMAT (code);
2987 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2989 switch (fmt[i])
2991 case 'V':
2992 case 'E':
2993 for (j = 0; j < XVECLEN (x, i); j++)
2994 clear_struct_flag (XVECEXP (x, i, j));
2995 break;
2997 case 'e':
2998 clear_struct_flag (XEXP (x, i));
2999 break;
3004 /* Create table entries for DEFINE_ATTR. */
3006 static void
3007 gen_attr (rtx exp, int lineno)
3009 struct attr_desc *attr;
3010 struct attr_value *av;
3011 const char *name_ptr;
3012 char *p;
3014 /* Make a new attribute structure. Check for duplicate by looking at
3015 attr->default_val, since it is initialized by this routine. */
3016 attr = find_attr (&XSTR (exp, 0), 1);
3017 if (attr->default_val)
3019 message_with_line (lineno, "duplicate definition for attribute %s",
3020 attr->name);
3021 message_with_line (attr->lineno, "previous definition");
3022 have_error = 1;
3023 return;
3025 attr->lineno = lineno;
3027 if (*XSTR (exp, 1) == '\0')
3028 attr->is_numeric = 1;
3029 else
3031 name_ptr = XSTR (exp, 1);
3032 while ((p = next_comma_elt (&name_ptr)) != NULL)
3034 av = oballoc (sizeof (struct attr_value));
3035 av->value = attr_rtx (CONST_STRING, p);
3036 av->next = attr->first_value;
3037 attr->first_value = av;
3038 av->first_insn = NULL;
3039 av->num_insns = 0;
3040 av->has_asm_insn = 0;
3044 if (GET_CODE (XEXP (exp, 2)) == CONST)
3046 attr->is_const = 1;
3047 if (attr->is_numeric)
3049 message_with_line (lineno,
3050 "constant attributes may not take numeric values");
3051 have_error = 1;
3054 /* Get rid of the CONST node. It is allowed only at top-level. */
3055 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3058 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3060 message_with_line (lineno,
3061 "`length' attribute must take numeric values");
3062 have_error = 1;
3065 /* Set up the default value. */
3066 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3067 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3070 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3071 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3072 number of alternatives as this should be checked elsewhere. */
3074 static int
3075 count_alternatives (rtx exp)
3077 int i, j, n;
3078 const char *fmt;
3080 if (GET_CODE (exp) == MATCH_OPERAND)
3081 return n_comma_elts (XSTR (exp, 2));
3083 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3084 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3085 switch (*fmt++)
3087 case 'e':
3088 case 'u':
3089 n = count_alternatives (XEXP (exp, i));
3090 if (n)
3091 return n;
3092 break;
3094 case 'E':
3095 case 'V':
3096 if (XVEC (exp, i) != NULL)
3097 for (j = 0; j < XVECLEN (exp, i); j++)
3099 n = count_alternatives (XVECEXP (exp, i, j));
3100 if (n)
3101 return n;
3105 return 0;
3108 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3109 `alternative' attribute. */
3111 static int
3112 compares_alternatives_p (rtx exp)
3114 int i, j;
3115 const char *fmt;
3117 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3118 return 1;
3120 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3121 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3122 switch (*fmt++)
3124 case 'e':
3125 case 'u':
3126 if (compares_alternatives_p (XEXP (exp, i)))
3127 return 1;
3128 break;
3130 case 'E':
3131 for (j = 0; j < XVECLEN (exp, i); j++)
3132 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3133 return 1;
3134 break;
3137 return 0;
3140 /* Returns nonzero is INNER is contained in EXP. */
3142 static int
3143 contained_in_p (rtx inner, rtx exp)
3145 int i, j;
3146 const char *fmt;
3148 if (rtx_equal_p (inner, exp))
3149 return 1;
3151 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3152 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3153 switch (*fmt++)
3155 case 'e':
3156 case 'u':
3157 if (contained_in_p (inner, XEXP (exp, i)))
3158 return 1;
3159 break;
3161 case 'E':
3162 for (j = 0; j < XVECLEN (exp, i); j++)
3163 if (contained_in_p (inner, XVECEXP (exp, i, j)))
3164 return 1;
3165 break;
3168 return 0;
3171 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3173 static void
3174 gen_insn (rtx exp, int lineno)
3176 struct insn_def *id;
3178 id = oballoc (sizeof (struct insn_def));
3179 id->next = defs;
3180 defs = id;
3181 id->def = exp;
3182 id->lineno = lineno;
3184 switch (GET_CODE (exp))
3186 case DEFINE_INSN:
3187 id->insn_code = insn_code_number;
3188 id->insn_index = insn_index_number;
3189 id->num_alternatives = count_alternatives (exp);
3190 if (id->num_alternatives == 0)
3191 id->num_alternatives = 1;
3192 id->vec_idx = 4;
3193 break;
3195 case DEFINE_PEEPHOLE:
3196 id->insn_code = insn_code_number;
3197 id->insn_index = insn_index_number;
3198 id->num_alternatives = count_alternatives (exp);
3199 if (id->num_alternatives == 0)
3200 id->num_alternatives = 1;
3201 id->vec_idx = 3;
3202 break;
3204 case DEFINE_ASM_ATTRIBUTES:
3205 id->insn_code = -1;
3206 id->insn_index = -1;
3207 id->num_alternatives = 1;
3208 id->vec_idx = 0;
3209 got_define_asm_attributes = 1;
3210 break;
3212 default:
3213 abort ();
3217 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3218 true or annul false is specified, and make a `struct delay_desc'. */
3220 static void
3221 gen_delay (rtx def, int lineno)
3223 struct delay_desc *delay;
3224 int i;
3226 if (XVECLEN (def, 1) % 3 != 0)
3228 message_with_line (lineno,
3229 "number of elements in DEFINE_DELAY must be multiple of three");
3230 have_error = 1;
3231 return;
3234 for (i = 0; i < XVECLEN (def, 1); i += 3)
3236 if (XVECEXP (def, 1, i + 1))
3237 have_annul_true = 1;
3238 if (XVECEXP (def, 1, i + 2))
3239 have_annul_false = 1;
3242 delay = oballoc (sizeof (struct delay_desc));
3243 delay->def = def;
3244 delay->num = ++num_delays;
3245 delay->next = delays;
3246 delay->lineno = lineno;
3247 delays = delay;
3250 /* Given a piece of RTX, print a C expression to test its truth value.
3251 We use AND and IOR both for logical and bit-wise operations, so
3252 interpret them as logical unless they are inside a comparison expression.
3253 The first bit of FLAGS will be nonzero in that case.
3255 Set the second bit of FLAGS to make references to attribute values use
3256 a cached local variable instead of calling a function. */
3258 static void
3259 write_test_expr (rtx exp, int flags)
3261 int comparison_operator = 0;
3262 RTX_CODE code;
3263 struct attr_desc *attr;
3265 /* In order not to worry about operator precedence, surround our part of
3266 the expression with parentheses. */
3268 printf ("(");
3269 code = GET_CODE (exp);
3270 switch (code)
3272 /* Binary operators. */
3273 case GEU: case GTU:
3274 case LEU: case LTU:
3275 printf ("(unsigned) ");
3276 /* Fall through. */
3278 case EQ: case NE:
3279 case GE: case GT:
3280 case LE: case LT:
3281 comparison_operator = 1;
3283 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3284 case AND: case IOR: case XOR:
3285 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3286 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
3287 switch (code)
3289 case EQ:
3290 printf (" == ");
3291 break;
3292 case NE:
3293 printf (" != ");
3294 break;
3295 case GE:
3296 printf (" >= ");
3297 break;
3298 case GT:
3299 printf (" > ");
3300 break;
3301 case GEU:
3302 printf (" >= (unsigned) ");
3303 break;
3304 case GTU:
3305 printf (" > (unsigned) ");
3306 break;
3307 case LE:
3308 printf (" <= ");
3309 break;
3310 case LT:
3311 printf (" < ");
3312 break;
3313 case LEU:
3314 printf (" <= (unsigned) ");
3315 break;
3316 case LTU:
3317 printf (" < (unsigned) ");
3318 break;
3319 case PLUS:
3320 printf (" + ");
3321 break;
3322 case MINUS:
3323 printf (" - ");
3324 break;
3325 case MULT:
3326 printf (" * ");
3327 break;
3328 case DIV:
3329 printf (" / ");
3330 break;
3331 case MOD:
3332 printf (" %% ");
3333 break;
3334 case AND:
3335 if (flags & 1)
3336 printf (" & ");
3337 else
3338 printf (" && ");
3339 break;
3340 case IOR:
3341 if (flags & 1)
3342 printf (" | ");
3343 else
3344 printf (" || ");
3345 break;
3346 case XOR:
3347 printf (" ^ ");
3348 break;
3349 case ASHIFT:
3350 printf (" << ");
3351 break;
3352 case LSHIFTRT:
3353 case ASHIFTRT:
3354 printf (" >> ");
3355 break;
3356 default:
3357 abort ();
3360 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
3361 break;
3363 case NOT:
3364 /* Special-case (not (eq_attrq "alternative" "x")) */
3365 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3366 && XSTR (XEXP (exp, 0), 0) == alternative_name)
3368 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3369 break;
3372 /* Otherwise, fall through to normal unary operator. */
3374 /* Unary operators. */
3375 case ABS: case NEG:
3376 switch (code)
3378 case NOT:
3379 if (flags & 1)
3380 printf ("~ ");
3381 else
3382 printf ("! ");
3383 break;
3384 case ABS:
3385 printf ("abs ");
3386 break;
3387 case NEG:
3388 printf ("-");
3389 break;
3390 default:
3391 abort ();
3394 write_test_expr (XEXP (exp, 0), flags);
3395 break;
3397 case EQ_ATTR_ALT:
3399 int set = XINT (exp, 0), bit = 0;
3401 if (flags & 1)
3402 fatal ("EQ_ATTR_ALT not valid inside comparison");
3404 if (!set)
3405 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3407 if (!(set & (set - 1)))
3409 if (!(set & 0xffff))
3411 bit += 16;
3412 set >>= 16;
3414 if (!(set & 0xff))
3416 bit += 8;
3417 set >>= 8;
3419 if (!(set & 0xf))
3421 bit += 4;
3422 set >>= 4;
3424 if (!(set & 0x3))
3426 bit += 2;
3427 set >>= 2;
3429 if (!(set & 1))
3430 bit++;
3432 printf ("which_alternative %s= %d",
3433 XINT (exp, 1) ? "!" : "=", bit);
3435 else
3437 printf ("%s((1 << which_alternative) & 0x%x)",
3438 XINT (exp, 1) ? "!" : "", set);
3441 break;
3443 /* Comparison test of an attribute with a value. Most of these will
3444 have been removed by optimization. Handle "alternative"
3445 specially and give error if EQ_ATTR present inside a comparison. */
3446 case EQ_ATTR:
3447 if (flags & 1)
3448 fatal ("EQ_ATTR not valid inside comparison");
3450 if (XSTR (exp, 0) == alternative_name)
3452 printf ("which_alternative == %s", XSTR (exp, 1));
3453 break;
3456 attr = find_attr (&XSTR (exp, 0), 0);
3457 if (! attr)
3458 abort ();
3460 /* Now is the time to expand the value of a constant attribute. */
3461 if (attr->is_const)
3463 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
3464 -2, -2),
3465 flags);
3467 else
3469 if (flags & 2)
3470 printf ("attr_%s", attr->name);
3471 else
3472 printf ("get_attr_%s (insn)", attr->name);
3473 printf (" == ");
3474 write_attr_valueq (attr, XSTR (exp, 1));
3476 break;
3478 /* Comparison test of flags for define_delays. */
3479 case ATTR_FLAG:
3480 if (flags & 1)
3481 fatal ("ATTR_FLAG not valid inside comparison");
3482 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3483 break;
3485 /* See if an operand matches a predicate. */
3486 case MATCH_OPERAND:
3487 /* If only a mode is given, just ensure the mode matches the operand.
3488 If neither a mode nor predicate is given, error. */
3489 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3491 if (GET_MODE (exp) == VOIDmode)
3492 fatal ("null MATCH_OPERAND specified as test");
3493 else
3494 printf ("GET_MODE (operands[%d]) == %smode",
3495 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3497 else
3498 printf ("%s (operands[%d], %smode)",
3499 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3500 break;
3502 /* Constant integer. */
3503 case CONST_INT:
3504 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3505 break;
3507 /* A random C expression. */
3508 case SYMBOL_REF:
3509 printf ("%s", XSTR (exp, 0));
3510 break;
3512 /* The address of the branch target. */
3513 case MATCH_DUP:
3514 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3515 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3516 break;
3518 case PC:
3519 /* The address of the current insn. We implement this actually as the
3520 address of the current insn for backward branches, but the last
3521 address of the next insn for forward branches, and both with
3522 adjustments that account for the worst-case possible stretching of
3523 intervening alignments between this insn and its destination. */
3524 printf ("insn_current_reference_address (insn)");
3525 break;
3527 case CONST_STRING:
3528 printf ("%s", XSTR (exp, 0));
3529 break;
3531 case IF_THEN_ELSE:
3532 write_test_expr (XEXP (exp, 0), flags & 2);
3533 printf (" ? ");
3534 write_test_expr (XEXP (exp, 1), flags | 1);
3535 printf (" : ");
3536 write_test_expr (XEXP (exp, 2), flags | 1);
3537 break;
3539 default:
3540 fatal ("bad RTX code `%s' in attribute calculation\n",
3541 GET_RTX_NAME (code));
3544 printf (")");
3547 /* Given an attribute value, return the maximum CONST_STRING argument
3548 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3550 static int
3551 max_attr_value (rtx exp, int *unknownp)
3553 int current_max;
3554 int i, n;
3556 switch (GET_CODE (exp))
3558 case CONST_STRING:
3559 current_max = atoi (XSTR (exp, 0));
3560 break;
3562 case COND:
3563 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3564 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3566 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3567 if (n > current_max)
3568 current_max = n;
3570 break;
3572 case IF_THEN_ELSE:
3573 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3574 n = max_attr_value (XEXP (exp, 2), unknownp);
3575 if (n > current_max)
3576 current_max = n;
3577 break;
3579 default:
3580 *unknownp = 1;
3581 current_max = INT_MAX;
3582 break;
3585 return current_max;
3588 /* Given an attribute value, return the result of ORing together all
3589 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3590 if the numeric value is not known. */
3592 static int
3593 or_attr_value (rtx exp, int *unknownp)
3595 int current_or;
3596 int i;
3598 switch (GET_CODE (exp))
3600 case CONST_STRING:
3601 current_or = atoi (XSTR (exp, 0));
3602 break;
3604 case COND:
3605 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3606 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3607 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3608 break;
3610 case IF_THEN_ELSE:
3611 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3612 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3613 break;
3615 default:
3616 *unknownp = 1;
3617 current_or = -1;
3618 break;
3621 return current_or;
3624 /* Scan an attribute value, possibly a conditional, and record what actions
3625 will be required to do any conditional tests in it.
3627 Specifically, set
3628 `must_extract' if we need to extract the insn operands
3629 `must_constrain' if we must compute `which_alternative'
3630 `address_used' if an address expression was used
3631 `length_used' if an (eq_attr "length" ...) was used
3634 static void
3635 walk_attr_value (rtx exp)
3637 int i, j;
3638 const char *fmt;
3639 RTX_CODE code;
3641 if (exp == NULL)
3642 return;
3644 code = GET_CODE (exp);
3645 switch (code)
3647 case SYMBOL_REF:
3648 if (! ATTR_IND_SIMPLIFIED_P (exp))
3649 /* Since this is an arbitrary expression, it can look at anything.
3650 However, constant expressions do not depend on any particular
3651 insn. */
3652 must_extract = must_constrain = 1;
3653 return;
3655 case MATCH_OPERAND:
3656 must_extract = 1;
3657 return;
3659 case EQ_ATTR_ALT:
3660 must_extract = must_constrain = 1;
3661 break;
3663 case EQ_ATTR:
3664 if (XSTR (exp, 0) == alternative_name)
3665 must_extract = must_constrain = 1;
3666 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3667 length_used = 1;
3668 return;
3670 case MATCH_DUP:
3671 must_extract = 1;
3672 address_used = 1;
3673 return;
3675 case PC:
3676 address_used = 1;
3677 return;
3679 case ATTR_FLAG:
3680 return;
3682 default:
3683 break;
3686 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3687 switch (*fmt++)
3689 case 'e':
3690 case 'u':
3691 walk_attr_value (XEXP (exp, i));
3692 break;
3694 case 'E':
3695 if (XVEC (exp, i) != NULL)
3696 for (j = 0; j < XVECLEN (exp, i); j++)
3697 walk_attr_value (XVECEXP (exp, i, j));
3698 break;
3702 /* Write out a function to obtain the attribute for a given INSN. */
3704 static void
3705 write_attr_get (struct attr_desc *attr)
3707 struct attr_value *av, *common_av;
3709 /* Find the most used attribute value. Handle that as the `default' of the
3710 switch we will generate. */
3711 common_av = find_most_used (attr);
3713 /* Write out start of function, then all values with explicit `case' lines,
3714 then a `default', then the value with the most uses. */
3715 if (attr->static_p)
3716 printf ("static ");
3717 if (!attr->is_numeric)
3718 printf ("enum attr_%s\n", attr->name);
3719 else if (attr->unsigned_p)
3720 printf ("unsigned int\n");
3721 else
3722 printf ("int\n");
3724 /* If the attribute name starts with a star, the remainder is the name of
3725 the subroutine to use, instead of `get_attr_...'. */
3726 if (attr->name[0] == '*')
3727 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3728 else if (attr->is_const == 0)
3729 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3730 else
3732 printf ("get_attr_%s (void)\n", attr->name);
3733 printf ("{\n");
3735 for (av = attr->first_value; av; av = av->next)
3736 if (av->num_insns != 0)
3737 write_attr_set (attr, 2, av->value, "return", ";",
3738 true_rtx, av->first_insn->def->insn_code,
3739 av->first_insn->def->insn_index);
3741 printf ("}\n\n");
3742 return;
3745 printf ("{\n");
3746 printf (" switch (recog_memoized (insn))\n");
3747 printf (" {\n");
3749 for (av = attr->first_value; av; av = av->next)
3750 if (av != common_av)
3751 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3753 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3754 printf (" }\n}\n\n");
3757 /* Given an AND tree of known true terms (because we are inside an `if' with
3758 that as the condition or are in an `else' clause) and an expression,
3759 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3760 the bulk of the work. */
3762 static rtx
3763 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
3765 rtx term;
3767 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3769 if (GET_CODE (known_true) == AND)
3771 exp = eliminate_known_true (XEXP (known_true, 0), exp,
3772 insn_code, insn_index);
3773 exp = eliminate_known_true (XEXP (known_true, 1), exp,
3774 insn_code, insn_index);
3776 else
3778 term = known_true;
3779 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3782 return exp;
3785 /* Write out a series of tests and assignment statements to perform tests and
3786 sets of an attribute value. We are passed an indentation amount and prefix
3787 and suffix strings to write around each attribute value (e.g., "return"
3788 and ";"). */
3790 static void
3791 write_attr_set (struct attr_desc *attr, int indent, rtx value,
3792 const char *prefix, const char *suffix, rtx known_true,
3793 int insn_code, int insn_index)
3795 if (GET_CODE (value) == COND)
3797 /* Assume the default value will be the default of the COND unless we
3798 find an always true expression. */
3799 rtx default_val = XEXP (value, 1);
3800 rtx our_known_true = known_true;
3801 rtx newexp;
3802 int first_if = 1;
3803 int i;
3805 for (i = 0; i < XVECLEN (value, 0); i += 2)
3807 rtx testexp;
3808 rtx inner_true;
3810 testexp = eliminate_known_true (our_known_true,
3811 XVECEXP (value, 0, i),
3812 insn_code, insn_index);
3813 newexp = attr_rtx (NOT, testexp);
3814 newexp = insert_right_side (AND, our_known_true, newexp,
3815 insn_code, insn_index);
3817 /* If the test expression is always true or if the next `known_true'
3818 expression is always false, this is the last case, so break
3819 out and let this value be the `else' case. */
3820 if (testexp == true_rtx || newexp == false_rtx)
3822 default_val = XVECEXP (value, 0, i + 1);
3823 break;
3826 /* Compute the expression to pass to our recursive call as being
3827 known true. */
3828 inner_true = insert_right_side (AND, our_known_true,
3829 testexp, insn_code, insn_index);
3831 /* If this is always false, skip it. */
3832 if (inner_true == false_rtx)
3833 continue;
3835 write_indent (indent);
3836 printf ("%sif ", first_if ? "" : "else ");
3837 first_if = 0;
3838 write_test_expr (testexp, 0);
3839 printf ("\n");
3840 write_indent (indent + 2);
3841 printf ("{\n");
3843 write_attr_set (attr, indent + 4,
3844 XVECEXP (value, 0, i + 1), prefix, suffix,
3845 inner_true, insn_code, insn_index);
3846 write_indent (indent + 2);
3847 printf ("}\n");
3848 our_known_true = newexp;
3851 if (! first_if)
3853 write_indent (indent);
3854 printf ("else\n");
3855 write_indent (indent + 2);
3856 printf ("{\n");
3859 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3860 prefix, suffix, our_known_true, insn_code, insn_index);
3862 if (! first_if)
3864 write_indent (indent + 2);
3865 printf ("}\n");
3868 else
3870 write_indent (indent);
3871 printf ("%s ", prefix);
3872 write_attr_value (attr, value);
3873 printf ("%s\n", suffix);
3877 /* Write out the computation for one attribute value. */
3879 static void
3880 write_attr_case (struct attr_desc *attr, struct attr_value *av,
3881 int write_case_lines, const char *prefix, const char *suffix,
3882 int indent, rtx known_true)
3884 struct insn_ent *ie;
3886 if (av->num_insns == 0)
3887 return;
3889 if (av->has_asm_insn)
3891 write_indent (indent);
3892 printf ("case -1:\n");
3893 write_indent (indent + 2);
3894 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3895 write_indent (indent + 2);
3896 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3897 write_indent (indent + 2);
3898 printf (" fatal_insn_not_found (insn);\n");
3901 if (write_case_lines)
3903 for (ie = av->first_insn; ie; ie = ie->next)
3904 if (ie->def->insn_code != -1)
3906 write_indent (indent);
3907 printf ("case %d: /* %s */\n",
3908 ie->def->insn_code, XSTR (ie->def->def, 0));
3911 else
3913 write_indent (indent);
3914 printf ("default:\n");
3917 /* See what we have to do to output this value. */
3918 must_extract = must_constrain = address_used = 0;
3919 walk_attr_value (av->value);
3921 if (must_constrain)
3923 write_indent (indent + 2);
3924 printf ("extract_constrain_insn_cached (insn);\n");
3926 else if (must_extract)
3928 write_indent (indent + 2);
3929 printf ("extract_insn_cached (insn);\n");
3932 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3933 known_true, av->first_insn->def->insn_code,
3934 av->first_insn->def->insn_index);
3936 if (strncmp (prefix, "return", 6))
3938 write_indent (indent + 2);
3939 printf ("break;\n");
3941 printf ("\n");
3944 /* Search for uses of non-const attributes and write code to cache them. */
3946 static int
3947 write_expr_attr_cache (rtx p, struct attr_desc *attr)
3949 const char *fmt;
3950 int i, ie, j, je;
3952 if (GET_CODE (p) == EQ_ATTR)
3954 if (XSTR (p, 0) != attr->name)
3955 return 0;
3957 if (!attr->is_numeric)
3958 printf (" enum attr_%s ", attr->name);
3959 else if (attr->unsigned_p)
3960 printf (" unsigned int ");
3961 else
3962 printf (" int ");
3964 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
3965 return 1;
3968 fmt = GET_RTX_FORMAT (GET_CODE (p));
3969 ie = GET_RTX_LENGTH (GET_CODE (p));
3970 for (i = 0; i < ie; i++)
3972 switch (*fmt++)
3974 case 'e':
3975 if (write_expr_attr_cache (XEXP (p, i), attr))
3976 return 1;
3977 break;
3979 case 'E':
3980 je = XVECLEN (p, i);
3981 for (j = 0; j < je; ++j)
3982 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
3983 return 1;
3984 break;
3988 return 0;
3991 /* Utilities to write in various forms. */
3993 static void
3994 write_attr_valueq (struct attr_desc *attr, const char *s)
3996 if (attr->is_numeric)
3998 int num = atoi (s);
4000 printf ("%d", num);
4002 if (num > 9 || num < 0)
4003 printf (" /* 0x%x */", num);
4005 else
4007 write_upcase (attr->name);
4008 printf ("_");
4009 write_upcase (s);
4013 static void
4014 write_attr_value (struct attr_desc *attr, rtx value)
4016 int op;
4018 switch (GET_CODE (value))
4020 case CONST_STRING:
4021 write_attr_valueq (attr, XSTR (value, 0));
4022 break;
4024 case CONST_INT:
4025 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4026 break;
4028 case SYMBOL_REF:
4029 fputs (XSTR (value, 0), stdout);
4030 break;
4032 case ATTR:
4034 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4035 printf ("get_attr_%s (%s)", attr2->name,
4036 (attr2->is_const ? "" : "insn"));
4038 break;
4040 case PLUS:
4041 op = '+';
4042 goto do_operator;
4043 case MINUS:
4044 op = '-';
4045 goto do_operator;
4046 case MULT:
4047 op = '*';
4048 goto do_operator;
4049 case DIV:
4050 op = '/';
4051 goto do_operator;
4052 case MOD:
4053 op = '%';
4054 goto do_operator;
4056 do_operator:
4057 write_attr_value (attr, XEXP (value, 0));
4058 putchar (' ');
4059 putchar (op);
4060 putchar (' ');
4061 write_attr_value (attr, XEXP (value, 1));
4062 break;
4064 default:
4065 abort ();
4069 static void
4070 write_upcase (const char *str)
4072 while (*str)
4074 /* The argument of TOUPPER should not have side effects. */
4075 putchar (TOUPPER(*str));
4076 str++;
4080 static void
4081 write_indent (int indent)
4083 for (; indent > 8; indent -= 8)
4084 printf ("\t");
4086 for (; indent; indent--)
4087 printf (" ");
4090 /* Write a subroutine that is given an insn that requires a delay slot, a
4091 delay slot ordinal, and a candidate insn. It returns nonzero if the
4092 candidate can be placed in the specified delay slot of the insn.
4094 We can write as many as three subroutines. `eligible_for_delay'
4095 handles normal delay slots, `eligible_for_annul_true' indicates that
4096 the specified insn can be annulled if the branch is true, and likewise
4097 for `eligible_for_annul_false'.
4099 KIND is a string distinguishing these three cases ("delay", "annul_true",
4100 or "annul_false"). */
4102 static void
4103 write_eligible_delay (const char *kind)
4105 struct delay_desc *delay;
4106 int max_slots;
4107 char str[50];
4108 const char *pstr;
4109 struct attr_desc *attr;
4110 struct attr_value *av, *common_av;
4111 int i;
4113 /* Compute the maximum number of delay slots required. We use the delay
4114 ordinal times this number plus one, plus the slot number as an index into
4115 the appropriate predicate to test. */
4117 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4118 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4119 max_slots = XVECLEN (delay->def, 1) / 3;
4121 /* Write function prelude. */
4123 printf ("int\n");
4124 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4125 kind);
4126 printf ("{\n");
4127 printf (" rtx insn;\n");
4128 printf ("\n");
4129 printf (" if (slot >= %d)\n", max_slots);
4130 printf (" abort ();\n");
4131 printf ("\n");
4132 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4133 converts a compound instruction into a loop. */
4134 printf (" if (!INSN_P (candidate_insn))\n");
4135 printf (" return 0;\n");
4136 printf ("\n");
4138 /* If more than one delay type, find out which type the delay insn is. */
4140 if (num_delays > 1)
4142 attr = find_attr (&delay_type_str, 0);
4143 if (! attr)
4144 abort ();
4145 common_av = find_most_used (attr);
4147 printf (" insn = delay_insn;\n");
4148 printf (" switch (recog_memoized (insn))\n");
4149 printf (" {\n");
4151 sprintf (str, " * %d;\n break;", max_slots);
4152 for (av = attr->first_value; av; av = av->next)
4153 if (av != common_av)
4154 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4156 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4157 printf (" }\n\n");
4159 /* Ensure matched. Otherwise, shouldn't have been called. */
4160 printf (" if (slot < %d)\n", max_slots);
4161 printf (" abort ();\n\n");
4164 /* If just one type of delay slot, write simple switch. */
4165 if (num_delays == 1 && max_slots == 1)
4167 printf (" insn = candidate_insn;\n");
4168 printf (" switch (recog_memoized (insn))\n");
4169 printf (" {\n");
4171 attr = find_attr (&delay_1_0_str, 0);
4172 if (! attr)
4173 abort ();
4174 common_av = find_most_used (attr);
4176 for (av = attr->first_value; av; av = av->next)
4177 if (av != common_av)
4178 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4180 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4181 printf (" }\n");
4184 else
4186 /* Write a nested CASE. The first indicates which condition we need to
4187 test, and the inner CASE tests the condition. */
4188 printf (" insn = candidate_insn;\n");
4189 printf (" switch (slot)\n");
4190 printf (" {\n");
4192 for (delay = delays; delay; delay = delay->next)
4193 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4195 printf (" case %d:\n",
4196 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4197 printf (" switch (recog_memoized (insn))\n");
4198 printf ("\t{\n");
4200 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4201 pstr = str;
4202 attr = find_attr (&pstr, 0);
4203 if (! attr)
4204 abort ();
4205 common_av = find_most_used (attr);
4207 for (av = attr->first_value; av; av = av->next)
4208 if (av != common_av)
4209 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4211 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4212 printf (" }\n");
4215 printf (" default:\n");
4216 printf (" abort ();\n");
4217 printf (" }\n");
4220 printf ("}\n\n");
4223 /* This page contains miscellaneous utility routines. */
4225 /* Given a pointer to a (char *), return a malloc'ed string containing the
4226 next comma-separated element. Advance the pointer to after the string
4227 scanned, or the end-of-string. Return NULL if at end of string. */
4229 static char *
4230 next_comma_elt (const char **pstr)
4232 const char *start;
4234 start = scan_comma_elt (pstr);
4236 if (start == NULL)
4237 return NULL;
4239 return attr_string (start, *pstr - start);
4242 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4243 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4244 replaced by a pointer to a canonical copy of the string. */
4246 static struct attr_desc *
4247 find_attr (const char **name_p, int create)
4249 struct attr_desc *attr;
4250 int index;
4251 const char *name = *name_p;
4253 /* Before we resort to using `strcmp', see if the string address matches
4254 anywhere. In most cases, it should have been canonicalized to do so. */
4255 if (name == alternative_name)
4256 return NULL;
4258 index = name[0] & (MAX_ATTRS_INDEX - 1);
4259 for (attr = attrs[index]; attr; attr = attr->next)
4260 if (name == attr->name)
4261 return attr;
4263 /* Otherwise, do it the slow way. */
4264 for (attr = attrs[index]; attr; attr = attr->next)
4265 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4267 *name_p = attr->name;
4268 return attr;
4271 if (! create)
4272 return NULL;
4274 attr = oballoc (sizeof (struct attr_desc));
4275 attr->name = DEF_ATTR_STRING (name);
4276 attr->first_value = attr->default_val = NULL;
4277 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
4278 attr->unsigned_p = attr->static_p = 0;
4279 attr->next = attrs[index];
4280 attrs[index] = attr;
4282 *name_p = attr->name;
4284 return attr;
4287 /* Create internal attribute with the given default value. */
4289 void
4290 make_internal_attr (const char *name, rtx value, int special)
4292 struct attr_desc *attr;
4294 attr = find_attr (&name, 1);
4295 if (attr->default_val)
4296 abort ();
4298 attr->is_numeric = 1;
4299 attr->is_const = 0;
4300 attr->is_special = (special & ATTR_SPECIAL) != 0;
4301 attr->negative_ok = (special & ATTR_NEGATIVE_OK) != 0;
4302 attr->unsigned_p = (special & ATTR_UNSIGNED) != 0;
4303 attr->static_p = (special & ATTR_STATIC) != 0;
4304 attr->default_val = get_attr_value (value, attr, -2);
4307 /* Find the most used value of an attribute. */
4309 static struct attr_value *
4310 find_most_used (struct attr_desc *attr)
4312 struct attr_value *av;
4313 struct attr_value *most_used;
4314 int nuses;
4316 most_used = NULL;
4317 nuses = -1;
4319 for (av = attr->first_value; av; av = av->next)
4320 if (av->num_insns > nuses)
4321 nuses = av->num_insns, most_used = av;
4323 return most_used;
4326 /* Return (attr_value "n") */
4329 make_numeric_value (int n)
4331 static rtx int_values[20];
4332 rtx exp;
4333 char *p;
4335 if (n < 0)
4336 abort ();
4338 if (n < 20 && int_values[n])
4339 return int_values[n];
4341 p = attr_printf (MAX_DIGITS, "%d", n);
4342 exp = attr_rtx (CONST_STRING, p);
4344 if (n < 20)
4345 int_values[n] = exp;
4347 return exp;
4350 static rtx
4351 copy_rtx_unchanging (rtx orig)
4353 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4354 return orig;
4356 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4357 return orig;
4360 /* Determine if an insn has a constant number of delay slots, i.e., the
4361 number of delay slots is not a function of the length of the insn. */
4363 static void
4364 write_const_num_delay_slots (void)
4366 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4367 struct attr_value *av;
4368 struct insn_ent *ie;
4370 if (attr)
4372 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4373 printf ("{\n");
4374 printf (" switch (recog_memoized (insn))\n");
4375 printf (" {\n");
4377 for (av = attr->first_value; av; av = av->next)
4379 length_used = 0;
4380 walk_attr_value (av->value);
4381 if (length_used)
4383 for (ie = av->first_insn; ie; ie = ie->next)
4384 if (ie->def->insn_code != -1)
4385 printf (" case %d: /* %s */\n",
4386 ie->def->insn_code, XSTR (ie->def->def, 0));
4387 printf (" return 0;\n");
4391 printf (" default:\n");
4392 printf (" return 1;\n");
4393 printf (" }\n}\n\n");
4398 main (int argc, char **argv)
4400 rtx desc;
4401 struct attr_desc *attr;
4402 struct insn_def *id;
4403 rtx tem;
4404 int i;
4406 progname = "genattrtab";
4408 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
4409 return (FATAL_EXIT_CODE);
4411 obstack_init (hash_obstack);
4412 obstack_init (temp_obstack);
4414 /* Set up true and false rtx's */
4415 true_rtx = rtx_alloc (CONST_INT);
4416 XWINT (true_rtx, 0) = 1;
4417 false_rtx = rtx_alloc (CONST_INT);
4418 XWINT (false_rtx, 0) = 0;
4419 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4420 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
4422 alternative_name = DEF_ATTR_STRING ("alternative");
4423 length_str = DEF_ATTR_STRING ("length");
4424 delay_type_str = DEF_ATTR_STRING ("*delay_type");
4425 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4426 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
4428 printf ("/* Generated automatically by the program `genattrtab'\n\
4429 from the machine description file `md'. */\n\n");
4431 /* Read the machine description. */
4433 initiate_automaton_gen (argc, argv);
4434 while (1)
4436 int lineno;
4438 desc = read_md_rtx (&lineno, &insn_code_number);
4439 if (desc == NULL)
4440 break;
4442 switch (GET_CODE (desc))
4444 case DEFINE_INSN:
4445 case DEFINE_PEEPHOLE:
4446 case DEFINE_ASM_ATTRIBUTES:
4447 gen_insn (desc, lineno);
4448 break;
4450 case DEFINE_ATTR:
4451 gen_attr (desc, lineno);
4452 break;
4454 case DEFINE_DELAY:
4455 gen_delay (desc, lineno);
4456 break;
4458 case DEFINE_CPU_UNIT:
4459 gen_cpu_unit (desc);
4460 break;
4462 case DEFINE_QUERY_CPU_UNIT:
4463 gen_query_cpu_unit (desc);
4464 break;
4466 case DEFINE_BYPASS:
4467 gen_bypass (desc);
4468 break;
4470 case EXCLUSION_SET:
4471 gen_excl_set (desc);
4472 break;
4474 case PRESENCE_SET:
4475 gen_presence_set (desc);
4476 break;
4478 case FINAL_PRESENCE_SET:
4479 gen_final_presence_set (desc);
4480 break;
4482 case ABSENCE_SET:
4483 gen_absence_set (desc);
4484 break;
4486 case FINAL_ABSENCE_SET:
4487 gen_final_absence_set (desc);
4488 break;
4490 case DEFINE_AUTOMATON:
4491 gen_automaton (desc);
4492 break;
4494 case AUTOMATA_OPTION:
4495 gen_automata_option (desc);
4496 break;
4498 case DEFINE_RESERVATION:
4499 gen_reserv (desc);
4500 break;
4502 case DEFINE_INSN_RESERVATION:
4503 gen_insn_reserv (desc);
4504 break;
4506 default:
4507 break;
4509 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
4510 insn_index_number++;
4513 if (have_error)
4514 return FATAL_EXIT_CODE;
4516 insn_code_number++;
4518 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4519 if (! got_define_asm_attributes)
4521 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4522 XVEC (tem, 0) = rtvec_alloc (0);
4523 gen_insn (tem, 0);
4526 /* Expand DEFINE_DELAY information into new attribute. */
4527 if (num_delays)
4528 expand_delays ();
4530 /* Build DFA, output some functions and expand DFA information
4531 to new attributes. */
4532 if (num_dfa_decls)
4533 expand_automata ();
4535 printf ("#include \"config.h\"\n");
4536 printf ("#include \"system.h\"\n");
4537 printf ("#include \"coretypes.h\"\n");
4538 printf ("#include \"tm.h\"\n");
4539 printf ("#include \"rtl.h\"\n");
4540 printf ("#include \"tm_p.h\"\n");
4541 printf ("#include \"insn-config.h\"\n");
4542 printf ("#include \"recog.h\"\n");
4543 printf ("#include \"regs.h\"\n");
4544 printf ("#include \"real.h\"\n");
4545 printf ("#include \"output.h\"\n");
4546 printf ("#include \"insn-attr.h\"\n");
4547 printf ("#include \"toplev.h\"\n");
4548 printf ("#include \"flags.h\"\n");
4549 printf ("#include \"function.h\"\n");
4550 printf ("\n");
4551 printf ("#define operands recog_data.operand\n\n");
4553 /* Make `insn_alternatives'. */
4554 insn_alternatives = oballoc (insn_code_number * sizeof (int));
4555 for (id = defs; id; id = id->next)
4556 if (id->insn_code >= 0)
4557 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4559 /* Make `insn_n_alternatives'. */
4560 insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
4561 for (id = defs; id; id = id->next)
4562 if (id->insn_code >= 0)
4563 insn_n_alternatives[id->insn_code] = id->num_alternatives;
4565 /* Prepare to write out attribute subroutines by checking everything stored
4566 away and building the attribute cases. */
4568 check_defs ();
4570 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4571 for (attr = attrs[i]; attr; attr = attr->next)
4572 attr->default_val->value
4573 = check_attr_value (attr->default_val->value, attr);
4575 if (have_error)
4576 return FATAL_EXIT_CODE;
4578 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4579 for (attr = attrs[i]; attr; attr = attr->next)
4580 fill_attr (attr);
4582 /* Construct extra attributes for `length'. */
4583 make_length_attrs ();
4585 /* Perform any possible optimizations to speed up compilation. */
4586 optimize_attrs ();
4588 /* Now write out all the `gen_attr_...' routines. Do these before the
4589 special routines so that they get defined before they are used. */
4591 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4592 for (attr = attrs[i]; attr; attr = attr->next)
4594 if (! attr->is_special && ! attr->is_const)
4596 int insn_alts_p;
4598 insn_alts_p
4599 = (attr->name [0] == '*'
4600 && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
4601 if (insn_alts_p)
4602 printf ("\n#if AUTOMATON_ALTS\n");
4603 write_attr_get (attr);
4604 if (insn_alts_p)
4605 printf ("#endif\n\n");
4609 /* Write out delay eligibility information, if DEFINE_DELAY present.
4610 (The function to compute the number of delay slots will be written
4611 below.) */
4612 if (num_delays)
4614 write_eligible_delay ("delay");
4615 if (have_annul_true)
4616 write_eligible_delay ("annul_true");
4617 if (have_annul_false)
4618 write_eligible_delay ("annul_false");
4621 /* Output code for pipeline hazards recognition based on DFA
4622 (deterministic finite-state automata). */
4623 if (num_dfa_decls)
4624 write_automata ();
4626 /* Write out constant delay slot info. */
4627 write_const_num_delay_slots ();
4629 write_length_unit_log ();
4631 fflush (stdout);
4632 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
4635 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
4636 const char *
4637 get_insn_name (int code ATTRIBUTE_UNUSED)
4639 return NULL;