* arm.c (FL_WBUF): Define.
[official-gcc.git] / gcc / genattrtab.c
blobe45466715f8759b0f6f27fad397515ebd79aa7f0
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, 2005 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 : (gcc_assert (strcmp ((S1), (S2))), 1))
106 #else
107 #define strcmp_check(S1, S2) ((S1) != (S2))
108 #endif
110 #include "bconfig.h"
111 #include "system.h"
112 #include "coretypes.h"
113 #include "tm.h"
114 #include "rtl.h"
115 #include "ggc.h"
116 #include "gensupport.h"
118 #ifdef HAVE_SYS_RESOURCE_H
119 # include <sys/resource.h>
120 #endif
122 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
123 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
124 #include "obstack.h"
125 #include "errors.h"
127 #include "genattrtab.h"
129 static struct obstack obstack1, obstack2;
130 struct obstack *hash_obstack = &obstack1;
131 struct obstack *temp_obstack = &obstack2;
133 /* enough space to reserve for printing out ints */
134 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
136 /* Define structures used to record attributes and values. */
138 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
139 encountered, we store all the relevant information into a
140 `struct insn_def'. This is done to allow attribute definitions to occur
141 anywhere in the file. */
143 struct insn_def
145 struct insn_def *next; /* Next insn in chain. */
146 rtx def; /* The DEFINE_... */
147 int insn_code; /* Instruction number. */
148 int insn_index; /* Expression numer in file, for errors. */
149 int lineno; /* Line number. */
150 int num_alternatives; /* Number of alternatives. */
151 int vec_idx; /* Index of attribute vector in `def'. */
154 /* Once everything has been read in, we store in each attribute value a list
155 of insn codes that have that value. Here is the structure used for the
156 list. */
158 struct insn_ent
160 struct insn_ent *next; /* Next in chain. */
161 struct insn_def *def; /* Instruction definition. */
164 /* Each value of an attribute (either constant or computed) is assigned a
165 structure which is used as the listhead of the insns that have that
166 value. */
168 struct attr_value
170 rtx value; /* Value of attribute. */
171 struct attr_value *next; /* Next attribute value in chain. */
172 struct insn_ent *first_insn; /* First insn with this value. */
173 int num_insns; /* Number of insns with this value. */
174 int has_asm_insn; /* True if this value used for `asm' insns */
177 /* Structure for each attribute. */
179 struct attr_desc
181 char *name; /* Name of attribute. */
182 struct attr_desc *next; /* Next attribute. */
183 struct attr_value *first_value; /* First value of this attribute. */
184 struct attr_value *default_val; /* Default value for this attribute. */
185 int lineno : 24; /* Line number. */
186 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
187 unsigned is_const : 1; /* Attribute value constant for each run. */
188 unsigned is_special : 1; /* Don't call `write_attr_set'. */
189 unsigned static_p : 1; /* Make the output function static. */
192 #define NULL_ATTR (struct attr_desc *) NULL
194 /* Structure for each DEFINE_DELAY. */
196 struct delay_desc
198 rtx def; /* DEFINE_DELAY expression. */
199 struct delay_desc *next; /* Next DEFINE_DELAY. */
200 int num; /* Number of DEFINE_DELAY, starting at 1. */
201 int lineno; /* Line number. */
204 /* Listheads of above structures. */
206 /* This one is indexed by the first character of the attribute name. */
207 #define MAX_ATTRS_INDEX 256
208 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
209 static struct insn_def *defs;
210 static struct delay_desc *delays;
212 /* Other variables. */
214 static int insn_code_number;
215 static int insn_index_number;
216 static int got_define_asm_attributes;
217 static int must_extract;
218 static int must_constrain;
219 static int address_used;
220 static int length_used;
221 static int num_delays;
222 static int have_annul_true, have_annul_false;
223 static int num_insn_ents;
225 int num_dfa_decls;
227 /* Stores, for each insn code, the number of constraint alternatives. */
229 static int *insn_n_alternatives;
231 /* Stores, for each insn code, a bitmap that has bits on for each possible
232 alternative. */
234 static int *insn_alternatives;
236 /* If nonzero, assume that the `alternative' attr has this value.
237 This is the hashed, unique string for the numeral
238 whose value is chosen alternative. */
240 static const char *current_alternative_string;
242 /* Used to simplify expressions. */
244 static rtx true_rtx, false_rtx;
246 /* Used to reduce calls to `strcmp' */
248 static char *alternative_name;
249 static const char *length_str;
250 static const char *delay_type_str;
251 static const char *delay_1_0_str;
252 static const char *num_delay_slots_str;
254 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
255 called. */
257 int reload_completed = 0;
259 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
260 to define it here. */
262 int optimize = 0;
264 /* Simplify an expression. Only call the routine if there is something to
265 simplify. */
266 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
267 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
268 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
270 /* Simplify (eq_attr ("alternative") ...)
271 when we are working with a particular alternative. */
272 #define SIMPLIFY_ALTERNATIVE(EXP) \
273 if (current_alternative_string \
274 && GET_CODE ((EXP)) == EQ_ATTR \
275 && XSTR ((EXP), 0) == alternative_name) \
276 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
277 ? true_rtx : false_rtx);
279 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
281 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
282 They won't actually be used. */
284 rtx global_rtl[GR_MAX];
285 rtx pic_offset_table_rtx;
287 static void attr_hash_add_rtx (int, rtx);
288 static void attr_hash_add_string (int, char *);
289 static rtx attr_rtx (enum rtx_code, ...);
290 static rtx attr_rtx_1 (enum rtx_code, va_list);
291 static char *attr_string (const char *, int);
292 static rtx check_attr_value (rtx, struct attr_desc *);
293 static rtx convert_set_attr_alternative (rtx, struct insn_def *);
294 static rtx convert_set_attr (rtx, struct insn_def *);
295 static void check_defs (void);
296 static rtx make_canonical (struct attr_desc *, rtx);
297 static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
298 static rtx copy_rtx_unchanging (rtx);
299 static rtx copy_boolean (rtx);
300 static void expand_delays (void);
301 static void fill_attr (struct attr_desc *);
302 static rtx substitute_address (rtx, rtx (*) (rtx), rtx (*) (rtx));
303 static void make_length_attrs (void);
304 static rtx identity_fn (rtx);
305 static rtx zero_fn (rtx);
306 static rtx one_fn (rtx);
307 static rtx max_fn (rtx);
308 static void write_length_unit_log (void);
309 static rtx simplify_cond (rtx, int, int);
310 static void clear_struct_flag (rtx);
311 static void remove_insn_ent (struct attr_value *, struct insn_ent *);
312 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
313 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
314 static rtx make_alternative_compare (int);
315 static int compute_alternative_mask (rtx, enum rtx_code);
316 static rtx evaluate_eq_attr (rtx, rtx, int, int);
317 static rtx simplify_and_tree (rtx, rtx *, int, int);
318 static rtx simplify_or_tree (rtx, rtx *, int, int);
319 static rtx simplify_test_exp (rtx, int, int);
320 static rtx simplify_test_exp_in_temp (rtx, int, int);
321 static void optimize_attrs (void);
322 static void gen_attr (rtx, int);
323 static int count_alternatives (rtx);
324 static int compares_alternatives_p (rtx);
325 static int contained_in_p (rtx, rtx);
326 static void gen_insn (rtx, int);
327 static void gen_delay (rtx, int);
328 static void write_test_expr (rtx, int);
329 static int max_attr_value (rtx, int*);
330 static int or_attr_value (rtx, int*);
331 static void walk_attr_value (rtx);
332 static void write_attr_get (struct attr_desc *);
333 static rtx eliminate_known_true (rtx, rtx, int, int);
334 static void write_attr_set (struct attr_desc *, int, rtx,
335 const char *, const char *, rtx,
336 int, int);
337 static void write_insn_cases (struct insn_ent *, int);
338 static void write_attr_case (struct attr_desc *, struct attr_value *,
339 int, const char *, const char *, int, rtx);
340 static void write_attr_valueq (struct attr_desc *, const char *);
341 static void write_attr_value (struct attr_desc *, rtx);
342 static void write_upcase (const char *);
343 static void write_indent (int);
344 static void write_eligible_delay (const char *);
345 static int write_expr_attr_cache (rtx, struct attr_desc *);
346 static void write_const_num_delay_slots (void);
347 static char *next_comma_elt (const char **);
348 static struct attr_desc *find_attr (const char **, int);
349 static struct attr_value *find_most_used (struct attr_desc *);
350 static rtx attr_eq (const char *, const char *);
351 static const char *attr_numeral (int);
352 static int attr_equal_p (rtx, rtx);
353 static rtx attr_copy_rtx (rtx);
354 static int attr_rtx_cost (rtx);
355 static bool attr_alt_subset_p (rtx, rtx);
356 static bool attr_alt_subset_of_compl_p (rtx, rtx);
357 static rtx attr_alt_intersection (rtx, rtx);
358 static rtx attr_alt_union (rtx, rtx);
359 static rtx attr_alt_complement (rtx);
360 static bool attr_alt_bit_p (rtx, int);
361 static rtx mk_attr_alt (int);
363 #define oballoc(size) obstack_alloc (hash_obstack, size)
365 /* Hash table for sharing RTL and strings. */
367 /* Each hash table slot is a bucket containing a chain of these structures.
368 Strings are given negative hash codes; RTL expressions are given positive
369 hash codes. */
371 struct attr_hash
373 struct attr_hash *next; /* Next structure in the bucket. */
374 int hashcode; /* Hash code of this rtx or string. */
375 union
377 char *str; /* The string (negative hash codes) */
378 rtx rtl; /* or the RTL recorded here. */
379 } u;
382 /* Now here is the hash table. When recording an RTL, it is added to
383 the slot whose index is the hash code mod the table size. Note
384 that the hash table is used for several kinds of RTL (see attr_rtx)
385 and for strings. While all these live in the same table, they are
386 completely independent, and the hash code is computed differently
387 for each. */
389 #define RTL_HASH_SIZE 4093
390 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
392 /* Here is how primitive or already-shared RTL's hash
393 codes are made. */
394 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
396 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
398 static void
399 attr_hash_add_rtx (int hashcode, rtx rtl)
401 struct attr_hash *h;
403 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
404 h->hashcode = hashcode;
405 h->u.rtl = rtl;
406 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
407 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
410 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
412 static void
413 attr_hash_add_string (int hashcode, char *str)
415 struct attr_hash *h;
417 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
418 h->hashcode = -hashcode;
419 h->u.str = str;
420 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
421 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
424 /* Generate an RTL expression, but avoid duplicates.
425 Set the ATTR_PERMANENT_P flag for these permanent objects.
427 In some cases we cannot uniquify; then we return an ordinary
428 impermanent rtx with ATTR_PERMANENT_P clear.
430 Args are as follows:
432 rtx attr_rtx (code, [element1, ..., elementn]) */
434 static rtx
435 attr_rtx_1 (enum rtx_code code, va_list p)
437 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
438 int hashcode;
439 struct attr_hash *h;
440 struct obstack *old_obstack = rtl_obstack;
442 /* For each of several cases, search the hash table for an existing entry.
443 Use that entry if one is found; otherwise create a new RTL and add it
444 to the table. */
446 if (GET_RTX_CLASS (code) == RTX_UNARY)
448 rtx arg0 = va_arg (p, rtx);
450 /* A permanent object cannot point to impermanent ones. */
451 if (! ATTR_PERMANENT_P (arg0))
453 rt_val = rtx_alloc (code);
454 XEXP (rt_val, 0) = arg0;
455 return rt_val;
458 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
459 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
460 if (h->hashcode == hashcode
461 && GET_CODE (h->u.rtl) == code
462 && XEXP (h->u.rtl, 0) == arg0)
463 return h->u.rtl;
465 if (h == 0)
467 rtl_obstack = hash_obstack;
468 rt_val = rtx_alloc (code);
469 XEXP (rt_val, 0) = arg0;
472 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
473 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
474 || GET_RTX_CLASS (code) == RTX_COMPARE
475 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
477 rtx arg0 = va_arg (p, rtx);
478 rtx arg1 = va_arg (p, rtx);
480 /* A permanent object cannot point to impermanent ones. */
481 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
483 rt_val = rtx_alloc (code);
484 XEXP (rt_val, 0) = arg0;
485 XEXP (rt_val, 1) = arg1;
486 return rt_val;
489 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
490 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
491 if (h->hashcode == hashcode
492 && GET_CODE (h->u.rtl) == code
493 && XEXP (h->u.rtl, 0) == arg0
494 && XEXP (h->u.rtl, 1) == arg1)
495 return h->u.rtl;
497 if (h == 0)
499 rtl_obstack = hash_obstack;
500 rt_val = rtx_alloc (code);
501 XEXP (rt_val, 0) = arg0;
502 XEXP (rt_val, 1) = arg1;
505 else if (GET_RTX_LENGTH (code) == 1
506 && GET_RTX_FORMAT (code)[0] == 's')
508 char *arg0 = va_arg (p, char *);
510 arg0 = DEF_ATTR_STRING (arg0);
512 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
513 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
514 if (h->hashcode == hashcode
515 && GET_CODE (h->u.rtl) == code
516 && XSTR (h->u.rtl, 0) == arg0)
517 return h->u.rtl;
519 if (h == 0)
521 rtl_obstack = hash_obstack;
522 rt_val = rtx_alloc (code);
523 XSTR (rt_val, 0) = arg0;
526 else if (GET_RTX_LENGTH (code) == 2
527 && GET_RTX_FORMAT (code)[0] == 's'
528 && GET_RTX_FORMAT (code)[1] == 's')
530 char *arg0 = va_arg (p, char *);
531 char *arg1 = va_arg (p, char *);
533 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
534 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
535 if (h->hashcode == hashcode
536 && GET_CODE (h->u.rtl) == code
537 && XSTR (h->u.rtl, 0) == arg0
538 && XSTR (h->u.rtl, 1) == arg1)
539 return h->u.rtl;
541 if (h == 0)
543 rtl_obstack = hash_obstack;
544 rt_val = rtx_alloc (code);
545 XSTR (rt_val, 0) = arg0;
546 XSTR (rt_val, 1) = arg1;
549 else if (code == CONST_INT)
551 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
552 if (arg0 == 0)
553 return false_rtx;
554 else if (arg0 == 1)
555 return true_rtx;
556 else
557 goto nohash;
559 else
561 int i; /* Array indices... */
562 const char *fmt; /* Current rtx's format... */
563 nohash:
564 rt_val = rtx_alloc (code); /* Allocate the storage space. */
566 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
567 for (i = 0; i < GET_RTX_LENGTH (code); i++)
569 switch (*fmt++)
571 case '0': /* Unused field. */
572 break;
574 case 'i': /* An integer? */
575 XINT (rt_val, i) = va_arg (p, int);
576 break;
578 case 'w': /* A wide integer? */
579 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
580 break;
582 case 's': /* A string? */
583 XSTR (rt_val, i) = va_arg (p, char *);
584 break;
586 case 'e': /* An expression? */
587 case 'u': /* An insn? Same except when printing. */
588 XEXP (rt_val, i) = va_arg (p, rtx);
589 break;
591 case 'E': /* An RTX vector? */
592 XVEC (rt_val, i) = va_arg (p, rtvec);
593 break;
595 default:
596 gcc_unreachable ();
599 return rt_val;
602 rtl_obstack = old_obstack;
603 attr_hash_add_rtx (hashcode, rt_val);
604 ATTR_PERMANENT_P (rt_val) = 1;
605 return rt_val;
608 static rtx
609 attr_rtx (enum rtx_code code, ...)
611 rtx result;
612 va_list p;
614 va_start (p, code);
615 result = attr_rtx_1 (code, p);
616 va_end (p);
617 return result;
620 /* Create a new string printed with the printf line arguments into a space
621 of at most LEN bytes:
623 rtx attr_printf (len, format, [arg1, ..., argn]) */
625 char *
626 attr_printf (unsigned int len, const char *fmt, ...)
628 char str[256];
629 va_list p;
631 va_start (p, fmt);
633 gcc_assert (len < sizeof str); /* Leave room for \0. */
635 vsprintf (str, fmt, p);
636 va_end (p);
638 return DEF_ATTR_STRING (str);
641 static rtx
642 attr_eq (const char *name, const char *value)
644 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
647 static const char *
648 attr_numeral (int n)
650 return XSTR (make_numeric_value (n), 0);
653 /* Return a permanent (possibly shared) copy of a string STR (not assumed
654 to be null terminated) with LEN bytes. */
656 static char *
657 attr_string (const char *str, int len)
659 struct attr_hash *h;
660 int hashcode;
661 int i;
662 char *new_str;
664 /* Compute the hash code. */
665 hashcode = (len + 1) * 613 + (unsigned) str[0];
666 for (i = 1; i <= len; i += 2)
667 hashcode = ((hashcode * 613) + (unsigned) str[i]);
668 if (hashcode < 0)
669 hashcode = -hashcode;
671 /* Search the table for the string. */
672 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
673 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
674 && !strncmp (h->u.str, str, len))
675 return h->u.str; /* <-- return if found. */
677 /* Not found; create a permanent copy and add it to the hash table. */
678 new_str = obstack_alloc (hash_obstack, len + 1);
679 memcpy (new_str, str, len);
680 new_str[len] = '\0';
681 attr_hash_add_string (hashcode, new_str);
683 return new_str; /* Return the new string. */
686 /* Check two rtx's for equality of contents,
687 taking advantage of the fact that if both are hashed
688 then they can't be equal unless they are the same object. */
690 static int
691 attr_equal_p (rtx x, rtx y)
693 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
694 && rtx_equal_p (x, y)));
697 /* Copy an attribute value expression,
698 descending to all depths, but not copying any
699 permanent hashed subexpressions. */
701 static rtx
702 attr_copy_rtx (rtx orig)
704 rtx copy;
705 int i, j;
706 RTX_CODE code;
707 const char *format_ptr;
709 /* No need to copy a permanent object. */
710 if (ATTR_PERMANENT_P (orig))
711 return orig;
713 code = GET_CODE (orig);
715 switch (code)
717 case REG:
718 case CONST_INT:
719 case CONST_DOUBLE:
720 case CONST_VECTOR:
721 case SYMBOL_REF:
722 case CODE_LABEL:
723 case PC:
724 case CC0:
725 return orig;
727 default:
728 break;
731 copy = rtx_alloc (code);
732 PUT_MODE (copy, GET_MODE (orig));
733 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
734 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
735 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
736 ATTR_EQ_ATTR_P (copy) = ATTR_EQ_ATTR_P (orig);
738 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
740 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
742 switch (*format_ptr++)
744 case 'e':
745 XEXP (copy, i) = XEXP (orig, i);
746 if (XEXP (orig, i) != NULL)
747 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
748 break;
750 case 'E':
751 case 'V':
752 XVEC (copy, i) = XVEC (orig, i);
753 if (XVEC (orig, i) != NULL)
755 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
756 for (j = 0; j < XVECLEN (copy, i); j++)
757 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
759 break;
761 case 'n':
762 case 'i':
763 XINT (copy, i) = XINT (orig, i);
764 break;
766 case 'w':
767 XWINT (copy, i) = XWINT (orig, i);
768 break;
770 case 's':
771 case 'S':
772 XSTR (copy, i) = XSTR (orig, i);
773 break;
775 default:
776 gcc_unreachable ();
779 return copy;
782 /* Given a test expression for an attribute, ensure it is validly formed.
783 IS_CONST indicates whether the expression is constant for each compiler
784 run (a constant expression may not test any particular insn).
786 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
787 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
788 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
790 Update the string address in EQ_ATTR expression to be the same used
791 in the attribute (or `alternative_name') to speed up subsequent
792 `find_attr' calls and eliminate most `strcmp' calls.
794 Return the new expression, if any. */
797 check_attr_test (rtx exp, int is_const, int lineno)
799 struct attr_desc *attr;
800 struct attr_value *av;
801 const char *name_ptr, *p;
802 rtx orexp, newexp;
804 switch (GET_CODE (exp))
806 case EQ_ATTR:
807 /* Handle negation test. */
808 if (XSTR (exp, 1)[0] == '!')
809 return check_attr_test (attr_rtx (NOT,
810 attr_eq (XSTR (exp, 0),
811 &XSTR (exp, 1)[1])),
812 is_const, lineno);
814 else if (n_comma_elts (XSTR (exp, 1)) == 1)
816 attr = find_attr (&XSTR (exp, 0), 0);
817 if (attr == NULL)
819 if (! strcmp (XSTR (exp, 0), "alternative"))
820 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
821 else
822 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
825 if (is_const && ! attr->is_const)
826 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
827 XSTR (exp, 0));
829 /* Copy this just to make it permanent,
830 so expressions using it can be permanent too. */
831 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
833 /* It shouldn't be possible to simplify the value given to a
834 constant attribute, so don't expand this until it's time to
835 write the test expression. */
836 if (attr->is_const)
837 ATTR_IND_SIMPLIFIED_P (exp) = 1;
839 if (attr->is_numeric)
841 for (p = XSTR (exp, 1); *p; p++)
842 if (! ISDIGIT (*p))
843 fatal ("attribute `%s' takes only numeric values",
844 XSTR (exp, 0));
846 else
848 for (av = attr->first_value; av; av = av->next)
849 if (GET_CODE (av->value) == CONST_STRING
850 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
851 break;
853 if (av == NULL)
854 fatal ("unknown value `%s' for `%s' attribute",
855 XSTR (exp, 1), XSTR (exp, 0));
858 else
860 if (! strcmp (XSTR (exp, 0), "alternative"))
862 int set = 0;
864 name_ptr = XSTR (exp, 1);
865 while ((p = next_comma_elt (&name_ptr)) != NULL)
866 set |= 1 << atoi (p);
868 return mk_attr_alt (set);
870 else
872 /* Make an IOR tree of the possible values. */
873 orexp = false_rtx;
874 name_ptr = XSTR (exp, 1);
875 while ((p = next_comma_elt (&name_ptr)) != NULL)
877 newexp = attr_eq (XSTR (exp, 0), p);
878 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
881 return check_attr_test (orexp, is_const, lineno);
884 break;
886 case ATTR_FLAG:
887 break;
889 case CONST_INT:
890 /* Either TRUE or FALSE. */
891 if (XWINT (exp, 0))
892 return true_rtx;
893 else
894 return false_rtx;
896 case IOR:
897 case AND:
898 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
899 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
900 break;
902 case NOT:
903 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
904 break;
906 case MATCH_OPERAND:
907 if (is_const)
908 fatal ("RTL operator \"%s\" not valid in constant attribute test",
909 GET_RTX_NAME (GET_CODE (exp)));
910 /* These cases can't be simplified. */
911 ATTR_IND_SIMPLIFIED_P (exp) = 1;
912 break;
914 case LE: case LT: case GT: case GE:
915 case LEU: case LTU: case GTU: case GEU:
916 case NE: case EQ:
917 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
918 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
919 exp = attr_rtx (GET_CODE (exp),
920 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
921 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
922 /* These cases can't be simplified. */
923 ATTR_IND_SIMPLIFIED_P (exp) = 1;
924 break;
926 case SYMBOL_REF:
927 if (is_const)
929 /* These cases are valid for constant attributes, but can't be
930 simplified. */
931 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
932 ATTR_IND_SIMPLIFIED_P (exp) = 1;
933 break;
935 default:
936 fatal ("RTL operator \"%s\" not valid in attribute test",
937 GET_RTX_NAME (GET_CODE (exp)));
940 return exp;
943 /* Given an expression, ensure that it is validly formed and that all named
944 attribute values are valid for the given attribute. Issue a fatal error
945 if not. If no attribute is specified, assume a numeric attribute.
947 Return a perhaps modified replacement expression for the value. */
949 static rtx
950 check_attr_value (rtx exp, struct attr_desc *attr)
952 struct attr_value *av;
953 const char *p;
954 int i;
956 switch (GET_CODE (exp))
958 case CONST_INT:
959 if (attr && ! attr->is_numeric)
961 message_with_line (attr->lineno,
962 "CONST_INT not valid for non-numeric attribute %s",
963 attr->name);
964 have_error = 1;
965 break;
968 if (INTVAL (exp) < 0)
970 message_with_line (attr->lineno,
971 "negative numeric value specified for attribute %s",
972 attr->name);
973 have_error = 1;
974 break;
976 break;
978 case CONST_STRING:
979 if (! strcmp (XSTR (exp, 0), "*"))
980 break;
982 if (attr == 0 || attr->is_numeric)
984 p = XSTR (exp, 0);
985 for (; *p; p++)
986 if (! ISDIGIT (*p))
988 message_with_line (attr ? attr->lineno : 0,
989 "non-numeric value for numeric attribute %s",
990 attr ? attr->name : "internal");
991 have_error = 1;
992 break;
994 break;
997 for (av = attr->first_value; av; av = av->next)
998 if (GET_CODE (av->value) == CONST_STRING
999 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1000 break;
1002 if (av == NULL)
1004 message_with_line (attr->lineno,
1005 "unknown value `%s' for `%s' attribute",
1006 XSTR (exp, 0), attr ? attr->name : "internal");
1007 have_error = 1;
1009 break;
1011 case IF_THEN_ELSE:
1012 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1013 attr ? attr->is_const : 0,
1014 attr ? attr->lineno : 0);
1015 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1016 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1017 break;
1019 case PLUS:
1020 case MINUS:
1021 case MULT:
1022 case DIV:
1023 case MOD:
1024 if (attr && !attr->is_numeric)
1026 message_with_line (attr->lineno,
1027 "invalid operation `%s' for non-numeric attribute value",
1028 GET_RTX_NAME (GET_CODE (exp)));
1029 have_error = 1;
1030 break;
1032 /* Fall through. */
1034 case IOR:
1035 case AND:
1036 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1037 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1038 break;
1040 case FFS:
1041 case CLZ:
1042 case CTZ:
1043 case POPCOUNT:
1044 case PARITY:
1045 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1046 break;
1048 case COND:
1049 if (XVECLEN (exp, 0) % 2 != 0)
1051 message_with_line (attr->lineno,
1052 "first operand of COND must have even length");
1053 have_error = 1;
1054 break;
1057 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1059 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1060 attr ? attr->is_const : 0,
1061 attr ? attr->lineno : 0);
1062 XVECEXP (exp, 0, i + 1)
1063 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1066 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1067 break;
1069 case ATTR:
1071 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1072 if (attr2 == NULL)
1074 message_with_line (attr ? attr->lineno : 0,
1075 "unknown attribute `%s' in ATTR",
1076 XSTR (exp, 0));
1077 have_error = 1;
1079 else if (attr && attr->is_const && ! attr2->is_const)
1081 message_with_line (attr->lineno,
1082 "non-constant attribute `%s' referenced from `%s'",
1083 XSTR (exp, 0), attr->name);
1084 have_error = 1;
1086 else if (attr
1087 && attr->is_numeric != attr2->is_numeric)
1089 message_with_line (attr->lineno,
1090 "numeric attribute mismatch calling `%s' from `%s'",
1091 XSTR (exp, 0), attr->name);
1092 have_error = 1;
1095 break;
1097 case SYMBOL_REF:
1098 /* A constant SYMBOL_REF is valid as a constant attribute test and
1099 is expanded later by make_canonical into a COND. In a non-constant
1100 attribute test, it is left be. */
1101 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1103 default:
1104 message_with_line (attr ? attr->lineno : 0,
1105 "invalid operation `%s' for attribute value",
1106 GET_RTX_NAME (GET_CODE (exp)));
1107 have_error = 1;
1108 break;
1111 return exp;
1114 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1115 It becomes a COND with each test being (eq_attr "alternative "n") */
1117 static rtx
1118 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1120 int num_alt = id->num_alternatives;
1121 rtx condexp;
1122 int i;
1124 if (XVECLEN (exp, 1) != num_alt)
1126 message_with_line (id->lineno,
1127 "bad number of entries in SET_ATTR_ALTERNATIVE");
1128 have_error = 1;
1129 return NULL_RTX;
1132 /* Make a COND with all tests but the last. Select the last value via the
1133 default. */
1134 condexp = rtx_alloc (COND);
1135 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1137 for (i = 0; i < num_alt - 1; i++)
1139 const char *p;
1140 p = attr_numeral (i);
1142 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1143 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1146 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1148 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1151 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1152 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1154 static rtx
1155 convert_set_attr (rtx exp, struct insn_def *id)
1157 rtx newexp;
1158 const char *name_ptr;
1159 char *p;
1160 int n;
1162 /* See how many alternative specified. */
1163 n = n_comma_elts (XSTR (exp, 1));
1164 if (n == 1)
1165 return attr_rtx (SET,
1166 attr_rtx (ATTR, XSTR (exp, 0)),
1167 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1169 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1170 XSTR (newexp, 0) = XSTR (exp, 0);
1171 XVEC (newexp, 1) = rtvec_alloc (n);
1173 /* Process each comma-separated name. */
1174 name_ptr = XSTR (exp, 1);
1175 n = 0;
1176 while ((p = next_comma_elt (&name_ptr)) != NULL)
1177 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1179 return convert_set_attr_alternative (newexp, id);
1182 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1183 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1184 expressions. */
1186 static void
1187 check_defs (void)
1189 struct insn_def *id;
1190 struct attr_desc *attr;
1191 int i;
1192 rtx value;
1194 for (id = defs; id; id = id->next)
1196 if (XVEC (id->def, id->vec_idx) == NULL)
1197 continue;
1199 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1201 value = XVECEXP (id->def, id->vec_idx, i);
1202 switch (GET_CODE (value))
1204 case SET:
1205 if (GET_CODE (XEXP (value, 0)) != ATTR)
1207 message_with_line (id->lineno, "bad attribute set");
1208 have_error = 1;
1209 value = NULL_RTX;
1211 break;
1213 case SET_ATTR_ALTERNATIVE:
1214 value = convert_set_attr_alternative (value, id);
1215 break;
1217 case SET_ATTR:
1218 value = convert_set_attr (value, id);
1219 break;
1221 default:
1222 message_with_line (id->lineno, "invalid attribute code %s",
1223 GET_RTX_NAME (GET_CODE (value)));
1224 have_error = 1;
1225 value = NULL_RTX;
1227 if (value == NULL_RTX)
1228 continue;
1230 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1232 message_with_line (id->lineno, "unknown attribute %s",
1233 XSTR (XEXP (value, 0), 0));
1234 have_error = 1;
1235 continue;
1238 XVECEXP (id->def, id->vec_idx, i) = value;
1239 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1244 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1245 expressions by converting them into a COND. This removes cases from this
1246 program. Also, replace an attribute value of "*" with the default attribute
1247 value. */
1249 static rtx
1250 make_canonical (struct attr_desc *attr, rtx exp)
1252 int i;
1253 rtx newexp;
1255 switch (GET_CODE (exp))
1257 case CONST_INT:
1258 exp = make_numeric_value (INTVAL (exp));
1259 break;
1261 case CONST_STRING:
1262 if (! strcmp (XSTR (exp, 0), "*"))
1264 if (attr == 0 || attr->default_val == 0)
1265 fatal ("(attr_value \"*\") used in invalid context");
1266 exp = attr->default_val->value;
1268 else
1269 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1271 break;
1273 case SYMBOL_REF:
1274 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1275 break;
1276 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1277 This makes the COND something that won't be considered an arbitrary
1278 expression by walk_attr_value. */
1279 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1280 exp = check_attr_value (exp, attr);
1281 break;
1283 case IF_THEN_ELSE:
1284 newexp = rtx_alloc (COND);
1285 XVEC (newexp, 0) = rtvec_alloc (2);
1286 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1287 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1289 XEXP (newexp, 1) = XEXP (exp, 2);
1291 exp = newexp;
1292 /* Fall through to COND case since this is now a COND. */
1294 case COND:
1296 int allsame = 1;
1297 rtx defval;
1299 /* First, check for degenerate COND. */
1300 if (XVECLEN (exp, 0) == 0)
1301 return make_canonical (attr, XEXP (exp, 1));
1302 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1304 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1306 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1307 XVECEXP (exp, 0, i + 1)
1308 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1309 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1310 allsame = 0;
1312 if (allsame)
1313 return defval;
1315 break;
1317 default:
1318 break;
1321 return exp;
1324 static rtx
1325 copy_boolean (rtx exp)
1327 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1328 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1329 copy_boolean (XEXP (exp, 1)));
1330 if (GET_CODE (exp) == MATCH_OPERAND)
1332 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1333 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1335 else if (GET_CODE (exp) == EQ_ATTR)
1337 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1338 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1341 return exp;
1344 /* Given a value and an attribute description, return a `struct attr_value *'
1345 that represents that value. This is either an existing structure, if the
1346 value has been previously encountered, or a newly-created structure.
1348 `insn_code' is the code of an insn whose attribute has the specified
1349 value (-2 if not processing an insn). We ensure that all insns for
1350 a given value have the same number of alternatives if the value checks
1351 alternatives. */
1353 static struct attr_value *
1354 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1356 struct attr_value *av;
1357 int num_alt = 0;
1359 value = make_canonical (attr, value);
1360 if (compares_alternatives_p (value))
1362 if (insn_code < 0 || insn_alternatives == NULL)
1363 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1364 else
1365 num_alt = insn_alternatives[insn_code];
1368 for (av = attr->first_value; av; av = av->next)
1369 if (rtx_equal_p (value, av->value)
1370 && (num_alt == 0 || av->first_insn == NULL
1371 || insn_alternatives[av->first_insn->def->insn_code]))
1372 return av;
1374 av = oballoc (sizeof (struct attr_value));
1375 av->value = value;
1376 av->next = attr->first_value;
1377 attr->first_value = av;
1378 av->first_insn = NULL;
1379 av->num_insns = 0;
1380 av->has_asm_insn = 0;
1382 return av;
1385 /* After all DEFINE_DELAYs have been read in, create internal attributes
1386 to generate the required routines.
1388 First, we compute the number of delay slots for each insn (as a COND of
1389 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1390 delay type is specified, we compute a similar function giving the
1391 DEFINE_DELAY ordinal for each insn.
1393 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1394 tells whether a given insn can be in that delay slot.
1396 Normal attribute filling and optimization expands these to contain the
1397 information needed to handle delay slots. */
1399 static void
1400 expand_delays (void)
1402 struct delay_desc *delay;
1403 rtx condexp;
1404 rtx newexp;
1405 int i;
1406 char *p;
1408 /* First, generate data for `num_delay_slots' function. */
1410 condexp = rtx_alloc (COND);
1411 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1412 XEXP (condexp, 1) = make_numeric_value (0);
1414 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1416 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1417 XVECEXP (condexp, 0, i + 1)
1418 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1421 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1423 /* If more than one delay type, do the same for computing the delay type. */
1424 if (num_delays > 1)
1426 condexp = rtx_alloc (COND);
1427 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1428 XEXP (condexp, 1) = make_numeric_value (0);
1430 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1432 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1433 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1436 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1439 /* For each delay possibility and delay slot, compute an eligibility
1440 attribute for non-annulled insns and for each type of annulled (annul
1441 if true and annul if false). */
1442 for (delay = delays; delay; delay = delay->next)
1444 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1446 condexp = XVECEXP (delay->def, 1, i);
1447 if (condexp == 0)
1448 condexp = false_rtx;
1449 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1450 make_numeric_value (1), make_numeric_value (0));
1452 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1453 "*delay_%d_%d", delay->num, i / 3);
1454 make_internal_attr (p, newexp, ATTR_SPECIAL);
1456 if (have_annul_true)
1458 condexp = XVECEXP (delay->def, 1, i + 1);
1459 if (condexp == 0) condexp = false_rtx;
1460 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1461 make_numeric_value (1),
1462 make_numeric_value (0));
1463 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1464 "*annul_true_%d_%d", delay->num, i / 3);
1465 make_internal_attr (p, newexp, ATTR_SPECIAL);
1468 if (have_annul_false)
1470 condexp = XVECEXP (delay->def, 1, i + 2);
1471 if (condexp == 0) condexp = false_rtx;
1472 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1473 make_numeric_value (1),
1474 make_numeric_value (0));
1475 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1476 "*annul_false_%d_%d", delay->num, i / 3);
1477 make_internal_attr (p, newexp, ATTR_SPECIAL);
1483 /* Once all attributes and insns have been read and checked, we construct for
1484 each attribute value a list of all the insns that have that value for
1485 the attribute. */
1487 static void
1488 fill_attr (struct attr_desc *attr)
1490 struct attr_value *av;
1491 struct insn_ent *ie;
1492 struct insn_def *id;
1493 int i;
1494 rtx value;
1496 /* Don't fill constant attributes. The value is independent of
1497 any particular insn. */
1498 if (attr->is_const)
1499 return;
1501 for (id = defs; id; id = id->next)
1503 /* If no value is specified for this insn for this attribute, use the
1504 default. */
1505 value = NULL;
1506 if (XVEC (id->def, id->vec_idx))
1507 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1508 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1509 attr->name))
1510 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1512 if (value == NULL)
1513 av = attr->default_val;
1514 else
1515 av = get_attr_value (value, attr, id->insn_code);
1517 ie = oballoc (sizeof (struct insn_ent));
1518 ie->def = id;
1519 insert_insn_ent (av, ie);
1523 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1524 test that checks relative positions of insns (uses MATCH_DUP or PC).
1525 If so, replace it with what is obtained by passing the expression to
1526 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1527 recursively on each value (including the default value). Otherwise,
1528 return the value returned by NO_ADDRESS_FN applied to EXP. */
1530 static rtx
1531 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1532 rtx (*address_fn) (rtx))
1534 int i;
1535 rtx newexp;
1537 if (GET_CODE (exp) == COND)
1539 /* See if any tests use addresses. */
1540 address_used = 0;
1541 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1542 walk_attr_value (XVECEXP (exp, 0, i));
1544 if (address_used)
1545 return (*address_fn) (exp);
1547 /* Make a new copy of this COND, replacing each element. */
1548 newexp = rtx_alloc (COND);
1549 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1550 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1552 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1553 XVECEXP (newexp, 0, i + 1)
1554 = substitute_address (XVECEXP (exp, 0, i + 1),
1555 no_address_fn, address_fn);
1558 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1559 no_address_fn, address_fn);
1561 return newexp;
1564 else if (GET_CODE (exp) == IF_THEN_ELSE)
1566 address_used = 0;
1567 walk_attr_value (XEXP (exp, 0));
1568 if (address_used)
1569 return (*address_fn) (exp);
1571 return attr_rtx (IF_THEN_ELSE,
1572 substitute_address (XEXP (exp, 0),
1573 no_address_fn, address_fn),
1574 substitute_address (XEXP (exp, 1),
1575 no_address_fn, address_fn),
1576 substitute_address (XEXP (exp, 2),
1577 no_address_fn, address_fn));
1580 return (*no_address_fn) (exp);
1583 /* Make new attributes from the `length' attribute. The following are made,
1584 each corresponding to a function called from `shorten_branches' or
1585 `get_attr_length':
1587 *insn_default_length This is the length of the insn to be returned
1588 by `get_attr_length' before `shorten_branches'
1589 has been called. In each case where the length
1590 depends on relative addresses, the largest
1591 possible is used. This routine is also used
1592 to compute the initial size of the insn.
1594 *insn_variable_length_p This returns 1 if the insn's length depends
1595 on relative addresses, zero otherwise.
1597 *insn_current_length This is only called when it is known that the
1598 insn has a variable length and returns the
1599 current length, based on relative addresses.
1602 static void
1603 make_length_attrs (void)
1605 static const char *new_names[] =
1607 "*insn_default_length",
1608 "*insn_variable_length_p",
1609 "*insn_current_length"
1611 static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn};
1612 static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn};
1613 size_t i;
1614 struct attr_desc *length_attr, *new_attr;
1615 struct attr_value *av, *new_av;
1616 struct insn_ent *ie, *new_ie;
1618 /* See if length attribute is defined. If so, it must be numeric. Make
1619 it special so we don't output anything for it. */
1620 length_attr = find_attr (&length_str, 0);
1621 if (length_attr == 0)
1622 return;
1624 if (! length_attr->is_numeric)
1625 fatal ("length attribute must be numeric");
1627 length_attr->is_const = 0;
1628 length_attr->is_special = 1;
1630 /* Make each new attribute, in turn. */
1631 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1633 make_internal_attr (new_names[i],
1634 substitute_address (length_attr->default_val->value,
1635 no_address_fn[i], address_fn[i]),
1636 ATTR_NONE);
1637 new_attr = find_attr (&new_names[i], 0);
1638 for (av = length_attr->first_value; av; av = av->next)
1639 for (ie = av->first_insn; ie; ie = ie->next)
1641 new_av = get_attr_value (substitute_address (av->value,
1642 no_address_fn[i],
1643 address_fn[i]),
1644 new_attr, ie->def->insn_code);
1645 new_ie = oballoc (sizeof (struct insn_ent));
1646 new_ie->def = ie->def;
1647 insert_insn_ent (new_av, new_ie);
1652 /* Utility functions called from above routine. */
1654 static rtx
1655 identity_fn (rtx exp)
1657 return exp;
1660 static rtx
1661 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1663 return make_numeric_value (0);
1666 static rtx
1667 one_fn (rtx exp ATTRIBUTE_UNUSED)
1669 return make_numeric_value (1);
1672 static rtx
1673 max_fn (rtx exp)
1675 int unknown;
1676 return make_numeric_value (max_attr_value (exp, &unknown));
1679 static void
1680 write_length_unit_log (void)
1682 struct attr_desc *length_attr = find_attr (&length_str, 0);
1683 struct attr_value *av;
1684 struct insn_ent *ie;
1685 unsigned int length_unit_log, length_or;
1686 int unknown = 0;
1688 if (length_attr == 0)
1689 return;
1690 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1691 for (av = length_attr->first_value; av; av = av->next)
1692 for (ie = av->first_insn; ie; ie = ie->next)
1693 length_or |= or_attr_value (av->value, &unknown);
1695 if (unknown)
1696 length_unit_log = 0;
1697 else
1699 length_or = ~length_or;
1700 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1701 length_unit_log++;
1703 printf ("int length_unit_log = %u;\n", length_unit_log);
1706 /* Take a COND expression and see if any of the conditions in it can be
1707 simplified. If any are known true or known false for the particular insn
1708 code, the COND can be further simplified.
1710 Also call ourselves on any COND operations that are values of this COND.
1712 We do not modify EXP; rather, we make and return a new rtx. */
1714 static rtx
1715 simplify_cond (rtx exp, int insn_code, int insn_index)
1717 int i, j;
1718 /* We store the desired contents here,
1719 then build a new expression if they don't match EXP. */
1720 rtx defval = XEXP (exp, 1);
1721 rtx new_defval = XEXP (exp, 1);
1722 int len = XVECLEN (exp, 0);
1723 rtx *tests = xmalloc (len * sizeof (rtx));
1724 int allsame = 1;
1725 rtx ret;
1727 /* This lets us free all storage allocated below, if appropriate. */
1728 obstack_finish (rtl_obstack);
1730 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1732 /* See if default value needs simplification. */
1733 if (GET_CODE (defval) == COND)
1734 new_defval = simplify_cond (defval, insn_code, insn_index);
1736 /* Simplify the subexpressions, and see what tests we can get rid of. */
1738 for (i = 0; i < len; i += 2)
1740 rtx newtest, newval;
1742 /* Simplify this test. */
1743 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1744 tests[i] = newtest;
1746 newval = tests[i + 1];
1747 /* See if this value may need simplification. */
1748 if (GET_CODE (newval) == COND)
1749 newval = simplify_cond (newval, insn_code, insn_index);
1751 /* Look for ways to delete or combine this test. */
1752 if (newtest == true_rtx)
1754 /* If test is true, make this value the default
1755 and discard this + any following tests. */
1756 len = i;
1757 defval = tests[i + 1];
1758 new_defval = newval;
1761 else if (newtest == false_rtx)
1763 /* If test is false, discard it and its value. */
1764 for (j = i; j < len - 2; j++)
1765 tests[j] = tests[j + 2];
1766 i -= 2;
1767 len -= 2;
1770 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1772 /* If this value and the value for the prev test are the same,
1773 merge the tests. */
1775 tests[i - 2]
1776 = insert_right_side (IOR, tests[i - 2], newtest,
1777 insn_code, insn_index);
1779 /* Delete this test/value. */
1780 for (j = i; j < len - 2; j++)
1781 tests[j] = tests[j + 2];
1782 len -= 2;
1783 i -= 2;
1786 else
1787 tests[i + 1] = newval;
1790 /* If the last test in a COND has the same value
1791 as the default value, that test isn't needed. */
1793 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1794 len -= 2;
1796 /* See if we changed anything. */
1797 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1798 allsame = 0;
1799 else
1800 for (i = 0; i < len; i++)
1801 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1803 allsame = 0;
1804 break;
1807 if (len == 0)
1809 if (GET_CODE (defval) == COND)
1810 ret = simplify_cond (defval, insn_code, insn_index);
1811 else
1812 ret = defval;
1814 else if (allsame)
1815 ret = exp;
1816 else
1818 rtx newexp = rtx_alloc (COND);
1820 XVEC (newexp, 0) = rtvec_alloc (len);
1821 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1822 XEXP (newexp, 1) = new_defval;
1823 ret = newexp;
1825 free (tests);
1826 return ret;
1829 /* Remove an insn entry from an attribute value. */
1831 static void
1832 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1834 struct insn_ent *previe;
1836 if (av->first_insn == ie)
1837 av->first_insn = ie->next;
1838 else
1840 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1842 previe->next = ie->next;
1845 av->num_insns--;
1846 if (ie->def->insn_code == -1)
1847 av->has_asm_insn = 0;
1849 num_insn_ents--;
1852 /* Insert an insn entry in an attribute value list. */
1854 static void
1855 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1857 ie->next = av->first_insn;
1858 av->first_insn = ie;
1859 av->num_insns++;
1860 if (ie->def->insn_code == -1)
1861 av->has_asm_insn = 1;
1863 num_insn_ents++;
1866 /* This is a utility routine to take an expression that is a tree of either
1867 AND or IOR expressions and insert a new term. The new term will be
1868 inserted at the right side of the first node whose code does not match
1869 the root. A new node will be created with the root's code. Its left
1870 side will be the old right side and its right side will be the new
1871 term.
1873 If the `term' is itself a tree, all its leaves will be inserted. */
1875 static rtx
1876 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1878 rtx newexp;
1880 /* Avoid consing in some special cases. */
1881 if (code == AND && term == true_rtx)
1882 return exp;
1883 if (code == AND && term == false_rtx)
1884 return false_rtx;
1885 if (code == AND && exp == true_rtx)
1886 return term;
1887 if (code == AND && exp == false_rtx)
1888 return false_rtx;
1889 if (code == IOR && term == true_rtx)
1890 return true_rtx;
1891 if (code == IOR && term == false_rtx)
1892 return exp;
1893 if (code == IOR && exp == true_rtx)
1894 return true_rtx;
1895 if (code == IOR && exp == false_rtx)
1896 return term;
1897 if (attr_equal_p (exp, term))
1898 return exp;
1900 if (GET_CODE (term) == code)
1902 exp = insert_right_side (code, exp, XEXP (term, 0),
1903 insn_code, insn_index);
1904 exp = insert_right_side (code, exp, XEXP (term, 1),
1905 insn_code, insn_index);
1907 return exp;
1910 if (GET_CODE (exp) == code)
1912 rtx new = insert_right_side (code, XEXP (exp, 1),
1913 term, insn_code, insn_index);
1914 if (new != XEXP (exp, 1))
1915 /* Make a copy of this expression and call recursively. */
1916 newexp = attr_rtx (code, XEXP (exp, 0), new);
1917 else
1918 newexp = exp;
1920 else
1922 /* Insert the new term. */
1923 newexp = attr_rtx (code, exp, term);
1926 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1929 /* If we have an expression which AND's a bunch of
1930 (not (eq_attrq "alternative" "n"))
1931 terms, we may have covered all or all but one of the possible alternatives.
1932 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1934 This routine is passed an expression and either AND or IOR. It returns a
1935 bitmask indicating which alternatives are mentioned within EXP. */
1937 static int
1938 compute_alternative_mask (rtx exp, enum rtx_code code)
1940 const char *string;
1941 if (GET_CODE (exp) == code)
1942 return compute_alternative_mask (XEXP (exp, 0), code)
1943 | compute_alternative_mask (XEXP (exp, 1), code);
1945 else if (code == AND && GET_CODE (exp) == NOT
1946 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1947 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1948 string = XSTR (XEXP (exp, 0), 1);
1950 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1951 && XSTR (exp, 0) == alternative_name)
1952 string = XSTR (exp, 1);
1954 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1956 if (code == AND && XINT (exp, 1))
1957 return XINT (exp, 0);
1959 if (code == IOR && !XINT (exp, 1))
1960 return XINT (exp, 0);
1962 return 0;
1964 else
1965 return 0;
1967 if (string[1] == 0)
1968 return 1 << (string[0] - '0');
1969 return 1 << atoi (string);
1972 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1973 attribute with the value represented by that bit. */
1975 static rtx
1976 make_alternative_compare (int mask)
1978 return mk_attr_alt (mask);
1981 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1982 of "attr" for this insn code. From that value, we can compute a test
1983 showing when the EQ_ATTR will be true. This routine performs that
1984 computation. If a test condition involves an address, we leave the EQ_ATTR
1985 intact because addresses are only valid for the `length' attribute.
1987 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1988 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1990 static rtx
1991 evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
1993 rtx orexp, andexp;
1994 rtx right;
1995 rtx newexp;
1996 int i;
1998 switch (GET_CODE (value))
2000 case CONST_STRING:
2001 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
2002 newexp = true_rtx;
2003 else
2004 newexp = false_rtx;
2005 break;
2007 case SYMBOL_REF:
2009 char *p;
2010 char string[256];
2012 gcc_assert (GET_CODE (exp) == EQ_ATTR);
2013 gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
2014 <= 256);
2016 strcpy (string, XSTR (exp, 0));
2017 strcat (string, "_");
2018 strcat (string, XSTR (exp, 1));
2019 for (p = string; *p; p++)
2020 *p = TOUPPER (*p);
2022 newexp = attr_rtx (EQ, value,
2023 attr_rtx (SYMBOL_REF,
2024 DEF_ATTR_STRING (string)));
2025 break;
2028 case COND:
2029 /* We construct an IOR of all the cases for which the
2030 requested attribute value is present. Since we start with
2031 FALSE, if it is not present, FALSE will be returned.
2033 Each case is the AND of the NOT's of the previous conditions with the
2034 current condition; in the default case the current condition is TRUE.
2036 For each possible COND value, call ourselves recursively.
2038 The extra TRUE and FALSE expressions will be eliminated by another
2039 call to the simplification routine. */
2041 orexp = false_rtx;
2042 andexp = true_rtx;
2044 if (current_alternative_string)
2045 clear_struct_flag (value);
2047 for (i = 0; i < XVECLEN (value, 0); i += 2)
2049 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2050 insn_code, insn_index);
2052 SIMPLIFY_ALTERNATIVE (this);
2054 right = insert_right_side (AND, andexp, this,
2055 insn_code, insn_index);
2056 right = insert_right_side (AND, right,
2057 evaluate_eq_attr (exp,
2058 XVECEXP (value, 0,
2059 i + 1),
2060 insn_code, insn_index),
2061 insn_code, insn_index);
2062 orexp = insert_right_side (IOR, orexp, right,
2063 insn_code, insn_index);
2065 /* Add this condition into the AND expression. */
2066 newexp = attr_rtx (NOT, this);
2067 andexp = insert_right_side (AND, andexp, newexp,
2068 insn_code, insn_index);
2071 /* Handle the default case. */
2072 right = insert_right_side (AND, andexp,
2073 evaluate_eq_attr (exp, XEXP (value, 1),
2074 insn_code, insn_index),
2075 insn_code, insn_index);
2076 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2077 break;
2079 default:
2080 gcc_unreachable ();
2083 /* If uses an address, must return original expression. But set the
2084 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2086 address_used = 0;
2087 walk_attr_value (newexp);
2089 if (address_used)
2091 /* This had `&& current_alternative_string', which seems to be wrong. */
2092 if (! ATTR_IND_SIMPLIFIED_P (exp))
2093 return copy_rtx_unchanging (exp);
2094 return exp;
2096 else
2097 return newexp;
2100 /* This routine is called when an AND of a term with a tree of AND's is
2101 encountered. If the term or its complement is present in the tree, it
2102 can be replaced with TRUE or FALSE, respectively.
2104 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2105 be true and hence are complementary.
2107 There is one special case: If we see
2108 (and (not (eq_attr "att" "v1"))
2109 (eq_attr "att" "v2"))
2110 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2111 replace the term, not anything in the AND tree. So we pass a pointer to
2112 the term. */
2114 static rtx
2115 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2117 rtx left, right;
2118 rtx newexp;
2119 rtx temp;
2120 int left_eliminates_term, right_eliminates_term;
2122 if (GET_CODE (exp) == AND)
2124 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2125 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2126 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2128 newexp = attr_rtx (AND, left, right);
2130 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2134 else if (GET_CODE (exp) == IOR)
2136 /* For the IOR case, we do the same as above, except that we can
2137 only eliminate `term' if both sides of the IOR would do so. */
2138 temp = *pterm;
2139 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2140 left_eliminates_term = (temp == true_rtx);
2142 temp = *pterm;
2143 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2144 right_eliminates_term = (temp == true_rtx);
2146 if (left_eliminates_term && right_eliminates_term)
2147 *pterm = true_rtx;
2149 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2151 newexp = attr_rtx (IOR, left, right);
2153 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2157 /* Check for simplifications. Do some extra checking here since this
2158 routine is called so many times. */
2160 if (exp == *pterm)
2161 return true_rtx;
2163 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2164 return false_rtx;
2166 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2167 return false_rtx;
2169 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2171 if (attr_alt_subset_p (*pterm, exp))
2172 return true_rtx;
2174 if (attr_alt_subset_of_compl_p (*pterm, exp))
2175 return false_rtx;
2177 if (attr_alt_subset_p (exp, *pterm))
2178 *pterm = true_rtx;
2180 return exp;
2183 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2185 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2186 return exp;
2188 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2189 return true_rtx;
2190 else
2191 return false_rtx;
2194 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2195 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2197 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2198 return exp;
2200 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2201 return false_rtx;
2202 else
2203 return true_rtx;
2206 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2207 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2209 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2210 return exp;
2212 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2213 return false_rtx;
2214 else
2215 *pterm = true_rtx;
2218 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2220 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2221 return true_rtx;
2224 else if (GET_CODE (exp) == NOT)
2226 if (attr_equal_p (XEXP (exp, 0), *pterm))
2227 return false_rtx;
2230 else if (GET_CODE (*pterm) == NOT)
2232 if (attr_equal_p (XEXP (*pterm, 0), exp))
2233 return false_rtx;
2236 else if (attr_equal_p (exp, *pterm))
2237 return true_rtx;
2239 return exp;
2242 /* Similar to `simplify_and_tree', but for IOR trees. */
2244 static rtx
2245 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2247 rtx left, right;
2248 rtx newexp;
2249 rtx temp;
2250 int left_eliminates_term, right_eliminates_term;
2252 if (GET_CODE (exp) == IOR)
2254 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2255 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2256 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2258 newexp = attr_rtx (GET_CODE (exp), left, right);
2260 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2264 else if (GET_CODE (exp) == AND)
2266 /* For the AND case, we do the same as above, except that we can
2267 only eliminate `term' if both sides of the AND would do so. */
2268 temp = *pterm;
2269 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2270 left_eliminates_term = (temp == false_rtx);
2272 temp = *pterm;
2273 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2274 right_eliminates_term = (temp == false_rtx);
2276 if (left_eliminates_term && right_eliminates_term)
2277 *pterm = false_rtx;
2279 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2281 newexp = attr_rtx (GET_CODE (exp), left, right);
2283 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2287 if (attr_equal_p (exp, *pterm))
2288 return false_rtx;
2290 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2291 return true_rtx;
2293 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2294 return true_rtx;
2296 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2297 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2298 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2299 *pterm = false_rtx;
2301 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2302 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2303 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2304 return false_rtx;
2306 return exp;
2309 /* Compute approximate cost of the expression. Used to decide whether
2310 expression is cheap enough for inline. */
2311 static int
2312 attr_rtx_cost (rtx x)
2314 int cost = 0;
2315 enum rtx_code code;
2316 if (!x)
2317 return 0;
2318 code = GET_CODE (x);
2319 switch (code)
2321 case MATCH_OPERAND:
2322 if (XSTR (x, 1)[0])
2323 return 10;
2324 else
2325 return 0;
2327 case EQ_ATTR_ALT:
2328 return 0;
2330 case EQ_ATTR:
2331 /* Alternatives don't result into function call. */
2332 if (!strcmp_check (XSTR (x, 0), alternative_name))
2333 return 0;
2334 else
2335 return 5;
2336 default:
2338 int i, j;
2339 const char *fmt = GET_RTX_FORMAT (code);
2340 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2342 switch (fmt[i])
2344 case 'V':
2345 case 'E':
2346 for (j = 0; j < XVECLEN (x, i); j++)
2347 cost += attr_rtx_cost (XVECEXP (x, i, j));
2348 break;
2349 case 'e':
2350 cost += attr_rtx_cost (XEXP (x, i));
2351 break;
2355 break;
2357 return cost;
2360 /* Simplify test expression and use temporary obstack in order to avoid
2361 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2362 and avoid unnecessary copying if possible. */
2364 static rtx
2365 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2367 rtx x;
2368 struct obstack *old;
2369 if (ATTR_IND_SIMPLIFIED_P (exp))
2370 return exp;
2371 old = rtl_obstack;
2372 rtl_obstack = temp_obstack;
2373 x = simplify_test_exp (exp, insn_code, insn_index);
2374 rtl_obstack = old;
2375 if (x == exp || rtl_obstack == temp_obstack)
2376 return x;
2377 return attr_copy_rtx (x);
2380 /* Returns true if S1 is a subset of S2. */
2382 static bool
2383 attr_alt_subset_p (rtx s1, rtx s2)
2385 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2387 case (0 << 1) | 0:
2388 return !(XINT (s1, 0) &~ XINT (s2, 0));
2390 case (0 << 1) | 1:
2391 return !(XINT (s1, 0) & XINT (s2, 0));
2393 case (1 << 1) | 0:
2394 return false;
2396 case (1 << 1) | 1:
2397 return !(XINT (s2, 0) &~ XINT (s1, 0));
2399 default:
2400 gcc_unreachable ();
2404 /* Returns true if S1 is a subset of complement of S2. */
2406 static bool
2407 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2409 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2411 case (0 << 1) | 0:
2412 return !(XINT (s1, 0) & XINT (s2, 0));
2414 case (0 << 1) | 1:
2415 return !(XINT (s1, 0) & ~XINT (s2, 0));
2417 case (1 << 1) | 0:
2418 return !(XINT (s2, 0) &~ XINT (s1, 0));
2420 case (1 << 1) | 1:
2421 return false;
2423 default:
2424 gcc_unreachable ();
2428 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2430 static rtx
2431 attr_alt_intersection (rtx s1, rtx s2)
2433 rtx result = rtx_alloc (EQ_ATTR_ALT);
2435 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2437 case (0 << 1) | 0:
2438 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2439 break;
2440 case (0 << 1) | 1:
2441 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2442 break;
2443 case (1 << 1) | 0:
2444 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2445 break;
2446 case (1 << 1) | 1:
2447 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2448 break;
2449 default:
2450 gcc_unreachable ();
2452 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2454 return result;
2457 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2459 static rtx
2460 attr_alt_union (rtx s1, rtx s2)
2462 rtx result = rtx_alloc (EQ_ATTR_ALT);
2464 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2466 case (0 << 1) | 0:
2467 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2468 break;
2469 case (0 << 1) | 1:
2470 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2471 break;
2472 case (1 << 1) | 0:
2473 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2474 break;
2475 case (1 << 1) | 1:
2476 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2477 break;
2478 default:
2479 gcc_unreachable ();
2482 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2483 return result;
2486 /* Return EQ_ATTR_ALT expression representing complement of S. */
2488 static rtx
2489 attr_alt_complement (rtx s)
2491 rtx result = rtx_alloc (EQ_ATTR_ALT);
2493 XINT (result, 0) = XINT (s, 0);
2494 XINT (result, 1) = 1 - XINT (s, 1);
2496 return result;
2499 /* Tests whether a bit B belongs to the set represented by S. */
2501 static bool
2502 attr_alt_bit_p (rtx s, int b)
2504 return XINT (s, 1) ^ ((XINT (s, 0) >> b) & 1);
2507 /* Return EQ_ATTR_ALT expression representing set containing elements set
2508 in E. */
2510 static rtx
2511 mk_attr_alt (int e)
2513 rtx result = rtx_alloc (EQ_ATTR_ALT);
2515 XINT (result, 0) = e;
2516 XINT (result, 1) = 0;
2518 return result;
2521 /* Given an expression, see if it can be simplified for a particular insn
2522 code based on the values of other attributes being tested. This can
2523 eliminate nested get_attr_... calls.
2525 Note that if an endless recursion is specified in the patterns, the
2526 optimization will loop. However, it will do so in precisely the cases where
2527 an infinite recursion loop could occur during compilation. It's better that
2528 it occurs here! */
2530 static rtx
2531 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2533 rtx left, right;
2534 struct attr_desc *attr;
2535 struct attr_value *av;
2536 struct insn_ent *ie;
2537 int i;
2538 rtx newexp = exp;
2539 bool left_alt, right_alt;
2541 /* Don't re-simplify something we already simplified. */
2542 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2543 return exp;
2545 switch (GET_CODE (exp))
2547 case AND:
2548 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2549 SIMPLIFY_ALTERNATIVE (left);
2550 if (left == false_rtx)
2551 return false_rtx;
2552 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2553 SIMPLIFY_ALTERNATIVE (right);
2554 if (left == false_rtx)
2555 return false_rtx;
2557 if (GET_CODE (left) == EQ_ATTR_ALT
2558 && GET_CODE (right) == EQ_ATTR_ALT)
2560 exp = attr_alt_intersection (left, right);
2561 return simplify_test_exp (exp, insn_code, insn_index);
2564 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2565 present on both sides, apply the distributive law since this will
2566 yield simplifications. */
2567 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2568 && compute_alternative_mask (left, IOR)
2569 && compute_alternative_mask (right, IOR))
2571 if (GET_CODE (left) == IOR)
2573 rtx tem = left;
2574 left = right;
2575 right = tem;
2578 newexp = attr_rtx (IOR,
2579 attr_rtx (AND, left, XEXP (right, 0)),
2580 attr_rtx (AND, left, XEXP (right, 1)));
2582 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2585 /* Try with the term on both sides. */
2586 right = simplify_and_tree (right, &left, insn_code, insn_index);
2587 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2588 left = simplify_and_tree (left, &right, insn_code, insn_index);
2590 if (left == false_rtx || right == false_rtx)
2591 return false_rtx;
2592 else if (left == true_rtx)
2594 return right;
2596 else if (right == true_rtx)
2598 return left;
2600 /* See if all or all but one of the insn's alternatives are specified
2601 in this tree. Optimize if so. */
2603 if (GET_CODE (left) == NOT)
2604 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2605 && XSTR (XEXP (left, 0), 0) == alternative_name);
2606 else
2607 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2608 && XINT (left, 1));
2610 if (GET_CODE (right) == NOT)
2611 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2612 && XSTR (XEXP (right, 0), 0) == alternative_name);
2613 else
2614 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2615 && XINT (right, 1));
2617 if (insn_code >= 0
2618 && (GET_CODE (left) == AND
2619 || left_alt
2620 || GET_CODE (right) == AND
2621 || right_alt))
2623 i = compute_alternative_mask (exp, AND);
2624 if (i & ~insn_alternatives[insn_code])
2625 fatal ("invalid alternative specified for pattern number %d",
2626 insn_index);
2628 /* If all alternatives are excluded, this is false. */
2629 i ^= insn_alternatives[insn_code];
2630 if (i == 0)
2631 return false_rtx;
2632 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2634 /* If just one excluded, AND a comparison with that one to the
2635 front of the tree. The others will be eliminated by
2636 optimization. We do not want to do this if the insn has one
2637 alternative and we have tested none of them! */
2638 left = make_alternative_compare (i);
2639 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2640 newexp = attr_rtx (AND, left, right);
2642 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2646 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2648 newexp = attr_rtx (AND, left, right);
2649 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2651 break;
2653 case IOR:
2654 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2655 SIMPLIFY_ALTERNATIVE (left);
2656 if (left == true_rtx)
2657 return true_rtx;
2658 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2659 SIMPLIFY_ALTERNATIVE (right);
2660 if (right == true_rtx)
2661 return true_rtx;
2663 if (GET_CODE (left) == EQ_ATTR_ALT
2664 && GET_CODE (right) == EQ_ATTR_ALT)
2666 exp = attr_alt_union (left, right);
2667 return simplify_test_exp (exp, insn_code, insn_index);
2670 right = simplify_or_tree (right, &left, insn_code, insn_index);
2671 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2672 left = simplify_or_tree (left, &right, insn_code, insn_index);
2674 if (right == true_rtx || left == true_rtx)
2675 return true_rtx;
2676 else if (left == false_rtx)
2678 return right;
2680 else if (right == false_rtx)
2682 return left;
2685 /* Test for simple cases where the distributive law is useful. I.e.,
2686 convert (ior (and (x) (y))
2687 (and (x) (z)))
2688 to (and (x)
2689 (ior (y) (z)))
2692 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2693 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2695 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2697 left = XEXP (left, 0);
2698 right = newexp;
2699 newexp = attr_rtx (AND, left, right);
2700 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2703 /* See if all or all but one of the insn's alternatives are specified
2704 in this tree. Optimize if so. */
2706 else if (insn_code >= 0
2707 && (GET_CODE (left) == IOR
2708 || (GET_CODE (left) == EQ_ATTR_ALT
2709 && !XINT (left, 1))
2710 || (GET_CODE (left) == EQ_ATTR
2711 && XSTR (left, 0) == alternative_name)
2712 || GET_CODE (right) == IOR
2713 || (GET_CODE (right) == EQ_ATTR_ALT
2714 && !XINT (right, 1))
2715 || (GET_CODE (right) == EQ_ATTR
2716 && XSTR (right, 0) == alternative_name)))
2718 i = compute_alternative_mask (exp, IOR);
2719 if (i & ~insn_alternatives[insn_code])
2720 fatal ("invalid alternative specified for pattern number %d",
2721 insn_index);
2723 /* If all alternatives are included, this is true. */
2724 i ^= insn_alternatives[insn_code];
2725 if (i == 0)
2726 return true_rtx;
2727 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2729 /* If just one excluded, IOR a comparison with that one to the
2730 front of the tree. The others will be eliminated by
2731 optimization. We do not want to do this if the insn has one
2732 alternative and we have tested none of them! */
2733 left = make_alternative_compare (i);
2734 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2735 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2737 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2741 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2743 newexp = attr_rtx (IOR, left, right);
2744 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2746 break;
2748 case NOT:
2749 if (GET_CODE (XEXP (exp, 0)) == NOT)
2751 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2752 insn_code, insn_index);
2753 SIMPLIFY_ALTERNATIVE (left);
2754 return left;
2757 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2758 SIMPLIFY_ALTERNATIVE (left);
2759 if (GET_CODE (left) == NOT)
2760 return XEXP (left, 0);
2762 if (left == false_rtx)
2763 return true_rtx;
2764 if (left == true_rtx)
2765 return false_rtx;
2767 if (GET_CODE (left) == EQ_ATTR_ALT)
2769 exp = attr_alt_complement (left);
2770 return simplify_test_exp (exp, insn_code, insn_index);
2773 /* Try to apply De`Morgan's laws. */
2774 if (GET_CODE (left) == IOR)
2776 newexp = attr_rtx (AND,
2777 attr_rtx (NOT, XEXP (left, 0)),
2778 attr_rtx (NOT, XEXP (left, 1)));
2780 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2782 else if (GET_CODE (left) == AND)
2784 newexp = attr_rtx (IOR,
2785 attr_rtx (NOT, XEXP (left, 0)),
2786 attr_rtx (NOT, XEXP (left, 1)));
2788 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2790 else if (left != XEXP (exp, 0))
2792 newexp = attr_rtx (NOT, left);
2794 break;
2796 case EQ_ATTR_ALT:
2797 if (current_alternative_string)
2798 return attr_alt_bit_p (exp, atoi (current_alternative_string)) ? true_rtx : false_rtx;
2800 if (!XINT (exp, 0))
2801 return XINT (exp, 1) ? true_rtx : false_rtx;
2802 break;
2804 case EQ_ATTR:
2805 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
2806 return (XSTR (exp, 1) == current_alternative_string
2807 ? true_rtx : false_rtx);
2809 if (XSTR (exp, 0) == alternative_name)
2811 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2812 break;
2815 /* Look at the value for this insn code in the specified attribute.
2816 We normally can replace this comparison with the condition that
2817 would give this insn the values being tested for. */
2818 if (XSTR (exp, 0) != alternative_name
2819 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2820 for (av = attr->first_value; av; av = av->next)
2821 for (ie = av->first_insn; ie; ie = ie->next)
2822 if (ie->def->insn_code == insn_code)
2824 rtx x;
2825 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2826 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2827 if (attr_rtx_cost(x) < 20)
2828 return x;
2830 break;
2832 default:
2833 break;
2836 /* We have already simplified this expression. Simplifying it again
2837 won't buy anything unless we weren't given a valid insn code
2838 to process (i.e., we are canonicalizing something.). */
2839 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
2840 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2841 return copy_rtx_unchanging (newexp);
2843 return newexp;
2846 /* Optimize the attribute lists by seeing if we can determine conditional
2847 values from the known values of other attributes. This will save subroutine
2848 calls during the compilation. */
2850 static void
2851 optimize_attrs (void)
2853 struct attr_desc *attr;
2854 struct attr_value *av;
2855 struct insn_ent *ie;
2856 rtx newexp;
2857 int i;
2858 struct attr_value_list
2860 struct attr_value *av;
2861 struct insn_ent *ie;
2862 struct attr_desc *attr;
2863 struct attr_value_list *next;
2865 struct attr_value_list **insn_code_values;
2866 struct attr_value_list *ivbuf;
2867 struct attr_value_list *iv;
2869 /* For each insn code, make a list of all the insn_ent's for it,
2870 for all values for all attributes. */
2872 if (num_insn_ents == 0)
2873 return;
2875 /* Make 2 extra elements, for "code" values -2 and -1. */
2876 insn_code_values = xcalloc ((insn_code_number + 2),
2877 sizeof (struct attr_value_list *));
2879 /* Offset the table address so we can index by -2 or -1. */
2880 insn_code_values += 2;
2882 iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
2884 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2885 for (attr = attrs[i]; attr; attr = attr->next)
2886 for (av = attr->first_value; av; av = av->next)
2887 for (ie = av->first_insn; ie; ie = ie->next)
2889 iv->attr = attr;
2890 iv->av = av;
2891 iv->ie = ie;
2892 iv->next = insn_code_values[ie->def->insn_code];
2893 insn_code_values[ie->def->insn_code] = iv;
2894 iv++;
2897 /* Sanity check on num_insn_ents. */
2898 gcc_assert (iv == ivbuf + num_insn_ents);
2900 /* Process one insn code at a time. */
2901 for (i = -2; i < insn_code_number; i++)
2903 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2904 We use it to mean "already simplified for this insn". */
2905 for (iv = insn_code_values[i]; iv; iv = iv->next)
2906 clear_struct_flag (iv->av->value);
2908 for (iv = insn_code_values[i]; iv; iv = iv->next)
2910 struct obstack *old = rtl_obstack;
2912 attr = iv->attr;
2913 av = iv->av;
2914 ie = iv->ie;
2915 if (GET_CODE (av->value) != COND)
2916 continue;
2918 rtl_obstack = temp_obstack;
2919 newexp = av->value;
2920 while (GET_CODE (newexp) == COND)
2922 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2923 ie->def->insn_index);
2924 if (newexp2 == newexp)
2925 break;
2926 newexp = newexp2;
2929 rtl_obstack = old;
2930 if (newexp != av->value)
2932 newexp = attr_copy_rtx (newexp);
2933 remove_insn_ent (av, ie);
2934 av = get_attr_value (newexp, attr, ie->def->insn_code);
2935 iv->av = av;
2936 insert_insn_ent (av, ie);
2941 free (ivbuf);
2942 free (insn_code_values - 2);
2945 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2947 static void
2948 clear_struct_flag (rtx x)
2950 int i;
2951 int j;
2952 enum rtx_code code;
2953 const char *fmt;
2955 ATTR_CURR_SIMPLIFIED_P (x) = 0;
2956 if (ATTR_IND_SIMPLIFIED_P (x))
2957 return;
2959 code = GET_CODE (x);
2961 switch (code)
2963 case REG:
2964 case CONST_INT:
2965 case CONST_DOUBLE:
2966 case CONST_VECTOR:
2967 case SYMBOL_REF:
2968 case CODE_LABEL:
2969 case PC:
2970 case CC0:
2971 case EQ_ATTR:
2972 case ATTR_FLAG:
2973 return;
2975 default:
2976 break;
2979 /* Compare the elements. If any pair of corresponding elements
2980 fail to match, return 0 for the whole things. */
2982 fmt = GET_RTX_FORMAT (code);
2983 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2985 switch (fmt[i])
2987 case 'V':
2988 case 'E':
2989 for (j = 0; j < XVECLEN (x, i); j++)
2990 clear_struct_flag (XVECEXP (x, i, j));
2991 break;
2993 case 'e':
2994 clear_struct_flag (XEXP (x, i));
2995 break;
3000 /* Create table entries for DEFINE_ATTR. */
3002 static void
3003 gen_attr (rtx exp, int lineno)
3005 struct attr_desc *attr;
3006 struct attr_value *av;
3007 const char *name_ptr;
3008 char *p;
3010 /* Make a new attribute structure. Check for duplicate by looking at
3011 attr->default_val, since it is initialized by this routine. */
3012 attr = find_attr (&XSTR (exp, 0), 1);
3013 if (attr->default_val)
3015 message_with_line (lineno, "duplicate definition for attribute %s",
3016 attr->name);
3017 message_with_line (attr->lineno, "previous definition");
3018 have_error = 1;
3019 return;
3021 attr->lineno = lineno;
3023 if (*XSTR (exp, 1) == '\0')
3024 attr->is_numeric = 1;
3025 else
3027 name_ptr = XSTR (exp, 1);
3028 while ((p = next_comma_elt (&name_ptr)) != NULL)
3030 av = oballoc (sizeof (struct attr_value));
3031 av->value = attr_rtx (CONST_STRING, p);
3032 av->next = attr->first_value;
3033 attr->first_value = av;
3034 av->first_insn = NULL;
3035 av->num_insns = 0;
3036 av->has_asm_insn = 0;
3040 if (GET_CODE (XEXP (exp, 2)) == CONST)
3042 attr->is_const = 1;
3043 if (attr->is_numeric)
3045 message_with_line (lineno,
3046 "constant attributes may not take numeric values");
3047 have_error = 1;
3050 /* Get rid of the CONST node. It is allowed only at top-level. */
3051 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3054 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3056 message_with_line (lineno,
3057 "`length' attribute must take numeric values");
3058 have_error = 1;
3061 /* Set up the default value. */
3062 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3063 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3066 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3067 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3068 number of alternatives as this should be checked elsewhere. */
3070 static int
3071 count_alternatives (rtx exp)
3073 int i, j, n;
3074 const char *fmt;
3076 if (GET_CODE (exp) == MATCH_OPERAND)
3077 return n_comma_elts (XSTR (exp, 2));
3079 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3080 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3081 switch (*fmt++)
3083 case 'e':
3084 case 'u':
3085 n = count_alternatives (XEXP (exp, i));
3086 if (n)
3087 return n;
3088 break;
3090 case 'E':
3091 case 'V':
3092 if (XVEC (exp, i) != NULL)
3093 for (j = 0; j < XVECLEN (exp, i); j++)
3095 n = count_alternatives (XVECEXP (exp, i, j));
3096 if (n)
3097 return n;
3101 return 0;
3104 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3105 `alternative' attribute. */
3107 static int
3108 compares_alternatives_p (rtx exp)
3110 int i, j;
3111 const char *fmt;
3113 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3114 return 1;
3116 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3117 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3118 switch (*fmt++)
3120 case 'e':
3121 case 'u':
3122 if (compares_alternatives_p (XEXP (exp, i)))
3123 return 1;
3124 break;
3126 case 'E':
3127 for (j = 0; j < XVECLEN (exp, i); j++)
3128 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3129 return 1;
3130 break;
3133 return 0;
3136 /* Returns nonzero is INNER is contained in EXP. */
3138 static int
3139 contained_in_p (rtx inner, rtx exp)
3141 int i, j;
3142 const char *fmt;
3144 if (rtx_equal_p (inner, exp))
3145 return 1;
3147 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3148 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3149 switch (*fmt++)
3151 case 'e':
3152 case 'u':
3153 if (contained_in_p (inner, XEXP (exp, i)))
3154 return 1;
3155 break;
3157 case 'E':
3158 for (j = 0; j < XVECLEN (exp, i); j++)
3159 if (contained_in_p (inner, XVECEXP (exp, i, j)))
3160 return 1;
3161 break;
3164 return 0;
3167 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3169 static void
3170 gen_insn (rtx exp, int lineno)
3172 struct insn_def *id;
3174 id = oballoc (sizeof (struct insn_def));
3175 id->next = defs;
3176 defs = id;
3177 id->def = exp;
3178 id->lineno = lineno;
3180 switch (GET_CODE (exp))
3182 case DEFINE_INSN:
3183 id->insn_code = insn_code_number;
3184 id->insn_index = insn_index_number;
3185 id->num_alternatives = count_alternatives (exp);
3186 if (id->num_alternatives == 0)
3187 id->num_alternatives = 1;
3188 id->vec_idx = 4;
3189 break;
3191 case DEFINE_PEEPHOLE:
3192 id->insn_code = insn_code_number;
3193 id->insn_index = insn_index_number;
3194 id->num_alternatives = count_alternatives (exp);
3195 if (id->num_alternatives == 0)
3196 id->num_alternatives = 1;
3197 id->vec_idx = 3;
3198 break;
3200 case DEFINE_ASM_ATTRIBUTES:
3201 id->insn_code = -1;
3202 id->insn_index = -1;
3203 id->num_alternatives = 1;
3204 id->vec_idx = 0;
3205 got_define_asm_attributes = 1;
3206 break;
3208 default:
3209 gcc_unreachable ();
3213 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3214 true or annul false is specified, and make a `struct delay_desc'. */
3216 static void
3217 gen_delay (rtx def, int lineno)
3219 struct delay_desc *delay;
3220 int i;
3222 if (XVECLEN (def, 1) % 3 != 0)
3224 message_with_line (lineno,
3225 "number of elements in DEFINE_DELAY must be multiple of three");
3226 have_error = 1;
3227 return;
3230 for (i = 0; i < XVECLEN (def, 1); i += 3)
3232 if (XVECEXP (def, 1, i + 1))
3233 have_annul_true = 1;
3234 if (XVECEXP (def, 1, i + 2))
3235 have_annul_false = 1;
3238 delay = oballoc (sizeof (struct delay_desc));
3239 delay->def = def;
3240 delay->num = ++num_delays;
3241 delay->next = delays;
3242 delay->lineno = lineno;
3243 delays = delay;
3246 /* Given a piece of RTX, print a C expression to test its truth value.
3247 We use AND and IOR both for logical and bit-wise operations, so
3248 interpret them as logical unless they are inside a comparison expression.
3249 The first bit of FLAGS will be nonzero in that case.
3251 Set the second bit of FLAGS to make references to attribute values use
3252 a cached local variable instead of calling a function. */
3254 static void
3255 write_test_expr (rtx exp, int flags)
3257 int comparison_operator = 0;
3258 RTX_CODE code;
3259 struct attr_desc *attr;
3261 /* In order not to worry about operator precedence, surround our part of
3262 the expression with parentheses. */
3264 printf ("(");
3265 code = GET_CODE (exp);
3266 switch (code)
3268 /* Binary operators. */
3269 case GEU: case GTU:
3270 case LEU: case LTU:
3271 printf ("(unsigned) ");
3272 /* Fall through. */
3274 case EQ: case NE:
3275 case GE: case GT:
3276 case LE: case LT:
3277 comparison_operator = 1;
3279 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3280 case AND: case IOR: case XOR:
3281 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3282 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
3283 switch (code)
3285 case EQ:
3286 printf (" == ");
3287 break;
3288 case NE:
3289 printf (" != ");
3290 break;
3291 case GE:
3292 printf (" >= ");
3293 break;
3294 case GT:
3295 printf (" > ");
3296 break;
3297 case GEU:
3298 printf (" >= (unsigned) ");
3299 break;
3300 case GTU:
3301 printf (" > (unsigned) ");
3302 break;
3303 case LE:
3304 printf (" <= ");
3305 break;
3306 case LT:
3307 printf (" < ");
3308 break;
3309 case LEU:
3310 printf (" <= (unsigned) ");
3311 break;
3312 case LTU:
3313 printf (" < (unsigned) ");
3314 break;
3315 case PLUS:
3316 printf (" + ");
3317 break;
3318 case MINUS:
3319 printf (" - ");
3320 break;
3321 case MULT:
3322 printf (" * ");
3323 break;
3324 case DIV:
3325 printf (" / ");
3326 break;
3327 case MOD:
3328 printf (" %% ");
3329 break;
3330 case AND:
3331 if (flags & 1)
3332 printf (" & ");
3333 else
3334 printf (" && ");
3335 break;
3336 case IOR:
3337 if (flags & 1)
3338 printf (" | ");
3339 else
3340 printf (" || ");
3341 break;
3342 case XOR:
3343 printf (" ^ ");
3344 break;
3345 case ASHIFT:
3346 printf (" << ");
3347 break;
3348 case LSHIFTRT:
3349 case ASHIFTRT:
3350 printf (" >> ");
3351 break;
3352 default:
3353 gcc_unreachable ();
3356 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
3357 break;
3359 case NOT:
3360 /* Special-case (not (eq_attrq "alternative" "x")) */
3361 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3362 && XSTR (XEXP (exp, 0), 0) == alternative_name)
3364 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3365 break;
3368 /* Otherwise, fall through to normal unary operator. */
3370 /* Unary operators. */
3371 case ABS: case NEG:
3372 switch (code)
3374 case NOT:
3375 if (flags & 1)
3376 printf ("~ ");
3377 else
3378 printf ("! ");
3379 break;
3380 case ABS:
3381 printf ("abs ");
3382 break;
3383 case NEG:
3384 printf ("-");
3385 break;
3386 default:
3387 gcc_unreachable ();
3390 write_test_expr (XEXP (exp, 0), flags);
3391 break;
3393 case EQ_ATTR_ALT:
3395 int set = XINT (exp, 0), bit = 0;
3397 if (flags & 1)
3398 fatal ("EQ_ATTR_ALT not valid inside comparison");
3400 if (!set)
3401 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3403 if (!(set & (set - 1)))
3405 if (!(set & 0xffff))
3407 bit += 16;
3408 set >>= 16;
3410 if (!(set & 0xff))
3412 bit += 8;
3413 set >>= 8;
3415 if (!(set & 0xf))
3417 bit += 4;
3418 set >>= 4;
3420 if (!(set & 0x3))
3422 bit += 2;
3423 set >>= 2;
3425 if (!(set & 1))
3426 bit++;
3428 printf ("which_alternative %s= %d",
3429 XINT (exp, 1) ? "!" : "=", bit);
3431 else
3433 printf ("%s((1 << which_alternative) & 0x%x)",
3434 XINT (exp, 1) ? "!" : "", set);
3437 break;
3439 /* Comparison test of an attribute with a value. Most of these will
3440 have been removed by optimization. Handle "alternative"
3441 specially and give error if EQ_ATTR present inside a comparison. */
3442 case EQ_ATTR:
3443 if (flags & 1)
3444 fatal ("EQ_ATTR not valid inside comparison");
3446 if (XSTR (exp, 0) == alternative_name)
3448 printf ("which_alternative == %s", XSTR (exp, 1));
3449 break;
3452 attr = find_attr (&XSTR (exp, 0), 0);
3453 gcc_assert (attr);
3455 /* Now is the time to expand the value of a constant attribute. */
3456 if (attr->is_const)
3458 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
3459 -2, -2),
3460 flags);
3462 else
3464 if (flags & 2)
3465 printf ("attr_%s", attr->name);
3466 else
3467 printf ("get_attr_%s (insn)", attr->name);
3468 printf (" == ");
3469 write_attr_valueq (attr, XSTR (exp, 1));
3471 break;
3473 /* Comparison test of flags for define_delays. */
3474 case ATTR_FLAG:
3475 if (flags & 1)
3476 fatal ("ATTR_FLAG not valid inside comparison");
3477 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3478 break;
3480 /* See if an operand matches a predicate. */
3481 case MATCH_OPERAND:
3482 /* If only a mode is given, just ensure the mode matches the operand.
3483 If neither a mode nor predicate is given, error. */
3484 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3486 if (GET_MODE (exp) == VOIDmode)
3487 fatal ("null MATCH_OPERAND specified as test");
3488 else
3489 printf ("GET_MODE (operands[%d]) == %smode",
3490 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3492 else
3493 printf ("%s (operands[%d], %smode)",
3494 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3495 break;
3497 /* Constant integer. */
3498 case CONST_INT:
3499 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3500 break;
3502 /* A random C expression. */
3503 case SYMBOL_REF:
3504 print_c_condition (XSTR (exp, 0));
3505 break;
3507 /* The address of the branch target. */
3508 case MATCH_DUP:
3509 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3510 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3511 break;
3513 case PC:
3514 /* The address of the current insn. We implement this actually as the
3515 address of the current insn for backward branches, but the last
3516 address of the next insn for forward branches, and both with
3517 adjustments that account for the worst-case possible stretching of
3518 intervening alignments between this insn and its destination. */
3519 printf ("insn_current_reference_address (insn)");
3520 break;
3522 case CONST_STRING:
3523 printf ("%s", XSTR (exp, 0));
3524 break;
3526 case IF_THEN_ELSE:
3527 write_test_expr (XEXP (exp, 0), flags & 2);
3528 printf (" ? ");
3529 write_test_expr (XEXP (exp, 1), flags | 1);
3530 printf (" : ");
3531 write_test_expr (XEXP (exp, 2), flags | 1);
3532 break;
3534 default:
3535 fatal ("bad RTX code `%s' in attribute calculation\n",
3536 GET_RTX_NAME (code));
3539 printf (")");
3542 /* Given an attribute value, return the maximum CONST_STRING argument
3543 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3545 static int
3546 max_attr_value (rtx exp, int *unknownp)
3548 int current_max;
3549 int i, n;
3551 switch (GET_CODE (exp))
3553 case CONST_STRING:
3554 current_max = atoi (XSTR (exp, 0));
3555 break;
3557 case COND:
3558 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3559 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3561 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3562 if (n > current_max)
3563 current_max = n;
3565 break;
3567 case IF_THEN_ELSE:
3568 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3569 n = max_attr_value (XEXP (exp, 2), unknownp);
3570 if (n > current_max)
3571 current_max = n;
3572 break;
3574 default:
3575 *unknownp = 1;
3576 current_max = INT_MAX;
3577 break;
3580 return current_max;
3583 /* Given an attribute value, return the result of ORing together all
3584 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3585 if the numeric value is not known. */
3587 static int
3588 or_attr_value (rtx exp, int *unknownp)
3590 int current_or;
3591 int i;
3593 switch (GET_CODE (exp))
3595 case CONST_STRING:
3596 current_or = atoi (XSTR (exp, 0));
3597 break;
3599 case COND:
3600 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3601 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3602 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3603 break;
3605 case IF_THEN_ELSE:
3606 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3607 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3608 break;
3610 default:
3611 *unknownp = 1;
3612 current_or = -1;
3613 break;
3616 return current_or;
3619 /* Scan an attribute value, possibly a conditional, and record what actions
3620 will be required to do any conditional tests in it.
3622 Specifically, set
3623 `must_extract' if we need to extract the insn operands
3624 `must_constrain' if we must compute `which_alternative'
3625 `address_used' if an address expression was used
3626 `length_used' if an (eq_attr "length" ...) was used
3629 static void
3630 walk_attr_value (rtx exp)
3632 int i, j;
3633 const char *fmt;
3634 RTX_CODE code;
3636 if (exp == NULL)
3637 return;
3639 code = GET_CODE (exp);
3640 switch (code)
3642 case SYMBOL_REF:
3643 if (! ATTR_IND_SIMPLIFIED_P (exp))
3644 /* Since this is an arbitrary expression, it can look at anything.
3645 However, constant expressions do not depend on any particular
3646 insn. */
3647 must_extract = must_constrain = 1;
3648 return;
3650 case MATCH_OPERAND:
3651 must_extract = 1;
3652 return;
3654 case EQ_ATTR_ALT:
3655 must_extract = must_constrain = 1;
3656 break;
3658 case EQ_ATTR:
3659 if (XSTR (exp, 0) == alternative_name)
3660 must_extract = must_constrain = 1;
3661 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3662 length_used = 1;
3663 return;
3665 case MATCH_DUP:
3666 must_extract = 1;
3667 address_used = 1;
3668 return;
3670 case PC:
3671 address_used = 1;
3672 return;
3674 case ATTR_FLAG:
3675 return;
3677 default:
3678 break;
3681 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3682 switch (*fmt++)
3684 case 'e':
3685 case 'u':
3686 walk_attr_value (XEXP (exp, i));
3687 break;
3689 case 'E':
3690 if (XVEC (exp, i) != NULL)
3691 for (j = 0; j < XVECLEN (exp, i); j++)
3692 walk_attr_value (XVECEXP (exp, i, j));
3693 break;
3697 /* Write out a function to obtain the attribute for a given INSN. */
3699 static void
3700 write_attr_get (struct attr_desc *attr)
3702 struct attr_value *av, *common_av;
3704 /* Find the most used attribute value. Handle that as the `default' of the
3705 switch we will generate. */
3706 common_av = find_most_used (attr);
3708 /* Write out start of function, then all values with explicit `case' lines,
3709 then a `default', then the value with the most uses. */
3710 if (attr->static_p)
3711 printf ("static ");
3712 if (!attr->is_numeric)
3713 printf ("enum attr_%s\n", attr->name);
3714 else
3715 printf ("int\n");
3717 /* If the attribute name starts with a star, the remainder is the name of
3718 the subroutine to use, instead of `get_attr_...'. */
3719 if (attr->name[0] == '*')
3720 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3721 else if (attr->is_const == 0)
3722 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3723 else
3725 printf ("get_attr_%s (void)\n", attr->name);
3726 printf ("{\n");
3728 for (av = attr->first_value; av; av = av->next)
3729 if (av->num_insns != 0)
3730 write_attr_set (attr, 2, av->value, "return", ";",
3731 true_rtx, av->first_insn->def->insn_code,
3732 av->first_insn->def->insn_index);
3734 printf ("}\n\n");
3735 return;
3738 printf ("{\n");
3739 printf (" switch (recog_memoized (insn))\n");
3740 printf (" {\n");
3742 for (av = attr->first_value; av; av = av->next)
3743 if (av != common_av)
3744 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3746 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3747 printf (" }\n}\n\n");
3750 /* Given an AND tree of known true terms (because we are inside an `if' with
3751 that as the condition or are in an `else' clause) and an expression,
3752 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3753 the bulk of the work. */
3755 static rtx
3756 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
3758 rtx term;
3760 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3762 if (GET_CODE (known_true) == AND)
3764 exp = eliminate_known_true (XEXP (known_true, 0), exp,
3765 insn_code, insn_index);
3766 exp = eliminate_known_true (XEXP (known_true, 1), exp,
3767 insn_code, insn_index);
3769 else
3771 term = known_true;
3772 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3775 return exp;
3778 /* Write out a series of tests and assignment statements to perform tests and
3779 sets of an attribute value. We are passed an indentation amount and prefix
3780 and suffix strings to write around each attribute value (e.g., "return"
3781 and ";"). */
3783 static void
3784 write_attr_set (struct attr_desc *attr, int indent, rtx value,
3785 const char *prefix, const char *suffix, rtx known_true,
3786 int insn_code, int insn_index)
3788 if (GET_CODE (value) == COND)
3790 /* Assume the default value will be the default of the COND unless we
3791 find an always true expression. */
3792 rtx default_val = XEXP (value, 1);
3793 rtx our_known_true = known_true;
3794 rtx newexp;
3795 int first_if = 1;
3796 int i;
3798 for (i = 0; i < XVECLEN (value, 0); i += 2)
3800 rtx testexp;
3801 rtx inner_true;
3803 testexp = eliminate_known_true (our_known_true,
3804 XVECEXP (value, 0, i),
3805 insn_code, insn_index);
3806 newexp = attr_rtx (NOT, testexp);
3807 newexp = insert_right_side (AND, our_known_true, newexp,
3808 insn_code, insn_index);
3810 /* If the test expression is always true or if the next `known_true'
3811 expression is always false, this is the last case, so break
3812 out and let this value be the `else' case. */
3813 if (testexp == true_rtx || newexp == false_rtx)
3815 default_val = XVECEXP (value, 0, i + 1);
3816 break;
3819 /* Compute the expression to pass to our recursive call as being
3820 known true. */
3821 inner_true = insert_right_side (AND, our_known_true,
3822 testexp, insn_code, insn_index);
3824 /* If this is always false, skip it. */
3825 if (inner_true == false_rtx)
3826 continue;
3828 write_indent (indent);
3829 printf ("%sif ", first_if ? "" : "else ");
3830 first_if = 0;
3831 write_test_expr (testexp, 0);
3832 printf ("\n");
3833 write_indent (indent + 2);
3834 printf ("{\n");
3836 write_attr_set (attr, indent + 4,
3837 XVECEXP (value, 0, i + 1), prefix, suffix,
3838 inner_true, insn_code, insn_index);
3839 write_indent (indent + 2);
3840 printf ("}\n");
3841 our_known_true = newexp;
3844 if (! first_if)
3846 write_indent (indent);
3847 printf ("else\n");
3848 write_indent (indent + 2);
3849 printf ("{\n");
3852 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3853 prefix, suffix, our_known_true, insn_code, insn_index);
3855 if (! first_if)
3857 write_indent (indent + 2);
3858 printf ("}\n");
3861 else
3863 write_indent (indent);
3864 printf ("%s ", prefix);
3865 write_attr_value (attr, value);
3866 printf ("%s\n", suffix);
3870 /* Write a series of case statements for every instruction in list IE.
3871 INDENT is the amount of indentation to write before each case. */
3873 static void
3874 write_insn_cases (struct insn_ent *ie, int indent)
3876 for (; ie != 0; ie = ie->next)
3877 if (ie->def->insn_code != -1)
3879 write_indent (indent);
3880 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
3881 printf ("case %d: /* define_peephole, line %d */\n",
3882 ie->def->insn_code, ie->def->lineno);
3883 else
3884 printf ("case %d: /* %s */\n",
3885 ie->def->insn_code, XSTR (ie->def->def, 0));
3889 /* Write out the computation for one attribute value. */
3891 static void
3892 write_attr_case (struct attr_desc *attr, struct attr_value *av,
3893 int write_case_lines, const char *prefix, const char *suffix,
3894 int indent, rtx known_true)
3896 if (av->num_insns == 0)
3897 return;
3899 if (av->has_asm_insn)
3901 write_indent (indent);
3902 printf ("case -1:\n");
3903 write_indent (indent + 2);
3904 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3905 write_indent (indent + 2);
3906 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3907 write_indent (indent + 2);
3908 printf (" fatal_insn_not_found (insn);\n");
3911 if (write_case_lines)
3912 write_insn_cases (av->first_insn, indent);
3913 else
3915 write_indent (indent);
3916 printf ("default:\n");
3919 /* See what we have to do to output this value. */
3920 must_extract = must_constrain = address_used = 0;
3921 walk_attr_value (av->value);
3923 if (must_constrain)
3925 write_indent (indent + 2);
3926 printf ("extract_constrain_insn_cached (insn);\n");
3928 else if (must_extract)
3930 write_indent (indent + 2);
3931 printf ("extract_insn_cached (insn);\n");
3934 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3935 known_true, av->first_insn->def->insn_code,
3936 av->first_insn->def->insn_index);
3938 if (strncmp (prefix, "return", 6))
3940 write_indent (indent + 2);
3941 printf ("break;\n");
3943 printf ("\n");
3946 /* Search for uses of non-const attributes and write code to cache them. */
3948 static int
3949 write_expr_attr_cache (rtx p, struct attr_desc *attr)
3951 const char *fmt;
3952 int i, ie, j, je;
3954 if (GET_CODE (p) == EQ_ATTR)
3956 if (XSTR (p, 0) != attr->name)
3957 return 0;
3959 if (!attr->is_numeric)
3960 printf (" enum attr_%s ", attr->name);
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 print_c_condition (XSTR (value, 0));
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 gcc_unreachable ();
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 (" gcc_assert (slot < %d);\n", max_slots);
4130 printf ("\n");
4131 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4132 converts a compound instruction into a loop. */
4133 printf (" if (!INSN_P (candidate_insn))\n");
4134 printf (" return 0;\n");
4135 printf ("\n");
4137 /* If more than one delay type, find out which type the delay insn is. */
4139 if (num_delays > 1)
4141 attr = find_attr (&delay_type_str, 0);
4142 gcc_assert (attr);
4143 common_av = find_most_used (attr);
4145 printf (" insn = delay_insn;\n");
4146 printf (" switch (recog_memoized (insn))\n");
4147 printf (" {\n");
4149 sprintf (str, " * %d;\n break;", max_slots);
4150 for (av = attr->first_value; av; av = av->next)
4151 if (av != common_av)
4152 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4154 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4155 printf (" }\n\n");
4157 /* Ensure matched. Otherwise, shouldn't have been called. */
4158 printf (" gcc_assert (slot >= %d);\n\n", max_slots);
4161 /* If just one type of delay slot, write simple switch. */
4162 if (num_delays == 1 && max_slots == 1)
4164 printf (" insn = candidate_insn;\n");
4165 printf (" switch (recog_memoized (insn))\n");
4166 printf (" {\n");
4168 attr = find_attr (&delay_1_0_str, 0);
4169 gcc_assert (attr);
4170 common_av = find_most_used (attr);
4172 for (av = attr->first_value; av; av = av->next)
4173 if (av != common_av)
4174 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4176 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4177 printf (" }\n");
4180 else
4182 /* Write a nested CASE. The first indicates which condition we need to
4183 test, and the inner CASE tests the condition. */
4184 printf (" insn = candidate_insn;\n");
4185 printf (" switch (slot)\n");
4186 printf (" {\n");
4188 for (delay = delays; delay; delay = delay->next)
4189 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4191 printf (" case %d:\n",
4192 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4193 printf (" switch (recog_memoized (insn))\n");
4194 printf ("\t{\n");
4196 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4197 pstr = str;
4198 attr = find_attr (&pstr, 0);
4199 gcc_assert (attr);
4200 common_av = find_most_used (attr);
4202 for (av = attr->first_value; av; av = av->next)
4203 if (av != common_av)
4204 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4206 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4207 printf (" }\n");
4210 printf (" default:\n");
4211 printf (" gcc_unreachable ();\n");
4212 printf (" }\n");
4215 printf ("}\n\n");
4218 /* This page contains miscellaneous utility routines. */
4220 /* Given a pointer to a (char *), return a malloc'ed string containing the
4221 next comma-separated element. Advance the pointer to after the string
4222 scanned, or the end-of-string. Return NULL if at end of string. */
4224 static char *
4225 next_comma_elt (const char **pstr)
4227 const char *start;
4229 start = scan_comma_elt (pstr);
4231 if (start == NULL)
4232 return NULL;
4234 return attr_string (start, *pstr - start);
4237 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4238 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4239 replaced by a pointer to a canonical copy of the string. */
4241 static struct attr_desc *
4242 find_attr (const char **name_p, int create)
4244 struct attr_desc *attr;
4245 int index;
4246 const char *name = *name_p;
4248 /* Before we resort to using `strcmp', see if the string address matches
4249 anywhere. In most cases, it should have been canonicalized to do so. */
4250 if (name == alternative_name)
4251 return NULL;
4253 index = name[0] & (MAX_ATTRS_INDEX - 1);
4254 for (attr = attrs[index]; attr; attr = attr->next)
4255 if (name == attr->name)
4256 return attr;
4258 /* Otherwise, do it the slow way. */
4259 for (attr = attrs[index]; attr; attr = attr->next)
4260 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4262 *name_p = attr->name;
4263 return attr;
4266 if (! create)
4267 return NULL;
4269 attr = oballoc (sizeof (struct attr_desc));
4270 attr->name = DEF_ATTR_STRING (name);
4271 attr->first_value = attr->default_val = NULL;
4272 attr->is_numeric = attr->is_const = attr->is_special = 0;
4273 attr->static_p = 0;
4274 attr->next = attrs[index];
4275 attrs[index] = attr;
4277 *name_p = attr->name;
4279 return attr;
4282 /* Create internal attribute with the given default value. */
4284 void
4285 make_internal_attr (const char *name, rtx value, int special)
4287 struct attr_desc *attr;
4289 attr = find_attr (&name, 1);
4290 gcc_assert (!attr->default_val);
4292 attr->is_numeric = 1;
4293 attr->is_const = 0;
4294 attr->is_special = (special & ATTR_SPECIAL) != 0;
4295 attr->static_p = (special & ATTR_STATIC) != 0;
4296 attr->default_val = get_attr_value (value, attr, -2);
4299 /* Find the most used value of an attribute. */
4301 static struct attr_value *
4302 find_most_used (struct attr_desc *attr)
4304 struct attr_value *av;
4305 struct attr_value *most_used;
4306 int nuses;
4308 most_used = NULL;
4309 nuses = -1;
4311 for (av = attr->first_value; av; av = av->next)
4312 if (av->num_insns > nuses)
4313 nuses = av->num_insns, most_used = av;
4315 return most_used;
4318 /* Return (attr_value "n") */
4321 make_numeric_value (int n)
4323 static rtx int_values[20];
4324 rtx exp;
4325 char *p;
4327 gcc_assert (n >= 0);
4329 if (n < 20 && int_values[n])
4330 return int_values[n];
4332 p = attr_printf (MAX_DIGITS, "%d", n);
4333 exp = attr_rtx (CONST_STRING, p);
4335 if (n < 20)
4336 int_values[n] = exp;
4338 return exp;
4341 static rtx
4342 copy_rtx_unchanging (rtx orig)
4344 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4345 return orig;
4347 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4348 return orig;
4351 /* Determine if an insn has a constant number of delay slots, i.e., the
4352 number of delay slots is not a function of the length of the insn. */
4354 static void
4355 write_const_num_delay_slots (void)
4357 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4358 struct attr_value *av;
4360 if (attr)
4362 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4363 printf ("{\n");
4364 printf (" switch (recog_memoized (insn))\n");
4365 printf (" {\n");
4367 for (av = attr->first_value; av; av = av->next)
4369 length_used = 0;
4370 walk_attr_value (av->value);
4371 if (length_used)
4372 write_insn_cases (av->first_insn, 4);
4375 printf (" default:\n");
4376 printf (" return 1;\n");
4377 printf (" }\n}\n\n");
4382 main (int argc, char **argv)
4384 rtx desc;
4385 struct attr_desc *attr;
4386 struct insn_def *id;
4387 rtx tem;
4388 int i;
4390 progname = "genattrtab";
4392 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
4393 return (FATAL_EXIT_CODE);
4395 obstack_init (hash_obstack);
4396 obstack_init (temp_obstack);
4398 /* Set up true and false rtx's */
4399 true_rtx = rtx_alloc (CONST_INT);
4400 XWINT (true_rtx, 0) = 1;
4401 false_rtx = rtx_alloc (CONST_INT);
4402 XWINT (false_rtx, 0) = 0;
4403 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4404 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
4406 alternative_name = DEF_ATTR_STRING ("alternative");
4407 length_str = DEF_ATTR_STRING ("length");
4408 delay_type_str = DEF_ATTR_STRING ("*delay_type");
4409 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4410 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
4412 printf ("/* Generated automatically by the program `genattrtab'\n\
4413 from the machine description file `md'. */\n\n");
4415 /* Read the machine description. */
4417 initiate_automaton_gen (argc, argv);
4418 while (1)
4420 int lineno;
4422 desc = read_md_rtx (&lineno, &insn_code_number);
4423 if (desc == NULL)
4424 break;
4426 switch (GET_CODE (desc))
4428 case DEFINE_INSN:
4429 case DEFINE_PEEPHOLE:
4430 case DEFINE_ASM_ATTRIBUTES:
4431 gen_insn (desc, lineno);
4432 break;
4434 case DEFINE_ATTR:
4435 gen_attr (desc, lineno);
4436 break;
4438 case DEFINE_DELAY:
4439 gen_delay (desc, lineno);
4440 break;
4442 case DEFINE_CPU_UNIT:
4443 gen_cpu_unit (desc);
4444 break;
4446 case DEFINE_QUERY_CPU_UNIT:
4447 gen_query_cpu_unit (desc);
4448 break;
4450 case DEFINE_BYPASS:
4451 gen_bypass (desc);
4452 break;
4454 case EXCLUSION_SET:
4455 gen_excl_set (desc);
4456 break;
4458 case PRESENCE_SET:
4459 gen_presence_set (desc);
4460 break;
4462 case FINAL_PRESENCE_SET:
4463 gen_final_presence_set (desc);
4464 break;
4466 case ABSENCE_SET:
4467 gen_absence_set (desc);
4468 break;
4470 case FINAL_ABSENCE_SET:
4471 gen_final_absence_set (desc);
4472 break;
4474 case DEFINE_AUTOMATON:
4475 gen_automaton (desc);
4476 break;
4478 case AUTOMATA_OPTION:
4479 gen_automata_option (desc);
4480 break;
4482 case DEFINE_RESERVATION:
4483 gen_reserv (desc);
4484 break;
4486 case DEFINE_INSN_RESERVATION:
4487 gen_insn_reserv (desc);
4488 break;
4490 default:
4491 break;
4493 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
4494 insn_index_number++;
4497 if (have_error)
4498 return FATAL_EXIT_CODE;
4500 insn_code_number++;
4502 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4503 if (! got_define_asm_attributes)
4505 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4506 XVEC (tem, 0) = rtvec_alloc (0);
4507 gen_insn (tem, 0);
4510 /* Expand DEFINE_DELAY information into new attribute. */
4511 if (num_delays)
4512 expand_delays ();
4514 /* Build DFA, output some functions and expand DFA information
4515 to new attributes. */
4516 if (num_dfa_decls)
4517 expand_automata ();
4519 printf ("#include \"config.h\"\n");
4520 printf ("#include \"system.h\"\n");
4521 printf ("#include \"coretypes.h\"\n");
4522 printf ("#include \"tm.h\"\n");
4523 printf ("#include \"rtl.h\"\n");
4524 printf ("#include \"tm_p.h\"\n");
4525 printf ("#include \"insn-config.h\"\n");
4526 printf ("#include \"recog.h\"\n");
4527 printf ("#include \"regs.h\"\n");
4528 printf ("#include \"real.h\"\n");
4529 printf ("#include \"output.h\"\n");
4530 printf ("#include \"insn-attr.h\"\n");
4531 printf ("#include \"toplev.h\"\n");
4532 printf ("#include \"flags.h\"\n");
4533 printf ("#include \"function.h\"\n");
4534 printf ("\n");
4535 printf ("#define operands recog_data.operand\n\n");
4537 /* Make `insn_alternatives'. */
4538 insn_alternatives = oballoc (insn_code_number * sizeof (int));
4539 for (id = defs; id; id = id->next)
4540 if (id->insn_code >= 0)
4541 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4543 /* Make `insn_n_alternatives'. */
4544 insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
4545 for (id = defs; id; id = id->next)
4546 if (id->insn_code >= 0)
4547 insn_n_alternatives[id->insn_code] = id->num_alternatives;
4549 /* Prepare to write out attribute subroutines by checking everything stored
4550 away and building the attribute cases. */
4552 check_defs ();
4554 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4555 for (attr = attrs[i]; attr; attr = attr->next)
4556 attr->default_val->value
4557 = check_attr_value (attr->default_val->value, attr);
4559 if (have_error)
4560 return FATAL_EXIT_CODE;
4562 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4563 for (attr = attrs[i]; attr; attr = attr->next)
4564 fill_attr (attr);
4566 /* Construct extra attributes for `length'. */
4567 make_length_attrs ();
4569 /* Perform any possible optimizations to speed up compilation. */
4570 optimize_attrs ();
4572 /* Now write out all the `gen_attr_...' routines. Do these before the
4573 special routines so that they get defined before they are used. */
4575 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4576 for (attr = attrs[i]; attr; attr = attr->next)
4578 if (! attr->is_special && ! attr->is_const)
4580 int insn_alts_p;
4582 insn_alts_p
4583 = (attr->name [0] == '*'
4584 && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
4585 if (insn_alts_p)
4586 printf ("\n#if AUTOMATON_ALTS\n");
4587 write_attr_get (attr);
4588 if (insn_alts_p)
4589 printf ("#endif\n\n");
4593 /* Write out delay eligibility information, if DEFINE_DELAY present.
4594 (The function to compute the number of delay slots will be written
4595 below.) */
4596 if (num_delays)
4598 write_eligible_delay ("delay");
4599 if (have_annul_true)
4600 write_eligible_delay ("annul_true");
4601 if (have_annul_false)
4602 write_eligible_delay ("annul_false");
4605 /* Output code for pipeline hazards recognition based on DFA
4606 (deterministic finite-state automata). */
4607 if (num_dfa_decls)
4608 write_automata ();
4610 /* Write out constant delay slot info. */
4611 write_const_num_delay_slots ();
4613 write_length_unit_log ();
4615 fflush (stdout);
4616 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
4619 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
4620 const char *
4621 get_insn_name (int code ATTRIBUTE_UNUSED)
4623 return NULL;