os_dep.c: Add FreeBSD/PowerPC bits.
[official-gcc.git] / gcc / genattrtab.c
blob793841befcb1be0ff5bea8d7326857c0866b107a
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). */
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
99 #if 0
100 #define strcmp_check(S1, S2) ((S1) == (S2) \
101 ? 0 \
102 : (gcc_assert (strcmp ((S1), (S2))), 1))
103 #else
104 #define strcmp_check(S1, S2) ((S1) != (S2))
105 #endif
107 #include "bconfig.h"
108 #include "system.h"
109 #include "coretypes.h"
110 #include "tm.h"
111 #include "rtl.h"
112 #include "ggc.h"
113 #include "gensupport.h"
115 #ifdef HAVE_SYS_RESOURCE_H
116 # include <sys/resource.h>
117 #endif
119 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
120 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
121 #include "obstack.h"
122 #include "errors.h"
124 #include "genattrtab.h"
126 static struct obstack obstack1, obstack2;
127 struct obstack *hash_obstack = &obstack1;
128 struct obstack *temp_obstack = &obstack2;
130 /* enough space to reserve for printing out ints */
131 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
133 /* Define structures used to record attributes and values. */
135 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
136 encountered, we store all the relevant information into a
137 `struct insn_def'. This is done to allow attribute definitions to occur
138 anywhere in the file. */
140 struct insn_def
142 struct insn_def *next; /* Next insn in chain. */
143 rtx def; /* The DEFINE_... */
144 int insn_code; /* Instruction number. */
145 int insn_index; /* Expression numer in file, for errors. */
146 int lineno; /* Line number. */
147 int num_alternatives; /* Number of alternatives. */
148 int vec_idx; /* Index of attribute vector in `def'. */
151 /* Once everything has been read in, we store in each attribute value a list
152 of insn codes that have that value. Here is the structure used for the
153 list. */
155 struct insn_ent
157 struct insn_ent *next; /* Next in chain. */
158 struct insn_def *def; /* Instruction definition. */
161 /* Each value of an attribute (either constant or computed) is assigned a
162 structure which is used as the listhead of the insns that have that
163 value. */
165 struct attr_value
167 rtx value; /* Value of attribute. */
168 struct attr_value *next; /* Next attribute value in chain. */
169 struct insn_ent *first_insn; /* First insn with this value. */
170 int num_insns; /* Number of insns with this value. */
171 int has_asm_insn; /* True if this value used for `asm' insns */
174 /* Structure for each attribute. */
176 struct attr_desc
178 char *name; /* Name of attribute. */
179 struct attr_desc *next; /* Next attribute. */
180 struct attr_value *first_value; /* First value of this attribute. */
181 struct attr_value *default_val; /* Default value for this attribute. */
182 int lineno : 24; /* Line number. */
183 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
184 unsigned is_const : 1; /* Attribute value constant for each run. */
185 unsigned is_special : 1; /* Don't call `write_attr_set'. */
186 unsigned static_p : 1; /* Make the output function static. */
189 /* Structure for each DEFINE_DELAY. */
191 struct delay_desc
193 rtx def; /* DEFINE_DELAY expression. */
194 struct delay_desc *next; /* Next DEFINE_DELAY. */
195 int num; /* Number of DEFINE_DELAY, starting at 1. */
196 int lineno; /* Line number. */
199 /* Listheads of above structures. */
201 /* This one is indexed by the first character of the attribute name. */
202 #define MAX_ATTRS_INDEX 256
203 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
204 static struct insn_def *defs;
205 static struct delay_desc *delays;
207 /* Other variables. */
209 static int insn_code_number;
210 static int insn_index_number;
211 static int got_define_asm_attributes;
212 static int must_extract;
213 static int must_constrain;
214 static int address_used;
215 static int length_used;
216 static int num_delays;
217 static int have_annul_true, have_annul_false;
218 static int num_insn_ents;
220 int num_dfa_decls;
222 /* Stores, for each insn code, the number of constraint alternatives. */
224 static int *insn_n_alternatives;
226 /* Stores, for each insn code, a bitmap that has bits on for each possible
227 alternative. */
229 static int *insn_alternatives;
231 /* If nonzero, assume that the `alternative' attr has this value.
232 This is the hashed, unique string for the numeral
233 whose value is chosen alternative. */
235 static const char *current_alternative_string;
237 /* Used to simplify expressions. */
239 static rtx true_rtx, false_rtx;
241 /* Used to reduce calls to `strcmp' */
243 static char *alternative_name;
244 static const char *length_str;
245 static const char *delay_type_str;
246 static const char *delay_1_0_str;
247 static const char *num_delay_slots_str;
249 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
250 called. */
252 int reload_completed = 0;
254 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
255 to define it here. */
257 int optimize = 0;
259 /* Simplify an expression. Only call the routine if there is something to
260 simplify. */
261 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
262 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
263 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
265 /* Simplify (eq_attr ("alternative") ...)
266 when we are working with a particular alternative. */
267 #define SIMPLIFY_ALTERNATIVE(EXP) \
268 if (current_alternative_string \
269 && GET_CODE ((EXP)) == EQ_ATTR \
270 && XSTR ((EXP), 0) == alternative_name) \
271 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
272 ? true_rtx : false_rtx);
274 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
276 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
277 They won't actually be used. */
279 rtx global_rtl[GR_MAX];
280 rtx pic_offset_table_rtx;
282 static void attr_hash_add_rtx (int, rtx);
283 static void attr_hash_add_string (int, char *);
284 static rtx attr_rtx (enum rtx_code, ...);
285 static rtx attr_rtx_1 (enum rtx_code, va_list);
286 static char *attr_string (const char *, int);
287 static rtx check_attr_value (rtx, struct attr_desc *);
288 static rtx convert_set_attr_alternative (rtx, struct insn_def *);
289 static rtx convert_set_attr (rtx, struct insn_def *);
290 static void check_defs (void);
291 static rtx make_canonical (struct attr_desc *, rtx);
292 static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
293 static rtx copy_rtx_unchanging (rtx);
294 static rtx copy_boolean (rtx);
295 static void expand_delays (void);
296 static void fill_attr (struct attr_desc *);
297 static rtx substitute_address (rtx, rtx (*) (rtx), rtx (*) (rtx));
298 static void make_length_attrs (void);
299 static rtx identity_fn (rtx);
300 static rtx zero_fn (rtx);
301 static rtx one_fn (rtx);
302 static rtx max_fn (rtx);
303 static void write_length_unit_log (void);
304 static rtx simplify_cond (rtx, int, int);
305 static void clear_struct_flag (rtx);
306 static void remove_insn_ent (struct attr_value *, struct insn_ent *);
307 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
308 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
309 static rtx make_alternative_compare (int);
310 static int compute_alternative_mask (rtx, enum rtx_code);
311 static rtx evaluate_eq_attr (rtx, rtx, int, int);
312 static rtx simplify_and_tree (rtx, rtx *, int, int);
313 static rtx simplify_or_tree (rtx, rtx *, int, int);
314 static rtx simplify_test_exp (rtx, int, int);
315 static rtx simplify_test_exp_in_temp (rtx, int, int);
316 static void optimize_attrs (void);
317 static void gen_attr (rtx, int);
318 static int count_alternatives (rtx);
319 static int compares_alternatives_p (rtx);
320 static int contained_in_p (rtx, rtx);
321 static void gen_insn (rtx, int);
322 static void gen_delay (rtx, int);
323 static void write_test_expr (rtx, int);
324 static int max_attr_value (rtx, int*);
325 static int or_attr_value (rtx, int*);
326 static void walk_attr_value (rtx);
327 static void write_attr_get (struct attr_desc *);
328 static rtx eliminate_known_true (rtx, rtx, int, int);
329 static void write_attr_set (struct attr_desc *, int, rtx,
330 const char *, const char *, rtx,
331 int, int);
332 static void write_insn_cases (struct insn_ent *, int);
333 static void write_attr_case (struct attr_desc *, struct attr_value *,
334 int, const char *, const char *, int, rtx);
335 static void write_attr_valueq (struct attr_desc *, const char *);
336 static void write_attr_value (struct attr_desc *, rtx);
337 static void write_upcase (const char *);
338 static void write_indent (int);
339 static void write_eligible_delay (const char *);
340 static int write_expr_attr_cache (rtx, struct attr_desc *);
341 static void write_const_num_delay_slots (void);
342 static char *next_comma_elt (const char **);
343 static struct attr_desc *find_attr (const char **, int);
344 static struct attr_value *find_most_used (struct attr_desc *);
345 static rtx attr_eq (const char *, const char *);
346 static const char *attr_numeral (int);
347 static int attr_equal_p (rtx, rtx);
348 static rtx attr_copy_rtx (rtx);
349 static int attr_rtx_cost (rtx);
350 static bool attr_alt_subset_p (rtx, rtx);
351 static bool attr_alt_subset_of_compl_p (rtx, rtx);
352 static rtx attr_alt_intersection (rtx, rtx);
353 static rtx attr_alt_union (rtx, rtx);
354 static rtx attr_alt_complement (rtx);
355 static bool attr_alt_bit_p (rtx, int);
356 static rtx mk_attr_alt (int);
358 #define oballoc(size) obstack_alloc (hash_obstack, size)
360 /* Hash table for sharing RTL and strings. */
362 /* Each hash table slot is a bucket containing a chain of these structures.
363 Strings are given negative hash codes; RTL expressions are given positive
364 hash codes. */
366 struct attr_hash
368 struct attr_hash *next; /* Next structure in the bucket. */
369 int hashcode; /* Hash code of this rtx or string. */
370 union
372 char *str; /* The string (negative hash codes) */
373 rtx rtl; /* or the RTL recorded here. */
374 } u;
377 /* Now here is the hash table. When recording an RTL, it is added to
378 the slot whose index is the hash code mod the table size. Note
379 that the hash table is used for several kinds of RTL (see attr_rtx)
380 and for strings. While all these live in the same table, they are
381 completely independent, and the hash code is computed differently
382 for each. */
384 #define RTL_HASH_SIZE 4093
385 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
387 /* Here is how primitive or already-shared RTL's hash
388 codes are made. */
389 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
391 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
393 static void
394 attr_hash_add_rtx (int hashcode, rtx rtl)
396 struct attr_hash *h;
398 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
399 h->hashcode = hashcode;
400 h->u.rtl = rtl;
401 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
402 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
405 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
407 static void
408 attr_hash_add_string (int hashcode, char *str)
410 struct attr_hash *h;
412 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
413 h->hashcode = -hashcode;
414 h->u.str = str;
415 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
416 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
419 /* Generate an RTL expression, but avoid duplicates.
420 Set the ATTR_PERMANENT_P flag for these permanent objects.
422 In some cases we cannot uniquify; then we return an ordinary
423 impermanent rtx with ATTR_PERMANENT_P clear.
425 Args are as follows:
427 rtx attr_rtx (code, [element1, ..., elementn]) */
429 static rtx
430 attr_rtx_1 (enum rtx_code code, va_list p)
432 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
433 int hashcode;
434 struct attr_hash *h;
435 struct obstack *old_obstack = rtl_obstack;
437 /* For each of several cases, search the hash table for an existing entry.
438 Use that entry if one is found; otherwise create a new RTL and add it
439 to the table. */
441 if (GET_RTX_CLASS (code) == RTX_UNARY)
443 rtx arg0 = va_arg (p, rtx);
445 /* A permanent object cannot point to impermanent ones. */
446 if (! ATTR_PERMANENT_P (arg0))
448 rt_val = rtx_alloc (code);
449 XEXP (rt_val, 0) = arg0;
450 return rt_val;
453 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
454 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
455 if (h->hashcode == hashcode
456 && GET_CODE (h->u.rtl) == code
457 && XEXP (h->u.rtl, 0) == arg0)
458 return h->u.rtl;
460 if (h == 0)
462 rtl_obstack = hash_obstack;
463 rt_val = rtx_alloc (code);
464 XEXP (rt_val, 0) = arg0;
467 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
468 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
469 || GET_RTX_CLASS (code) == RTX_COMPARE
470 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
472 rtx arg0 = va_arg (p, rtx);
473 rtx arg1 = va_arg (p, rtx);
475 /* A permanent object cannot point to impermanent ones. */
476 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
478 rt_val = rtx_alloc (code);
479 XEXP (rt_val, 0) = arg0;
480 XEXP (rt_val, 1) = arg1;
481 return rt_val;
484 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
485 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
486 if (h->hashcode == hashcode
487 && GET_CODE (h->u.rtl) == code
488 && XEXP (h->u.rtl, 0) == arg0
489 && XEXP (h->u.rtl, 1) == arg1)
490 return h->u.rtl;
492 if (h == 0)
494 rtl_obstack = hash_obstack;
495 rt_val = rtx_alloc (code);
496 XEXP (rt_val, 0) = arg0;
497 XEXP (rt_val, 1) = arg1;
500 else if (GET_RTX_LENGTH (code) == 1
501 && GET_RTX_FORMAT (code)[0] == 's')
503 char *arg0 = va_arg (p, char *);
505 arg0 = DEF_ATTR_STRING (arg0);
507 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
508 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
509 if (h->hashcode == hashcode
510 && GET_CODE (h->u.rtl) == code
511 && XSTR (h->u.rtl, 0) == arg0)
512 return h->u.rtl;
514 if (h == 0)
516 rtl_obstack = hash_obstack;
517 rt_val = rtx_alloc (code);
518 XSTR (rt_val, 0) = arg0;
521 else if (GET_RTX_LENGTH (code) == 2
522 && GET_RTX_FORMAT (code)[0] == 's'
523 && GET_RTX_FORMAT (code)[1] == 's')
525 char *arg0 = va_arg (p, char *);
526 char *arg1 = va_arg (p, char *);
528 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
529 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
530 if (h->hashcode == hashcode
531 && GET_CODE (h->u.rtl) == code
532 && XSTR (h->u.rtl, 0) == arg0
533 && XSTR (h->u.rtl, 1) == arg1)
534 return h->u.rtl;
536 if (h == 0)
538 rtl_obstack = hash_obstack;
539 rt_val = rtx_alloc (code);
540 XSTR (rt_val, 0) = arg0;
541 XSTR (rt_val, 1) = arg1;
544 else if (code == CONST_INT)
546 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
547 if (arg0 == 0)
548 return false_rtx;
549 else if (arg0 == 1)
550 return true_rtx;
551 else
552 goto nohash;
554 else
556 int i; /* Array indices... */
557 const char *fmt; /* Current rtx's format... */
558 nohash:
559 rt_val = rtx_alloc (code); /* Allocate the storage space. */
561 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
562 for (i = 0; i < GET_RTX_LENGTH (code); i++)
564 switch (*fmt++)
566 case '0': /* Unused field. */
567 break;
569 case 'i': /* An integer? */
570 XINT (rt_val, i) = va_arg (p, int);
571 break;
573 case 'w': /* A wide integer? */
574 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
575 break;
577 case 's': /* A string? */
578 XSTR (rt_val, i) = va_arg (p, char *);
579 break;
581 case 'e': /* An expression? */
582 case 'u': /* An insn? Same except when printing. */
583 XEXP (rt_val, i) = va_arg (p, rtx);
584 break;
586 case 'E': /* An RTX vector? */
587 XVEC (rt_val, i) = va_arg (p, rtvec);
588 break;
590 default:
591 gcc_unreachable ();
594 return rt_val;
597 rtl_obstack = old_obstack;
598 attr_hash_add_rtx (hashcode, rt_val);
599 ATTR_PERMANENT_P (rt_val) = 1;
600 return rt_val;
603 static rtx
604 attr_rtx (enum rtx_code code, ...)
606 rtx result;
607 va_list p;
609 va_start (p, code);
610 result = attr_rtx_1 (code, p);
611 va_end (p);
612 return result;
615 /* Create a new string printed with the printf line arguments into a space
616 of at most LEN bytes:
618 rtx attr_printf (len, format, [arg1, ..., argn]) */
620 char *
621 attr_printf (unsigned int len, const char *fmt, ...)
623 char str[256];
624 va_list p;
626 va_start (p, fmt);
628 gcc_assert (len < sizeof str); /* Leave room for \0. */
630 vsprintf (str, fmt, p);
631 va_end (p);
633 return DEF_ATTR_STRING (str);
636 static rtx
637 attr_eq (const char *name, const char *value)
639 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
642 static const char *
643 attr_numeral (int n)
645 return XSTR (make_numeric_value (n), 0);
648 /* Return a permanent (possibly shared) copy of a string STR (not assumed
649 to be null terminated) with LEN bytes. */
651 static char *
652 attr_string (const char *str, int len)
654 struct attr_hash *h;
655 int hashcode;
656 int i;
657 char *new_str;
659 /* Compute the hash code. */
660 hashcode = (len + 1) * 613 + (unsigned) str[0];
661 for (i = 1; i <= len; i += 2)
662 hashcode = ((hashcode * 613) + (unsigned) str[i]);
663 if (hashcode < 0)
664 hashcode = -hashcode;
666 /* Search the table for the string. */
667 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
668 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
669 && !strncmp (h->u.str, str, len))
670 return h->u.str; /* <-- return if found. */
672 /* Not found; create a permanent copy and add it to the hash table. */
673 new_str = obstack_alloc (hash_obstack, len + 1);
674 memcpy (new_str, str, len);
675 new_str[len] = '\0';
676 attr_hash_add_string (hashcode, new_str);
678 return new_str; /* Return the new string. */
681 /* Check two rtx's for equality of contents,
682 taking advantage of the fact that if both are hashed
683 then they can't be equal unless they are the same object. */
685 static int
686 attr_equal_p (rtx x, rtx y)
688 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
689 && rtx_equal_p (x, y)));
692 /* Copy an attribute value expression,
693 descending to all depths, but not copying any
694 permanent hashed subexpressions. */
696 static rtx
697 attr_copy_rtx (rtx orig)
699 rtx copy;
700 int i, j;
701 RTX_CODE code;
702 const char *format_ptr;
704 /* No need to copy a permanent object. */
705 if (ATTR_PERMANENT_P (orig))
706 return orig;
708 code = GET_CODE (orig);
710 switch (code)
712 case REG:
713 case CONST_INT:
714 case CONST_DOUBLE:
715 case CONST_VECTOR:
716 case SYMBOL_REF:
717 case CODE_LABEL:
718 case PC:
719 case CC0:
720 return orig;
722 default:
723 break;
726 copy = rtx_alloc (code);
727 PUT_MODE (copy, GET_MODE (orig));
728 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
729 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
730 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
732 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
734 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
736 switch (*format_ptr++)
738 case 'e':
739 XEXP (copy, i) = XEXP (orig, i);
740 if (XEXP (orig, i) != NULL)
741 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
742 break;
744 case 'E':
745 case 'V':
746 XVEC (copy, i) = XVEC (orig, i);
747 if (XVEC (orig, i) != NULL)
749 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
750 for (j = 0; j < XVECLEN (copy, i); j++)
751 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
753 break;
755 case 'n':
756 case 'i':
757 XINT (copy, i) = XINT (orig, i);
758 break;
760 case 'w':
761 XWINT (copy, i) = XWINT (orig, i);
762 break;
764 case 's':
765 case 'S':
766 XSTR (copy, i) = XSTR (orig, i);
767 break;
769 default:
770 gcc_unreachable ();
773 return copy;
776 /* Given a test expression for an attribute, ensure it is validly formed.
777 IS_CONST indicates whether the expression is constant for each compiler
778 run (a constant expression may not test any particular insn).
780 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
781 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
782 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
784 Update the string address in EQ_ATTR expression to be the same used
785 in the attribute (or `alternative_name') to speed up subsequent
786 `find_attr' calls and eliminate most `strcmp' calls.
788 Return the new expression, if any. */
791 check_attr_test (rtx exp, int is_const, int lineno)
793 struct attr_desc *attr;
794 struct attr_value *av;
795 const char *name_ptr, *p;
796 rtx orexp, newexp;
798 switch (GET_CODE (exp))
800 case EQ_ATTR:
801 /* Handle negation test. */
802 if (XSTR (exp, 1)[0] == '!')
803 return check_attr_test (attr_rtx (NOT,
804 attr_eq (XSTR (exp, 0),
805 &XSTR (exp, 1)[1])),
806 is_const, lineno);
808 else if (n_comma_elts (XSTR (exp, 1)) == 1)
810 attr = find_attr (&XSTR (exp, 0), 0);
811 if (attr == NULL)
813 if (! strcmp (XSTR (exp, 0), "alternative"))
814 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
815 else
816 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
819 if (is_const && ! attr->is_const)
820 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
821 XSTR (exp, 0));
823 /* Copy this just to make it permanent,
824 so expressions using it can be permanent too. */
825 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
827 /* It shouldn't be possible to simplify the value given to a
828 constant attribute, so don't expand this until it's time to
829 write the test expression. */
830 if (attr->is_const)
831 ATTR_IND_SIMPLIFIED_P (exp) = 1;
833 if (attr->is_numeric)
835 for (p = XSTR (exp, 1); *p; p++)
836 if (! ISDIGIT (*p))
837 fatal ("attribute `%s' takes only numeric values",
838 XSTR (exp, 0));
840 else
842 for (av = attr->first_value; av; av = av->next)
843 if (GET_CODE (av->value) == CONST_STRING
844 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
845 break;
847 if (av == NULL)
848 fatal ("unknown value `%s' for `%s' attribute",
849 XSTR (exp, 1), XSTR (exp, 0));
852 else
854 if (! strcmp (XSTR (exp, 0), "alternative"))
856 int set = 0;
858 name_ptr = XSTR (exp, 1);
859 while ((p = next_comma_elt (&name_ptr)) != NULL)
860 set |= 1 << atoi (p);
862 return mk_attr_alt (set);
864 else
866 /* Make an IOR tree of the possible values. */
867 orexp = false_rtx;
868 name_ptr = XSTR (exp, 1);
869 while ((p = next_comma_elt (&name_ptr)) != NULL)
871 newexp = attr_eq (XSTR (exp, 0), p);
872 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
875 return check_attr_test (orexp, is_const, lineno);
878 break;
880 case ATTR_FLAG:
881 break;
883 case CONST_INT:
884 /* Either TRUE or FALSE. */
885 if (XWINT (exp, 0))
886 return true_rtx;
887 else
888 return false_rtx;
890 case IOR:
891 case AND:
892 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
893 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
894 break;
896 case NOT:
897 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
898 break;
900 case MATCH_OPERAND:
901 if (is_const)
902 fatal ("RTL operator \"%s\" not valid in constant attribute test",
903 GET_RTX_NAME (GET_CODE (exp)));
904 /* These cases can't be simplified. */
905 ATTR_IND_SIMPLIFIED_P (exp) = 1;
906 break;
908 case LE: case LT: case GT: case GE:
909 case LEU: case LTU: case GTU: case GEU:
910 case NE: case EQ:
911 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
912 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
913 exp = attr_rtx (GET_CODE (exp),
914 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
915 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
916 /* These cases can't be simplified. */
917 ATTR_IND_SIMPLIFIED_P (exp) = 1;
918 break;
920 case SYMBOL_REF:
921 if (is_const)
923 /* These cases are valid for constant attributes, but can't be
924 simplified. */
925 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
926 ATTR_IND_SIMPLIFIED_P (exp) = 1;
927 break;
929 default:
930 fatal ("RTL operator \"%s\" not valid in attribute test",
931 GET_RTX_NAME (GET_CODE (exp)));
934 return exp;
937 /* Given an expression, ensure that it is validly formed and that all named
938 attribute values are valid for the given attribute. Issue a fatal error
939 if not. If no attribute is specified, assume a numeric attribute.
941 Return a perhaps modified replacement expression for the value. */
943 static rtx
944 check_attr_value (rtx exp, struct attr_desc *attr)
946 struct attr_value *av;
947 const char *p;
948 int i;
950 switch (GET_CODE (exp))
952 case CONST_INT:
953 if (attr && ! attr->is_numeric)
955 message_with_line (attr->lineno,
956 "CONST_INT not valid for non-numeric attribute %s",
957 attr->name);
958 have_error = 1;
959 break;
962 if (INTVAL (exp) < 0)
964 message_with_line (attr->lineno,
965 "negative numeric value specified for attribute %s",
966 attr->name);
967 have_error = 1;
968 break;
970 break;
972 case CONST_STRING:
973 if (! strcmp (XSTR (exp, 0), "*"))
974 break;
976 if (attr == 0 || attr->is_numeric)
978 p = XSTR (exp, 0);
979 for (; *p; p++)
980 if (! ISDIGIT (*p))
982 message_with_line (attr ? attr->lineno : 0,
983 "non-numeric value for numeric attribute %s",
984 attr ? attr->name : "internal");
985 have_error = 1;
986 break;
988 break;
991 for (av = attr->first_value; av; av = av->next)
992 if (GET_CODE (av->value) == CONST_STRING
993 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
994 break;
996 if (av == NULL)
998 message_with_line (attr->lineno,
999 "unknown value `%s' for `%s' attribute",
1000 XSTR (exp, 0), attr ? attr->name : "internal");
1001 have_error = 1;
1003 break;
1005 case IF_THEN_ELSE:
1006 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1007 attr ? attr->is_const : 0,
1008 attr ? attr->lineno : 0);
1009 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1010 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1011 break;
1013 case PLUS:
1014 case MINUS:
1015 case MULT:
1016 case DIV:
1017 case MOD:
1018 if (attr && !attr->is_numeric)
1020 message_with_line (attr->lineno,
1021 "invalid operation `%s' for non-numeric attribute value",
1022 GET_RTX_NAME (GET_CODE (exp)));
1023 have_error = 1;
1024 break;
1026 /* Fall through. */
1028 case IOR:
1029 case AND:
1030 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1031 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1032 break;
1034 case FFS:
1035 case CLZ:
1036 case CTZ:
1037 case POPCOUNT:
1038 case PARITY:
1039 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1040 break;
1042 case COND:
1043 if (XVECLEN (exp, 0) % 2 != 0)
1045 message_with_line (attr->lineno,
1046 "first operand of COND must have even length");
1047 have_error = 1;
1048 break;
1051 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1053 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1054 attr ? attr->is_const : 0,
1055 attr ? attr->lineno : 0);
1056 XVECEXP (exp, 0, i + 1)
1057 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1060 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1061 break;
1063 case ATTR:
1065 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1066 if (attr2 == NULL)
1068 message_with_line (attr ? attr->lineno : 0,
1069 "unknown attribute `%s' in ATTR",
1070 XSTR (exp, 0));
1071 have_error = 1;
1073 else if (attr && attr->is_const && ! attr2->is_const)
1075 message_with_line (attr->lineno,
1076 "non-constant attribute `%s' referenced from `%s'",
1077 XSTR (exp, 0), attr->name);
1078 have_error = 1;
1080 else if (attr
1081 && attr->is_numeric != attr2->is_numeric)
1083 message_with_line (attr->lineno,
1084 "numeric attribute mismatch calling `%s' from `%s'",
1085 XSTR (exp, 0), attr->name);
1086 have_error = 1;
1089 break;
1091 case SYMBOL_REF:
1092 /* A constant SYMBOL_REF is valid as a constant attribute test and
1093 is expanded later by make_canonical into a COND. In a non-constant
1094 attribute test, it is left be. */
1095 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1097 default:
1098 message_with_line (attr ? attr->lineno : 0,
1099 "invalid operation `%s' for attribute value",
1100 GET_RTX_NAME (GET_CODE (exp)));
1101 have_error = 1;
1102 break;
1105 return exp;
1108 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1109 It becomes a COND with each test being (eq_attr "alternative "n") */
1111 static rtx
1112 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1114 int num_alt = id->num_alternatives;
1115 rtx condexp;
1116 int i;
1118 if (XVECLEN (exp, 1) != num_alt)
1120 message_with_line (id->lineno,
1121 "bad number of entries in SET_ATTR_ALTERNATIVE");
1122 have_error = 1;
1123 return NULL_RTX;
1126 /* Make a COND with all tests but the last. Select the last value via the
1127 default. */
1128 condexp = rtx_alloc (COND);
1129 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1131 for (i = 0; i < num_alt - 1; i++)
1133 const char *p;
1134 p = attr_numeral (i);
1136 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1137 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1140 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1142 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1145 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1146 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1148 static rtx
1149 convert_set_attr (rtx exp, struct insn_def *id)
1151 rtx newexp;
1152 const char *name_ptr;
1153 char *p;
1154 int n;
1156 /* See how many alternative specified. */
1157 n = n_comma_elts (XSTR (exp, 1));
1158 if (n == 1)
1159 return attr_rtx (SET,
1160 attr_rtx (ATTR, XSTR (exp, 0)),
1161 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1163 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1164 XSTR (newexp, 0) = XSTR (exp, 0);
1165 XVEC (newexp, 1) = rtvec_alloc (n);
1167 /* Process each comma-separated name. */
1168 name_ptr = XSTR (exp, 1);
1169 n = 0;
1170 while ((p = next_comma_elt (&name_ptr)) != NULL)
1171 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1173 return convert_set_attr_alternative (newexp, id);
1176 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1177 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1178 expressions. */
1180 static void
1181 check_defs (void)
1183 struct insn_def *id;
1184 struct attr_desc *attr;
1185 int i;
1186 rtx value;
1188 for (id = defs; id; id = id->next)
1190 if (XVEC (id->def, id->vec_idx) == NULL)
1191 continue;
1193 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1195 value = XVECEXP (id->def, id->vec_idx, i);
1196 switch (GET_CODE (value))
1198 case SET:
1199 if (GET_CODE (XEXP (value, 0)) != ATTR)
1201 message_with_line (id->lineno, "bad attribute set");
1202 have_error = 1;
1203 value = NULL_RTX;
1205 break;
1207 case SET_ATTR_ALTERNATIVE:
1208 value = convert_set_attr_alternative (value, id);
1209 break;
1211 case SET_ATTR:
1212 value = convert_set_attr (value, id);
1213 break;
1215 default:
1216 message_with_line (id->lineno, "invalid attribute code %s",
1217 GET_RTX_NAME (GET_CODE (value)));
1218 have_error = 1;
1219 value = NULL_RTX;
1221 if (value == NULL_RTX)
1222 continue;
1224 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1226 message_with_line (id->lineno, "unknown attribute %s",
1227 XSTR (XEXP (value, 0), 0));
1228 have_error = 1;
1229 continue;
1232 XVECEXP (id->def, id->vec_idx, i) = value;
1233 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1238 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1239 expressions by converting them into a COND. This removes cases from this
1240 program. Also, replace an attribute value of "*" with the default attribute
1241 value. */
1243 static rtx
1244 make_canonical (struct attr_desc *attr, rtx exp)
1246 int i;
1247 rtx newexp;
1249 switch (GET_CODE (exp))
1251 case CONST_INT:
1252 exp = make_numeric_value (INTVAL (exp));
1253 break;
1255 case CONST_STRING:
1256 if (! strcmp (XSTR (exp, 0), "*"))
1258 if (attr == 0 || attr->default_val == 0)
1259 fatal ("(attr_value \"*\") used in invalid context");
1260 exp = attr->default_val->value;
1262 else
1263 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1265 break;
1267 case SYMBOL_REF:
1268 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1269 break;
1270 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1271 This makes the COND something that won't be considered an arbitrary
1272 expression by walk_attr_value. */
1273 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1274 exp = check_attr_value (exp, attr);
1275 break;
1277 case IF_THEN_ELSE:
1278 newexp = rtx_alloc (COND);
1279 XVEC (newexp, 0) = rtvec_alloc (2);
1280 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1281 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1283 XEXP (newexp, 1) = XEXP (exp, 2);
1285 exp = newexp;
1286 /* Fall through to COND case since this is now a COND. */
1288 case COND:
1290 int allsame = 1;
1291 rtx defval;
1293 /* First, check for degenerate COND. */
1294 if (XVECLEN (exp, 0) == 0)
1295 return make_canonical (attr, XEXP (exp, 1));
1296 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1298 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1300 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1301 XVECEXP (exp, 0, i + 1)
1302 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1303 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1304 allsame = 0;
1306 if (allsame)
1307 return defval;
1309 break;
1311 default:
1312 break;
1315 return exp;
1318 static rtx
1319 copy_boolean (rtx exp)
1321 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1322 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1323 copy_boolean (XEXP (exp, 1)));
1324 if (GET_CODE (exp) == MATCH_OPERAND)
1326 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1327 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1329 else if (GET_CODE (exp) == EQ_ATTR)
1331 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1332 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1335 return exp;
1338 /* Given a value and an attribute description, return a `struct attr_value *'
1339 that represents that value. This is either an existing structure, if the
1340 value has been previously encountered, or a newly-created structure.
1342 `insn_code' is the code of an insn whose attribute has the specified
1343 value (-2 if not processing an insn). We ensure that all insns for
1344 a given value have the same number of alternatives if the value checks
1345 alternatives. */
1347 static struct attr_value *
1348 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1350 struct attr_value *av;
1351 int num_alt = 0;
1353 value = make_canonical (attr, value);
1354 if (compares_alternatives_p (value))
1356 if (insn_code < 0 || insn_alternatives == NULL)
1357 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1358 else
1359 num_alt = insn_alternatives[insn_code];
1362 for (av = attr->first_value; av; av = av->next)
1363 if (rtx_equal_p (value, av->value)
1364 && (num_alt == 0 || av->first_insn == NULL
1365 || insn_alternatives[av->first_insn->def->insn_code]))
1366 return av;
1368 av = oballoc (sizeof (struct attr_value));
1369 av->value = value;
1370 av->next = attr->first_value;
1371 attr->first_value = av;
1372 av->first_insn = NULL;
1373 av->num_insns = 0;
1374 av->has_asm_insn = 0;
1376 return av;
1379 /* After all DEFINE_DELAYs have been read in, create internal attributes
1380 to generate the required routines.
1382 First, we compute the number of delay slots for each insn (as a COND of
1383 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1384 delay type is specified, we compute a similar function giving the
1385 DEFINE_DELAY ordinal for each insn.
1387 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1388 tells whether a given insn can be in that delay slot.
1390 Normal attribute filling and optimization expands these to contain the
1391 information needed to handle delay slots. */
1393 static void
1394 expand_delays (void)
1396 struct delay_desc *delay;
1397 rtx condexp;
1398 rtx newexp;
1399 int i;
1400 char *p;
1402 /* First, generate data for `num_delay_slots' function. */
1404 condexp = rtx_alloc (COND);
1405 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1406 XEXP (condexp, 1) = make_numeric_value (0);
1408 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1410 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1411 XVECEXP (condexp, 0, i + 1)
1412 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1415 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1417 /* If more than one delay type, do the same for computing the delay type. */
1418 if (num_delays > 1)
1420 condexp = rtx_alloc (COND);
1421 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1422 XEXP (condexp, 1) = make_numeric_value (0);
1424 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1426 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1427 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1430 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1433 /* For each delay possibility and delay slot, compute an eligibility
1434 attribute for non-annulled insns and for each type of annulled (annul
1435 if true and annul if false). */
1436 for (delay = delays; delay; delay = delay->next)
1438 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1440 condexp = XVECEXP (delay->def, 1, i);
1441 if (condexp == 0)
1442 condexp = false_rtx;
1443 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1444 make_numeric_value (1), make_numeric_value (0));
1446 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1447 "*delay_%d_%d", delay->num, i / 3);
1448 make_internal_attr (p, newexp, ATTR_SPECIAL);
1450 if (have_annul_true)
1452 condexp = XVECEXP (delay->def, 1, i + 1);
1453 if (condexp == 0) condexp = false_rtx;
1454 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1455 make_numeric_value (1),
1456 make_numeric_value (0));
1457 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1458 "*annul_true_%d_%d", delay->num, i / 3);
1459 make_internal_attr (p, newexp, ATTR_SPECIAL);
1462 if (have_annul_false)
1464 condexp = XVECEXP (delay->def, 1, i + 2);
1465 if (condexp == 0) condexp = false_rtx;
1466 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1467 make_numeric_value (1),
1468 make_numeric_value (0));
1469 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1470 "*annul_false_%d_%d", delay->num, i / 3);
1471 make_internal_attr (p, newexp, ATTR_SPECIAL);
1477 /* Once all attributes and insns have been read and checked, we construct for
1478 each attribute value a list of all the insns that have that value for
1479 the attribute. */
1481 static void
1482 fill_attr (struct attr_desc *attr)
1484 struct attr_value *av;
1485 struct insn_ent *ie;
1486 struct insn_def *id;
1487 int i;
1488 rtx value;
1490 /* Don't fill constant attributes. The value is independent of
1491 any particular insn. */
1492 if (attr->is_const)
1493 return;
1495 for (id = defs; id; id = id->next)
1497 /* If no value is specified for this insn for this attribute, use the
1498 default. */
1499 value = NULL;
1500 if (XVEC (id->def, id->vec_idx))
1501 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1502 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1503 attr->name))
1504 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1506 if (value == NULL)
1507 av = attr->default_val;
1508 else
1509 av = get_attr_value (value, attr, id->insn_code);
1511 ie = oballoc (sizeof (struct insn_ent));
1512 ie->def = id;
1513 insert_insn_ent (av, ie);
1517 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1518 test that checks relative positions of insns (uses MATCH_DUP or PC).
1519 If so, replace it with what is obtained by passing the expression to
1520 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1521 recursively on each value (including the default value). Otherwise,
1522 return the value returned by NO_ADDRESS_FN applied to EXP. */
1524 static rtx
1525 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1526 rtx (*address_fn) (rtx))
1528 int i;
1529 rtx newexp;
1531 if (GET_CODE (exp) == COND)
1533 /* See if any tests use addresses. */
1534 address_used = 0;
1535 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1536 walk_attr_value (XVECEXP (exp, 0, i));
1538 if (address_used)
1539 return (*address_fn) (exp);
1541 /* Make a new copy of this COND, replacing each element. */
1542 newexp = rtx_alloc (COND);
1543 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1544 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1546 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1547 XVECEXP (newexp, 0, i + 1)
1548 = substitute_address (XVECEXP (exp, 0, i + 1),
1549 no_address_fn, address_fn);
1552 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1553 no_address_fn, address_fn);
1555 return newexp;
1558 else if (GET_CODE (exp) == IF_THEN_ELSE)
1560 address_used = 0;
1561 walk_attr_value (XEXP (exp, 0));
1562 if (address_used)
1563 return (*address_fn) (exp);
1565 return attr_rtx (IF_THEN_ELSE,
1566 substitute_address (XEXP (exp, 0),
1567 no_address_fn, address_fn),
1568 substitute_address (XEXP (exp, 1),
1569 no_address_fn, address_fn),
1570 substitute_address (XEXP (exp, 2),
1571 no_address_fn, address_fn));
1574 return (*no_address_fn) (exp);
1577 /* Make new attributes from the `length' attribute. The following are made,
1578 each corresponding to a function called from `shorten_branches' or
1579 `get_attr_length':
1581 *insn_default_length This is the length of the insn to be returned
1582 by `get_attr_length' before `shorten_branches'
1583 has been called. In each case where the length
1584 depends on relative addresses, the largest
1585 possible is used. This routine is also used
1586 to compute the initial size of the insn.
1588 *insn_variable_length_p This returns 1 if the insn's length depends
1589 on relative addresses, zero otherwise.
1591 *insn_current_length This is only called when it is known that the
1592 insn has a variable length and returns the
1593 current length, based on relative addresses.
1596 static void
1597 make_length_attrs (void)
1599 static const char *new_names[] =
1601 "*insn_default_length",
1602 "*insn_variable_length_p",
1603 "*insn_current_length"
1605 static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn};
1606 static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn};
1607 size_t i;
1608 struct attr_desc *length_attr, *new_attr;
1609 struct attr_value *av, *new_av;
1610 struct insn_ent *ie, *new_ie;
1612 /* See if length attribute is defined. If so, it must be numeric. Make
1613 it special so we don't output anything for it. */
1614 length_attr = find_attr (&length_str, 0);
1615 if (length_attr == 0)
1616 return;
1618 if (! length_attr->is_numeric)
1619 fatal ("length attribute must be numeric");
1621 length_attr->is_const = 0;
1622 length_attr->is_special = 1;
1624 /* Make each new attribute, in turn. */
1625 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1627 make_internal_attr (new_names[i],
1628 substitute_address (length_attr->default_val->value,
1629 no_address_fn[i], address_fn[i]),
1630 ATTR_NONE);
1631 new_attr = find_attr (&new_names[i], 0);
1632 for (av = length_attr->first_value; av; av = av->next)
1633 for (ie = av->first_insn; ie; ie = ie->next)
1635 new_av = get_attr_value (substitute_address (av->value,
1636 no_address_fn[i],
1637 address_fn[i]),
1638 new_attr, ie->def->insn_code);
1639 new_ie = oballoc (sizeof (struct insn_ent));
1640 new_ie->def = ie->def;
1641 insert_insn_ent (new_av, new_ie);
1646 /* Utility functions called from above routine. */
1648 static rtx
1649 identity_fn (rtx exp)
1651 return exp;
1654 static rtx
1655 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1657 return make_numeric_value (0);
1660 static rtx
1661 one_fn (rtx exp ATTRIBUTE_UNUSED)
1663 return make_numeric_value (1);
1666 static rtx
1667 max_fn (rtx exp)
1669 int unknown;
1670 return make_numeric_value (max_attr_value (exp, &unknown));
1673 static void
1674 write_length_unit_log (void)
1676 struct attr_desc *length_attr = find_attr (&length_str, 0);
1677 struct attr_value *av;
1678 struct insn_ent *ie;
1679 unsigned int length_unit_log, length_or;
1680 int unknown = 0;
1682 if (length_attr == 0)
1683 return;
1684 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1685 for (av = length_attr->first_value; av; av = av->next)
1686 for (ie = av->first_insn; ie; ie = ie->next)
1687 length_or |= or_attr_value (av->value, &unknown);
1689 if (unknown)
1690 length_unit_log = 0;
1691 else
1693 length_or = ~length_or;
1694 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1695 length_unit_log++;
1697 printf ("int length_unit_log = %u;\n", length_unit_log);
1700 /* Take a COND expression and see if any of the conditions in it can be
1701 simplified. If any are known true or known false for the particular insn
1702 code, the COND can be further simplified.
1704 Also call ourselves on any COND operations that are values of this COND.
1706 We do not modify EXP; rather, we make and return a new rtx. */
1708 static rtx
1709 simplify_cond (rtx exp, int insn_code, int insn_index)
1711 int i, j;
1712 /* We store the desired contents here,
1713 then build a new expression if they don't match EXP. */
1714 rtx defval = XEXP (exp, 1);
1715 rtx new_defval = XEXP (exp, 1);
1716 int len = XVECLEN (exp, 0);
1717 rtx *tests = xmalloc (len * sizeof (rtx));
1718 int allsame = 1;
1719 rtx ret;
1721 /* This lets us free all storage allocated below, if appropriate. */
1722 obstack_finish (rtl_obstack);
1724 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1726 /* See if default value needs simplification. */
1727 if (GET_CODE (defval) == COND)
1728 new_defval = simplify_cond (defval, insn_code, insn_index);
1730 /* Simplify the subexpressions, and see what tests we can get rid of. */
1732 for (i = 0; i < len; i += 2)
1734 rtx newtest, newval;
1736 /* Simplify this test. */
1737 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1738 tests[i] = newtest;
1740 newval = tests[i + 1];
1741 /* See if this value may need simplification. */
1742 if (GET_CODE (newval) == COND)
1743 newval = simplify_cond (newval, insn_code, insn_index);
1745 /* Look for ways to delete or combine this test. */
1746 if (newtest == true_rtx)
1748 /* If test is true, make this value the default
1749 and discard this + any following tests. */
1750 len = i;
1751 defval = tests[i + 1];
1752 new_defval = newval;
1755 else if (newtest == false_rtx)
1757 /* If test is false, discard it and its value. */
1758 for (j = i; j < len - 2; j++)
1759 tests[j] = tests[j + 2];
1760 i -= 2;
1761 len -= 2;
1764 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1766 /* If this value and the value for the prev test are the same,
1767 merge the tests. */
1769 tests[i - 2]
1770 = insert_right_side (IOR, tests[i - 2], newtest,
1771 insn_code, insn_index);
1773 /* Delete this test/value. */
1774 for (j = i; j < len - 2; j++)
1775 tests[j] = tests[j + 2];
1776 len -= 2;
1777 i -= 2;
1780 else
1781 tests[i + 1] = newval;
1784 /* If the last test in a COND has the same value
1785 as the default value, that test isn't needed. */
1787 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1788 len -= 2;
1790 /* See if we changed anything. */
1791 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1792 allsame = 0;
1793 else
1794 for (i = 0; i < len; i++)
1795 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1797 allsame = 0;
1798 break;
1801 if (len == 0)
1803 if (GET_CODE (defval) == COND)
1804 ret = simplify_cond (defval, insn_code, insn_index);
1805 else
1806 ret = defval;
1808 else if (allsame)
1809 ret = exp;
1810 else
1812 rtx newexp = rtx_alloc (COND);
1814 XVEC (newexp, 0) = rtvec_alloc (len);
1815 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1816 XEXP (newexp, 1) = new_defval;
1817 ret = newexp;
1819 free (tests);
1820 return ret;
1823 /* Remove an insn entry from an attribute value. */
1825 static void
1826 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1828 struct insn_ent *previe;
1830 if (av->first_insn == ie)
1831 av->first_insn = ie->next;
1832 else
1834 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1836 previe->next = ie->next;
1839 av->num_insns--;
1840 if (ie->def->insn_code == -1)
1841 av->has_asm_insn = 0;
1843 num_insn_ents--;
1846 /* Insert an insn entry in an attribute value list. */
1848 static void
1849 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1851 ie->next = av->first_insn;
1852 av->first_insn = ie;
1853 av->num_insns++;
1854 if (ie->def->insn_code == -1)
1855 av->has_asm_insn = 1;
1857 num_insn_ents++;
1860 /* This is a utility routine to take an expression that is a tree of either
1861 AND or IOR expressions and insert a new term. The new term will be
1862 inserted at the right side of the first node whose code does not match
1863 the root. A new node will be created with the root's code. Its left
1864 side will be the old right side and its right side will be the new
1865 term.
1867 If the `term' is itself a tree, all its leaves will be inserted. */
1869 static rtx
1870 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1872 rtx newexp;
1874 /* Avoid consing in some special cases. */
1875 if (code == AND && term == true_rtx)
1876 return exp;
1877 if (code == AND && term == false_rtx)
1878 return false_rtx;
1879 if (code == AND && exp == true_rtx)
1880 return term;
1881 if (code == AND && exp == false_rtx)
1882 return false_rtx;
1883 if (code == IOR && term == true_rtx)
1884 return true_rtx;
1885 if (code == IOR && term == false_rtx)
1886 return exp;
1887 if (code == IOR && exp == true_rtx)
1888 return true_rtx;
1889 if (code == IOR && exp == false_rtx)
1890 return term;
1891 if (attr_equal_p (exp, term))
1892 return exp;
1894 if (GET_CODE (term) == code)
1896 exp = insert_right_side (code, exp, XEXP (term, 0),
1897 insn_code, insn_index);
1898 exp = insert_right_side (code, exp, XEXP (term, 1),
1899 insn_code, insn_index);
1901 return exp;
1904 if (GET_CODE (exp) == code)
1906 rtx new = insert_right_side (code, XEXP (exp, 1),
1907 term, insn_code, insn_index);
1908 if (new != XEXP (exp, 1))
1909 /* Make a copy of this expression and call recursively. */
1910 newexp = attr_rtx (code, XEXP (exp, 0), new);
1911 else
1912 newexp = exp;
1914 else
1916 /* Insert the new term. */
1917 newexp = attr_rtx (code, exp, term);
1920 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1923 /* If we have an expression which AND's a bunch of
1924 (not (eq_attrq "alternative" "n"))
1925 terms, we may have covered all or all but one of the possible alternatives.
1926 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1928 This routine is passed an expression and either AND or IOR. It returns a
1929 bitmask indicating which alternatives are mentioned within EXP. */
1931 static int
1932 compute_alternative_mask (rtx exp, enum rtx_code code)
1934 const char *string;
1935 if (GET_CODE (exp) == code)
1936 return compute_alternative_mask (XEXP (exp, 0), code)
1937 | compute_alternative_mask (XEXP (exp, 1), code);
1939 else if (code == AND && GET_CODE (exp) == NOT
1940 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1941 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1942 string = XSTR (XEXP (exp, 0), 1);
1944 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1945 && XSTR (exp, 0) == alternative_name)
1946 string = XSTR (exp, 1);
1948 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1950 if (code == AND && XINT (exp, 1))
1951 return XINT (exp, 0);
1953 if (code == IOR && !XINT (exp, 1))
1954 return XINT (exp, 0);
1956 return 0;
1958 else
1959 return 0;
1961 if (string[1] == 0)
1962 return 1 << (string[0] - '0');
1963 return 1 << atoi (string);
1966 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1967 attribute with the value represented by that bit. */
1969 static rtx
1970 make_alternative_compare (int mask)
1972 return mk_attr_alt (mask);
1975 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1976 of "attr" for this insn code. From that value, we can compute a test
1977 showing when the EQ_ATTR will be true. This routine performs that
1978 computation. If a test condition involves an address, we leave the EQ_ATTR
1979 intact because addresses are only valid for the `length' attribute.
1981 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1982 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1984 static rtx
1985 evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
1987 rtx orexp, andexp;
1988 rtx right;
1989 rtx newexp;
1990 int i;
1992 switch (GET_CODE (value))
1994 case CONST_STRING:
1995 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
1996 newexp = true_rtx;
1997 else
1998 newexp = false_rtx;
1999 break;
2001 case SYMBOL_REF:
2003 char *p;
2004 char string[256];
2006 gcc_assert (GET_CODE (exp) == EQ_ATTR);
2007 gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
2008 <= 256);
2010 strcpy (string, XSTR (exp, 0));
2011 strcat (string, "_");
2012 strcat (string, XSTR (exp, 1));
2013 for (p = string; *p; p++)
2014 *p = TOUPPER (*p);
2016 newexp = attr_rtx (EQ, value,
2017 attr_rtx (SYMBOL_REF,
2018 DEF_ATTR_STRING (string)));
2019 break;
2022 case COND:
2023 /* We construct an IOR of all the cases for which the
2024 requested attribute value is present. Since we start with
2025 FALSE, if it is not present, FALSE will be returned.
2027 Each case is the AND of the NOT's of the previous conditions with the
2028 current condition; in the default case the current condition is TRUE.
2030 For each possible COND value, call ourselves recursively.
2032 The extra TRUE and FALSE expressions will be eliminated by another
2033 call to the simplification routine. */
2035 orexp = false_rtx;
2036 andexp = true_rtx;
2038 if (current_alternative_string)
2039 clear_struct_flag (value);
2041 for (i = 0; i < XVECLEN (value, 0); i += 2)
2043 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2044 insn_code, insn_index);
2046 SIMPLIFY_ALTERNATIVE (this);
2048 right = insert_right_side (AND, andexp, this,
2049 insn_code, insn_index);
2050 right = insert_right_side (AND, right,
2051 evaluate_eq_attr (exp,
2052 XVECEXP (value, 0,
2053 i + 1),
2054 insn_code, insn_index),
2055 insn_code, insn_index);
2056 orexp = insert_right_side (IOR, orexp, right,
2057 insn_code, insn_index);
2059 /* Add this condition into the AND expression. */
2060 newexp = attr_rtx (NOT, this);
2061 andexp = insert_right_side (AND, andexp, newexp,
2062 insn_code, insn_index);
2065 /* Handle the default case. */
2066 right = insert_right_side (AND, andexp,
2067 evaluate_eq_attr (exp, XEXP (value, 1),
2068 insn_code, insn_index),
2069 insn_code, insn_index);
2070 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2071 break;
2073 default:
2074 gcc_unreachable ();
2077 /* If uses an address, must return original expression. But set the
2078 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2080 address_used = 0;
2081 walk_attr_value (newexp);
2083 if (address_used)
2085 /* This had `&& current_alternative_string', which seems to be wrong. */
2086 if (! ATTR_IND_SIMPLIFIED_P (exp))
2087 return copy_rtx_unchanging (exp);
2088 return exp;
2090 else
2091 return newexp;
2094 /* This routine is called when an AND of a term with a tree of AND's is
2095 encountered. If the term or its complement is present in the tree, it
2096 can be replaced with TRUE or FALSE, respectively.
2098 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2099 be true and hence are complementary.
2101 There is one special case: If we see
2102 (and (not (eq_attr "att" "v1"))
2103 (eq_attr "att" "v2"))
2104 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2105 replace the term, not anything in the AND tree. So we pass a pointer to
2106 the term. */
2108 static rtx
2109 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2111 rtx left, right;
2112 rtx newexp;
2113 rtx temp;
2114 int left_eliminates_term, right_eliminates_term;
2116 if (GET_CODE (exp) == AND)
2118 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2119 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2120 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2122 newexp = attr_rtx (AND, left, right);
2124 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2128 else if (GET_CODE (exp) == IOR)
2130 /* For the IOR case, we do the same as above, except that we can
2131 only eliminate `term' if both sides of the IOR would do so. */
2132 temp = *pterm;
2133 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2134 left_eliminates_term = (temp == true_rtx);
2136 temp = *pterm;
2137 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2138 right_eliminates_term = (temp == true_rtx);
2140 if (left_eliminates_term && right_eliminates_term)
2141 *pterm = true_rtx;
2143 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2145 newexp = attr_rtx (IOR, left, right);
2147 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2151 /* Check for simplifications. Do some extra checking here since this
2152 routine is called so many times. */
2154 if (exp == *pterm)
2155 return true_rtx;
2157 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2158 return false_rtx;
2160 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2161 return false_rtx;
2163 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2165 if (attr_alt_subset_p (*pterm, exp))
2166 return true_rtx;
2168 if (attr_alt_subset_of_compl_p (*pterm, exp))
2169 return false_rtx;
2171 if (attr_alt_subset_p (exp, *pterm))
2172 *pterm = true_rtx;
2174 return exp;
2177 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2179 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2180 return exp;
2182 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2183 return true_rtx;
2184 else
2185 return false_rtx;
2188 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2189 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2191 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2192 return exp;
2194 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2195 return false_rtx;
2196 else
2197 return true_rtx;
2200 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2201 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2203 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2204 return exp;
2206 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2207 return false_rtx;
2208 else
2209 *pterm = true_rtx;
2212 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2214 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2215 return true_rtx;
2218 else if (GET_CODE (exp) == NOT)
2220 if (attr_equal_p (XEXP (exp, 0), *pterm))
2221 return false_rtx;
2224 else if (GET_CODE (*pterm) == NOT)
2226 if (attr_equal_p (XEXP (*pterm, 0), exp))
2227 return false_rtx;
2230 else if (attr_equal_p (exp, *pterm))
2231 return true_rtx;
2233 return exp;
2236 /* Similar to `simplify_and_tree', but for IOR trees. */
2238 static rtx
2239 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2241 rtx left, right;
2242 rtx newexp;
2243 rtx temp;
2244 int left_eliminates_term, right_eliminates_term;
2246 if (GET_CODE (exp) == IOR)
2248 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2249 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2250 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2252 newexp = attr_rtx (GET_CODE (exp), left, right);
2254 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2258 else if (GET_CODE (exp) == AND)
2260 /* For the AND case, we do the same as above, except that we can
2261 only eliminate `term' if both sides of the AND would do so. */
2262 temp = *pterm;
2263 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2264 left_eliminates_term = (temp == false_rtx);
2266 temp = *pterm;
2267 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2268 right_eliminates_term = (temp == false_rtx);
2270 if (left_eliminates_term && right_eliminates_term)
2271 *pterm = false_rtx;
2273 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2275 newexp = attr_rtx (GET_CODE (exp), left, right);
2277 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2281 if (attr_equal_p (exp, *pterm))
2282 return false_rtx;
2284 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2285 return true_rtx;
2287 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2288 return true_rtx;
2290 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2291 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2292 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2293 *pterm = false_rtx;
2295 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2296 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2297 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2298 return false_rtx;
2300 return exp;
2303 /* Compute approximate cost of the expression. Used to decide whether
2304 expression is cheap enough for inline. */
2305 static int
2306 attr_rtx_cost (rtx x)
2308 int cost = 0;
2309 enum rtx_code code;
2310 if (!x)
2311 return 0;
2312 code = GET_CODE (x);
2313 switch (code)
2315 case MATCH_OPERAND:
2316 if (XSTR (x, 1)[0])
2317 return 10;
2318 else
2319 return 0;
2321 case EQ_ATTR_ALT:
2322 return 0;
2324 case EQ_ATTR:
2325 /* Alternatives don't result into function call. */
2326 if (!strcmp_check (XSTR (x, 0), alternative_name))
2327 return 0;
2328 else
2329 return 5;
2330 default:
2332 int i, j;
2333 const char *fmt = GET_RTX_FORMAT (code);
2334 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2336 switch (fmt[i])
2338 case 'V':
2339 case 'E':
2340 for (j = 0; j < XVECLEN (x, i); j++)
2341 cost += attr_rtx_cost (XVECEXP (x, i, j));
2342 break;
2343 case 'e':
2344 cost += attr_rtx_cost (XEXP (x, i));
2345 break;
2349 break;
2351 return cost;
2354 /* Simplify test expression and use temporary obstack in order to avoid
2355 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2356 and avoid unnecessary copying if possible. */
2358 static rtx
2359 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2361 rtx x;
2362 struct obstack *old;
2363 if (ATTR_IND_SIMPLIFIED_P (exp))
2364 return exp;
2365 old = rtl_obstack;
2366 rtl_obstack = temp_obstack;
2367 x = simplify_test_exp (exp, insn_code, insn_index);
2368 rtl_obstack = old;
2369 if (x == exp || rtl_obstack == temp_obstack)
2370 return x;
2371 return attr_copy_rtx (x);
2374 /* Returns true if S1 is a subset of S2. */
2376 static bool
2377 attr_alt_subset_p (rtx s1, rtx s2)
2379 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2381 case (0 << 1) | 0:
2382 return !(XINT (s1, 0) &~ XINT (s2, 0));
2384 case (0 << 1) | 1:
2385 return !(XINT (s1, 0) & XINT (s2, 0));
2387 case (1 << 1) | 0:
2388 return false;
2390 case (1 << 1) | 1:
2391 return !(XINT (s2, 0) &~ XINT (s1, 0));
2393 default:
2394 gcc_unreachable ();
2398 /* Returns true if S1 is a subset of complement of S2. */
2400 static bool
2401 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2403 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2405 case (0 << 1) | 0:
2406 return !(XINT (s1, 0) & XINT (s2, 0));
2408 case (0 << 1) | 1:
2409 return !(XINT (s1, 0) & ~XINT (s2, 0));
2411 case (1 << 1) | 0:
2412 return !(XINT (s2, 0) &~ XINT (s1, 0));
2414 case (1 << 1) | 1:
2415 return false;
2417 default:
2418 gcc_unreachable ();
2422 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2424 static rtx
2425 attr_alt_intersection (rtx s1, rtx s2)
2427 rtx result = rtx_alloc (EQ_ATTR_ALT);
2429 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2431 case (0 << 1) | 0:
2432 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2433 break;
2434 case (0 << 1) | 1:
2435 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2436 break;
2437 case (1 << 1) | 0:
2438 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2439 break;
2440 case (1 << 1) | 1:
2441 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2442 break;
2443 default:
2444 gcc_unreachable ();
2446 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2448 return result;
2451 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2453 static rtx
2454 attr_alt_union (rtx s1, rtx s2)
2456 rtx result = rtx_alloc (EQ_ATTR_ALT);
2458 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2460 case (0 << 1) | 0:
2461 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2462 break;
2463 case (0 << 1) | 1:
2464 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2465 break;
2466 case (1 << 1) | 0:
2467 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2468 break;
2469 case (1 << 1) | 1:
2470 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2471 break;
2472 default:
2473 gcc_unreachable ();
2476 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2477 return result;
2480 /* Return EQ_ATTR_ALT expression representing complement of S. */
2482 static rtx
2483 attr_alt_complement (rtx s)
2485 rtx result = rtx_alloc (EQ_ATTR_ALT);
2487 XINT (result, 0) = XINT (s, 0);
2488 XINT (result, 1) = 1 - XINT (s, 1);
2490 return result;
2493 /* Tests whether a bit B belongs to the set represented by S. */
2495 static bool
2496 attr_alt_bit_p (rtx s, int b)
2498 return XINT (s, 1) ^ ((XINT (s, 0) >> b) & 1);
2501 /* Return EQ_ATTR_ALT expression representing set containing elements set
2502 in E. */
2504 static rtx
2505 mk_attr_alt (int e)
2507 rtx result = rtx_alloc (EQ_ATTR_ALT);
2509 XINT (result, 0) = e;
2510 XINT (result, 1) = 0;
2512 return result;
2515 /* Given an expression, see if it can be simplified for a particular insn
2516 code based on the values of other attributes being tested. This can
2517 eliminate nested get_attr_... calls.
2519 Note that if an endless recursion is specified in the patterns, the
2520 optimization will loop. However, it will do so in precisely the cases where
2521 an infinite recursion loop could occur during compilation. It's better that
2522 it occurs here! */
2524 static rtx
2525 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2527 rtx left, right;
2528 struct attr_desc *attr;
2529 struct attr_value *av;
2530 struct insn_ent *ie;
2531 int i;
2532 rtx newexp = exp;
2533 bool left_alt, right_alt;
2535 /* Don't re-simplify something we already simplified. */
2536 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2537 return exp;
2539 switch (GET_CODE (exp))
2541 case AND:
2542 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2543 SIMPLIFY_ALTERNATIVE (left);
2544 if (left == false_rtx)
2545 return false_rtx;
2546 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2547 SIMPLIFY_ALTERNATIVE (right);
2548 if (left == false_rtx)
2549 return false_rtx;
2551 if (GET_CODE (left) == EQ_ATTR_ALT
2552 && GET_CODE (right) == EQ_ATTR_ALT)
2554 exp = attr_alt_intersection (left, right);
2555 return simplify_test_exp (exp, insn_code, insn_index);
2558 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2559 present on both sides, apply the distributive law since this will
2560 yield simplifications. */
2561 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2562 && compute_alternative_mask (left, IOR)
2563 && compute_alternative_mask (right, IOR))
2565 if (GET_CODE (left) == IOR)
2567 rtx tem = left;
2568 left = right;
2569 right = tem;
2572 newexp = attr_rtx (IOR,
2573 attr_rtx (AND, left, XEXP (right, 0)),
2574 attr_rtx (AND, left, XEXP (right, 1)));
2576 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2579 /* Try with the term on both sides. */
2580 right = simplify_and_tree (right, &left, insn_code, insn_index);
2581 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2582 left = simplify_and_tree (left, &right, insn_code, insn_index);
2584 if (left == false_rtx || right == false_rtx)
2585 return false_rtx;
2586 else if (left == true_rtx)
2588 return right;
2590 else if (right == true_rtx)
2592 return left;
2594 /* See if all or all but one of the insn's alternatives are specified
2595 in this tree. Optimize if so. */
2597 if (GET_CODE (left) == NOT)
2598 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2599 && XSTR (XEXP (left, 0), 0) == alternative_name);
2600 else
2601 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2602 && XINT (left, 1));
2604 if (GET_CODE (right) == NOT)
2605 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2606 && XSTR (XEXP (right, 0), 0) == alternative_name);
2607 else
2608 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2609 && XINT (right, 1));
2611 if (insn_code >= 0
2612 && (GET_CODE (left) == AND
2613 || left_alt
2614 || GET_CODE (right) == AND
2615 || right_alt))
2617 i = compute_alternative_mask (exp, AND);
2618 if (i & ~insn_alternatives[insn_code])
2619 fatal ("invalid alternative specified for pattern number %d",
2620 insn_index);
2622 /* If all alternatives are excluded, this is false. */
2623 i ^= insn_alternatives[insn_code];
2624 if (i == 0)
2625 return false_rtx;
2626 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2628 /* If just one excluded, AND a comparison with that one to the
2629 front of the tree. The others will be eliminated by
2630 optimization. We do not want to do this if the insn has one
2631 alternative and we have tested none of them! */
2632 left = make_alternative_compare (i);
2633 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2634 newexp = attr_rtx (AND, left, right);
2636 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2640 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2642 newexp = attr_rtx (AND, left, right);
2643 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2645 break;
2647 case IOR:
2648 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2649 SIMPLIFY_ALTERNATIVE (left);
2650 if (left == true_rtx)
2651 return true_rtx;
2652 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2653 SIMPLIFY_ALTERNATIVE (right);
2654 if (right == true_rtx)
2655 return true_rtx;
2657 if (GET_CODE (left) == EQ_ATTR_ALT
2658 && GET_CODE (right) == EQ_ATTR_ALT)
2660 exp = attr_alt_union (left, right);
2661 return simplify_test_exp (exp, insn_code, insn_index);
2664 right = simplify_or_tree (right, &left, insn_code, insn_index);
2665 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2666 left = simplify_or_tree (left, &right, insn_code, insn_index);
2668 if (right == true_rtx || left == true_rtx)
2669 return true_rtx;
2670 else if (left == false_rtx)
2672 return right;
2674 else if (right == false_rtx)
2676 return left;
2679 /* Test for simple cases where the distributive law is useful. I.e.,
2680 convert (ior (and (x) (y))
2681 (and (x) (z)))
2682 to (and (x)
2683 (ior (y) (z)))
2686 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2687 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2689 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2691 left = XEXP (left, 0);
2692 right = newexp;
2693 newexp = attr_rtx (AND, left, right);
2694 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2697 /* See if all or all but one of the insn's alternatives are specified
2698 in this tree. Optimize if so. */
2700 else if (insn_code >= 0
2701 && (GET_CODE (left) == IOR
2702 || (GET_CODE (left) == EQ_ATTR_ALT
2703 && !XINT (left, 1))
2704 || (GET_CODE (left) == EQ_ATTR
2705 && XSTR (left, 0) == alternative_name)
2706 || GET_CODE (right) == IOR
2707 || (GET_CODE (right) == EQ_ATTR_ALT
2708 && !XINT (right, 1))
2709 || (GET_CODE (right) == EQ_ATTR
2710 && XSTR (right, 0) == alternative_name)))
2712 i = compute_alternative_mask (exp, IOR);
2713 if (i & ~insn_alternatives[insn_code])
2714 fatal ("invalid alternative specified for pattern number %d",
2715 insn_index);
2717 /* If all alternatives are included, this is true. */
2718 i ^= insn_alternatives[insn_code];
2719 if (i == 0)
2720 return true_rtx;
2721 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2723 /* If just one excluded, IOR a comparison with that one to the
2724 front of the tree. The others will be eliminated by
2725 optimization. We do not want to do this if the insn has one
2726 alternative and we have tested none of them! */
2727 left = make_alternative_compare (i);
2728 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2729 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2731 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2735 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2737 newexp = attr_rtx (IOR, left, right);
2738 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2740 break;
2742 case NOT:
2743 if (GET_CODE (XEXP (exp, 0)) == NOT)
2745 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2746 insn_code, insn_index);
2747 SIMPLIFY_ALTERNATIVE (left);
2748 return left;
2751 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2752 SIMPLIFY_ALTERNATIVE (left);
2753 if (GET_CODE (left) == NOT)
2754 return XEXP (left, 0);
2756 if (left == false_rtx)
2757 return true_rtx;
2758 if (left == true_rtx)
2759 return false_rtx;
2761 if (GET_CODE (left) == EQ_ATTR_ALT)
2763 exp = attr_alt_complement (left);
2764 return simplify_test_exp (exp, insn_code, insn_index);
2767 /* Try to apply De`Morgan's laws. */
2768 if (GET_CODE (left) == IOR)
2770 newexp = attr_rtx (AND,
2771 attr_rtx (NOT, XEXP (left, 0)),
2772 attr_rtx (NOT, XEXP (left, 1)));
2774 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2776 else if (GET_CODE (left) == AND)
2778 newexp = attr_rtx (IOR,
2779 attr_rtx (NOT, XEXP (left, 0)),
2780 attr_rtx (NOT, XEXP (left, 1)));
2782 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2784 else if (left != XEXP (exp, 0))
2786 newexp = attr_rtx (NOT, left);
2788 break;
2790 case EQ_ATTR_ALT:
2791 if (current_alternative_string)
2792 return attr_alt_bit_p (exp, atoi (current_alternative_string)) ? true_rtx : false_rtx;
2794 if (!XINT (exp, 0))
2795 return XINT (exp, 1) ? true_rtx : false_rtx;
2796 break;
2798 case EQ_ATTR:
2799 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
2800 return (XSTR (exp, 1) == current_alternative_string
2801 ? true_rtx : false_rtx);
2803 if (XSTR (exp, 0) == alternative_name)
2805 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2806 break;
2809 /* Look at the value for this insn code in the specified attribute.
2810 We normally can replace this comparison with the condition that
2811 would give this insn the values being tested for. */
2812 if (XSTR (exp, 0) != alternative_name
2813 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2814 for (av = attr->first_value; av; av = av->next)
2815 for (ie = av->first_insn; ie; ie = ie->next)
2816 if (ie->def->insn_code == insn_code)
2818 rtx x;
2819 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2820 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2821 if (attr_rtx_cost(x) < 20)
2822 return x;
2824 break;
2826 default:
2827 break;
2830 /* We have already simplified this expression. Simplifying it again
2831 won't buy anything unless we weren't given a valid insn code
2832 to process (i.e., we are canonicalizing something.). */
2833 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
2834 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2835 return copy_rtx_unchanging (newexp);
2837 return newexp;
2840 /* Optimize the attribute lists by seeing if we can determine conditional
2841 values from the known values of other attributes. This will save subroutine
2842 calls during the compilation. */
2844 static void
2845 optimize_attrs (void)
2847 struct attr_desc *attr;
2848 struct attr_value *av;
2849 struct insn_ent *ie;
2850 rtx newexp;
2851 int i;
2852 struct attr_value_list
2854 struct attr_value *av;
2855 struct insn_ent *ie;
2856 struct attr_desc *attr;
2857 struct attr_value_list *next;
2859 struct attr_value_list **insn_code_values;
2860 struct attr_value_list *ivbuf;
2861 struct attr_value_list *iv;
2863 /* For each insn code, make a list of all the insn_ent's for it,
2864 for all values for all attributes. */
2866 if (num_insn_ents == 0)
2867 return;
2869 /* Make 2 extra elements, for "code" values -2 and -1. */
2870 insn_code_values = xcalloc ((insn_code_number + 2),
2871 sizeof (struct attr_value_list *));
2873 /* Offset the table address so we can index by -2 or -1. */
2874 insn_code_values += 2;
2876 iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
2878 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2879 for (attr = attrs[i]; attr; attr = attr->next)
2880 for (av = attr->first_value; av; av = av->next)
2881 for (ie = av->first_insn; ie; ie = ie->next)
2883 iv->attr = attr;
2884 iv->av = av;
2885 iv->ie = ie;
2886 iv->next = insn_code_values[ie->def->insn_code];
2887 insn_code_values[ie->def->insn_code] = iv;
2888 iv++;
2891 /* Sanity check on num_insn_ents. */
2892 gcc_assert (iv == ivbuf + num_insn_ents);
2894 /* Process one insn code at a time. */
2895 for (i = -2; i < insn_code_number; i++)
2897 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2898 We use it to mean "already simplified for this insn". */
2899 for (iv = insn_code_values[i]; iv; iv = iv->next)
2900 clear_struct_flag (iv->av->value);
2902 for (iv = insn_code_values[i]; iv; iv = iv->next)
2904 struct obstack *old = rtl_obstack;
2906 attr = iv->attr;
2907 av = iv->av;
2908 ie = iv->ie;
2909 if (GET_CODE (av->value) != COND)
2910 continue;
2912 rtl_obstack = temp_obstack;
2913 newexp = av->value;
2914 while (GET_CODE (newexp) == COND)
2916 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2917 ie->def->insn_index);
2918 if (newexp2 == newexp)
2919 break;
2920 newexp = newexp2;
2923 rtl_obstack = old;
2924 if (newexp != av->value)
2926 newexp = attr_copy_rtx (newexp);
2927 remove_insn_ent (av, ie);
2928 av = get_attr_value (newexp, attr, ie->def->insn_code);
2929 iv->av = av;
2930 insert_insn_ent (av, ie);
2935 free (ivbuf);
2936 free (insn_code_values - 2);
2939 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2941 static void
2942 clear_struct_flag (rtx x)
2944 int i;
2945 int j;
2946 enum rtx_code code;
2947 const char *fmt;
2949 ATTR_CURR_SIMPLIFIED_P (x) = 0;
2950 if (ATTR_IND_SIMPLIFIED_P (x))
2951 return;
2953 code = GET_CODE (x);
2955 switch (code)
2957 case REG:
2958 case CONST_INT:
2959 case CONST_DOUBLE:
2960 case CONST_VECTOR:
2961 case SYMBOL_REF:
2962 case CODE_LABEL:
2963 case PC:
2964 case CC0:
2965 case EQ_ATTR:
2966 case ATTR_FLAG:
2967 return;
2969 default:
2970 break;
2973 /* Compare the elements. If any pair of corresponding elements
2974 fail to match, return 0 for the whole things. */
2976 fmt = GET_RTX_FORMAT (code);
2977 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2979 switch (fmt[i])
2981 case 'V':
2982 case 'E':
2983 for (j = 0; j < XVECLEN (x, i); j++)
2984 clear_struct_flag (XVECEXP (x, i, j));
2985 break;
2987 case 'e':
2988 clear_struct_flag (XEXP (x, i));
2989 break;
2994 /* Create table entries for DEFINE_ATTR. */
2996 static void
2997 gen_attr (rtx exp, int lineno)
2999 struct attr_desc *attr;
3000 struct attr_value *av;
3001 const char *name_ptr;
3002 char *p;
3004 /* Make a new attribute structure. Check for duplicate by looking at
3005 attr->default_val, since it is initialized by this routine. */
3006 attr = find_attr (&XSTR (exp, 0), 1);
3007 if (attr->default_val)
3009 message_with_line (lineno, "duplicate definition for attribute %s",
3010 attr->name);
3011 message_with_line (attr->lineno, "previous definition");
3012 have_error = 1;
3013 return;
3015 attr->lineno = lineno;
3017 if (*XSTR (exp, 1) == '\0')
3018 attr->is_numeric = 1;
3019 else
3021 name_ptr = XSTR (exp, 1);
3022 while ((p = next_comma_elt (&name_ptr)) != NULL)
3024 av = oballoc (sizeof (struct attr_value));
3025 av->value = attr_rtx (CONST_STRING, p);
3026 av->next = attr->first_value;
3027 attr->first_value = av;
3028 av->first_insn = NULL;
3029 av->num_insns = 0;
3030 av->has_asm_insn = 0;
3034 if (GET_CODE (XEXP (exp, 2)) == CONST)
3036 attr->is_const = 1;
3037 if (attr->is_numeric)
3039 message_with_line (lineno,
3040 "constant attributes may not take numeric values");
3041 have_error = 1;
3044 /* Get rid of the CONST node. It is allowed only at top-level. */
3045 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3048 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3050 message_with_line (lineno,
3051 "`length' attribute must take numeric values");
3052 have_error = 1;
3055 /* Set up the default value. */
3056 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3057 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3060 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3061 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3062 number of alternatives as this should be checked elsewhere. */
3064 static int
3065 count_alternatives (rtx exp)
3067 int i, j, n;
3068 const char *fmt;
3070 if (GET_CODE (exp) == MATCH_OPERAND)
3071 return n_comma_elts (XSTR (exp, 2));
3073 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3074 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3075 switch (*fmt++)
3077 case 'e':
3078 case 'u':
3079 n = count_alternatives (XEXP (exp, i));
3080 if (n)
3081 return n;
3082 break;
3084 case 'E':
3085 case 'V':
3086 if (XVEC (exp, i) != NULL)
3087 for (j = 0; j < XVECLEN (exp, i); j++)
3089 n = count_alternatives (XVECEXP (exp, i, j));
3090 if (n)
3091 return n;
3095 return 0;
3098 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3099 `alternative' attribute. */
3101 static int
3102 compares_alternatives_p (rtx exp)
3104 int i, j;
3105 const char *fmt;
3107 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3108 return 1;
3110 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3111 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3112 switch (*fmt++)
3114 case 'e':
3115 case 'u':
3116 if (compares_alternatives_p (XEXP (exp, i)))
3117 return 1;
3118 break;
3120 case 'E':
3121 for (j = 0; j < XVECLEN (exp, i); j++)
3122 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3123 return 1;
3124 break;
3127 return 0;
3130 /* Returns nonzero is INNER is contained in EXP. */
3132 static int
3133 contained_in_p (rtx inner, rtx exp)
3135 int i, j;
3136 const char *fmt;
3138 if (rtx_equal_p (inner, exp))
3139 return 1;
3141 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3142 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3143 switch (*fmt++)
3145 case 'e':
3146 case 'u':
3147 if (contained_in_p (inner, XEXP (exp, i)))
3148 return 1;
3149 break;
3151 case 'E':
3152 for (j = 0; j < XVECLEN (exp, i); j++)
3153 if (contained_in_p (inner, XVECEXP (exp, i, j)))
3154 return 1;
3155 break;
3158 return 0;
3161 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3163 static void
3164 gen_insn (rtx exp, int lineno)
3166 struct insn_def *id;
3168 id = oballoc (sizeof (struct insn_def));
3169 id->next = defs;
3170 defs = id;
3171 id->def = exp;
3172 id->lineno = lineno;
3174 switch (GET_CODE (exp))
3176 case DEFINE_INSN:
3177 id->insn_code = insn_code_number;
3178 id->insn_index = insn_index_number;
3179 id->num_alternatives = count_alternatives (exp);
3180 if (id->num_alternatives == 0)
3181 id->num_alternatives = 1;
3182 id->vec_idx = 4;
3183 break;
3185 case DEFINE_PEEPHOLE:
3186 id->insn_code = insn_code_number;
3187 id->insn_index = insn_index_number;
3188 id->num_alternatives = count_alternatives (exp);
3189 if (id->num_alternatives == 0)
3190 id->num_alternatives = 1;
3191 id->vec_idx = 3;
3192 break;
3194 case DEFINE_ASM_ATTRIBUTES:
3195 id->insn_code = -1;
3196 id->insn_index = -1;
3197 id->num_alternatives = 1;
3198 id->vec_idx = 0;
3199 got_define_asm_attributes = 1;
3200 break;
3202 default:
3203 gcc_unreachable ();
3207 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3208 true or annul false is specified, and make a `struct delay_desc'. */
3210 static void
3211 gen_delay (rtx def, int lineno)
3213 struct delay_desc *delay;
3214 int i;
3216 if (XVECLEN (def, 1) % 3 != 0)
3218 message_with_line (lineno,
3219 "number of elements in DEFINE_DELAY must be multiple of three");
3220 have_error = 1;
3221 return;
3224 for (i = 0; i < XVECLEN (def, 1); i += 3)
3226 if (XVECEXP (def, 1, i + 1))
3227 have_annul_true = 1;
3228 if (XVECEXP (def, 1, i + 2))
3229 have_annul_false = 1;
3232 delay = oballoc (sizeof (struct delay_desc));
3233 delay->def = def;
3234 delay->num = ++num_delays;
3235 delay->next = delays;
3236 delay->lineno = lineno;
3237 delays = delay;
3240 /* Given a piece of RTX, print a C expression to test its truth value.
3241 We use AND and IOR both for logical and bit-wise operations, so
3242 interpret them as logical unless they are inside a comparison expression.
3243 The first bit of FLAGS will be nonzero in that case.
3245 Set the second bit of FLAGS to make references to attribute values use
3246 a cached local variable instead of calling a function. */
3248 static void
3249 write_test_expr (rtx exp, int flags)
3251 int comparison_operator = 0;
3252 RTX_CODE code;
3253 struct attr_desc *attr;
3255 /* In order not to worry about operator precedence, surround our part of
3256 the expression with parentheses. */
3258 printf ("(");
3259 code = GET_CODE (exp);
3260 switch (code)
3262 /* Binary operators. */
3263 case GEU: case GTU:
3264 case LEU: case LTU:
3265 printf ("(unsigned) ");
3266 /* Fall through. */
3268 case EQ: case NE:
3269 case GE: case GT:
3270 case LE: case LT:
3271 comparison_operator = 1;
3273 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3274 case AND: case IOR: case XOR:
3275 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3276 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
3277 switch (code)
3279 case EQ:
3280 printf (" == ");
3281 break;
3282 case NE:
3283 printf (" != ");
3284 break;
3285 case GE:
3286 printf (" >= ");
3287 break;
3288 case GT:
3289 printf (" > ");
3290 break;
3291 case GEU:
3292 printf (" >= (unsigned) ");
3293 break;
3294 case GTU:
3295 printf (" > (unsigned) ");
3296 break;
3297 case LE:
3298 printf (" <= ");
3299 break;
3300 case LT:
3301 printf (" < ");
3302 break;
3303 case LEU:
3304 printf (" <= (unsigned) ");
3305 break;
3306 case LTU:
3307 printf (" < (unsigned) ");
3308 break;
3309 case PLUS:
3310 printf (" + ");
3311 break;
3312 case MINUS:
3313 printf (" - ");
3314 break;
3315 case MULT:
3316 printf (" * ");
3317 break;
3318 case DIV:
3319 printf (" / ");
3320 break;
3321 case MOD:
3322 printf (" %% ");
3323 break;
3324 case AND:
3325 if (flags & 1)
3326 printf (" & ");
3327 else
3328 printf (" && ");
3329 break;
3330 case IOR:
3331 if (flags & 1)
3332 printf (" | ");
3333 else
3334 printf (" || ");
3335 break;
3336 case XOR:
3337 printf (" ^ ");
3338 break;
3339 case ASHIFT:
3340 printf (" << ");
3341 break;
3342 case LSHIFTRT:
3343 case ASHIFTRT:
3344 printf (" >> ");
3345 break;
3346 default:
3347 gcc_unreachable ();
3350 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
3351 break;
3353 case NOT:
3354 /* Special-case (not (eq_attrq "alternative" "x")) */
3355 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3356 && XSTR (XEXP (exp, 0), 0) == alternative_name)
3358 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3359 break;
3362 /* Otherwise, fall through to normal unary operator. */
3364 /* Unary operators. */
3365 case ABS: case NEG:
3366 switch (code)
3368 case NOT:
3369 if (flags & 1)
3370 printf ("~ ");
3371 else
3372 printf ("! ");
3373 break;
3374 case ABS:
3375 printf ("abs ");
3376 break;
3377 case NEG:
3378 printf ("-");
3379 break;
3380 default:
3381 gcc_unreachable ();
3384 write_test_expr (XEXP (exp, 0), flags);
3385 break;
3387 case EQ_ATTR_ALT:
3389 int set = XINT (exp, 0), bit = 0;
3391 if (flags & 1)
3392 fatal ("EQ_ATTR_ALT not valid inside comparison");
3394 if (!set)
3395 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3397 if (!(set & (set - 1)))
3399 if (!(set & 0xffff))
3401 bit += 16;
3402 set >>= 16;
3404 if (!(set & 0xff))
3406 bit += 8;
3407 set >>= 8;
3409 if (!(set & 0xf))
3411 bit += 4;
3412 set >>= 4;
3414 if (!(set & 0x3))
3416 bit += 2;
3417 set >>= 2;
3419 if (!(set & 1))
3420 bit++;
3422 printf ("which_alternative %s= %d",
3423 XINT (exp, 1) ? "!" : "=", bit);
3425 else
3427 printf ("%s((1 << which_alternative) & 0x%x)",
3428 XINT (exp, 1) ? "!" : "", set);
3431 break;
3433 /* Comparison test of an attribute with a value. Most of these will
3434 have been removed by optimization. Handle "alternative"
3435 specially and give error if EQ_ATTR present inside a comparison. */
3436 case EQ_ATTR:
3437 if (flags & 1)
3438 fatal ("EQ_ATTR not valid inside comparison");
3440 if (XSTR (exp, 0) == alternative_name)
3442 printf ("which_alternative == %s", XSTR (exp, 1));
3443 break;
3446 attr = find_attr (&XSTR (exp, 0), 0);
3447 gcc_assert (attr);
3449 /* Now is the time to expand the value of a constant attribute. */
3450 if (attr->is_const)
3452 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
3453 -2, -2),
3454 flags);
3456 else
3458 if (flags & 2)
3459 printf ("attr_%s", attr->name);
3460 else
3461 printf ("get_attr_%s (insn)", attr->name);
3462 printf (" == ");
3463 write_attr_valueq (attr, XSTR (exp, 1));
3465 break;
3467 /* Comparison test of flags for define_delays. */
3468 case ATTR_FLAG:
3469 if (flags & 1)
3470 fatal ("ATTR_FLAG not valid inside comparison");
3471 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3472 break;
3474 /* See if an operand matches a predicate. */
3475 case MATCH_OPERAND:
3476 /* If only a mode is given, just ensure the mode matches the operand.
3477 If neither a mode nor predicate is given, error. */
3478 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3480 if (GET_MODE (exp) == VOIDmode)
3481 fatal ("null MATCH_OPERAND specified as test");
3482 else
3483 printf ("GET_MODE (operands[%d]) == %smode",
3484 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3486 else
3487 printf ("%s (operands[%d], %smode)",
3488 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3489 break;
3491 /* Constant integer. */
3492 case CONST_INT:
3493 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3494 break;
3496 /* A random C expression. */
3497 case SYMBOL_REF:
3498 print_c_condition (XSTR (exp, 0));
3499 break;
3501 /* The address of the branch target. */
3502 case MATCH_DUP:
3503 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3504 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3505 break;
3507 case PC:
3508 /* The address of the current insn. We implement this actually as the
3509 address of the current insn for backward branches, but the last
3510 address of the next insn for forward branches, and both with
3511 adjustments that account for the worst-case possible stretching of
3512 intervening alignments between this insn and its destination. */
3513 printf ("insn_current_reference_address (insn)");
3514 break;
3516 case CONST_STRING:
3517 printf ("%s", XSTR (exp, 0));
3518 break;
3520 case IF_THEN_ELSE:
3521 write_test_expr (XEXP (exp, 0), flags & 2);
3522 printf (" ? ");
3523 write_test_expr (XEXP (exp, 1), flags | 1);
3524 printf (" : ");
3525 write_test_expr (XEXP (exp, 2), flags | 1);
3526 break;
3528 default:
3529 fatal ("bad RTX code `%s' in attribute calculation\n",
3530 GET_RTX_NAME (code));
3533 printf (")");
3536 /* Given an attribute value, return the maximum CONST_STRING argument
3537 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3539 static int
3540 max_attr_value (rtx exp, int *unknownp)
3542 int current_max;
3543 int i, n;
3545 switch (GET_CODE (exp))
3547 case CONST_STRING:
3548 current_max = atoi (XSTR (exp, 0));
3549 break;
3551 case COND:
3552 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3553 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3555 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3556 if (n > current_max)
3557 current_max = n;
3559 break;
3561 case IF_THEN_ELSE:
3562 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3563 n = max_attr_value (XEXP (exp, 2), unknownp);
3564 if (n > current_max)
3565 current_max = n;
3566 break;
3568 default:
3569 *unknownp = 1;
3570 current_max = INT_MAX;
3571 break;
3574 return current_max;
3577 /* Given an attribute value, return the result of ORing together all
3578 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3579 if the numeric value is not known. */
3581 static int
3582 or_attr_value (rtx exp, int *unknownp)
3584 int current_or;
3585 int i;
3587 switch (GET_CODE (exp))
3589 case CONST_STRING:
3590 current_or = atoi (XSTR (exp, 0));
3591 break;
3593 case COND:
3594 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3595 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3596 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3597 break;
3599 case IF_THEN_ELSE:
3600 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3601 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3602 break;
3604 default:
3605 *unknownp = 1;
3606 current_or = -1;
3607 break;
3610 return current_or;
3613 /* Scan an attribute value, possibly a conditional, and record what actions
3614 will be required to do any conditional tests in it.
3616 Specifically, set
3617 `must_extract' if we need to extract the insn operands
3618 `must_constrain' if we must compute `which_alternative'
3619 `address_used' if an address expression was used
3620 `length_used' if an (eq_attr "length" ...) was used
3623 static void
3624 walk_attr_value (rtx exp)
3626 int i, j;
3627 const char *fmt;
3628 RTX_CODE code;
3630 if (exp == NULL)
3631 return;
3633 code = GET_CODE (exp);
3634 switch (code)
3636 case SYMBOL_REF:
3637 if (! ATTR_IND_SIMPLIFIED_P (exp))
3638 /* Since this is an arbitrary expression, it can look at anything.
3639 However, constant expressions do not depend on any particular
3640 insn. */
3641 must_extract = must_constrain = 1;
3642 return;
3644 case MATCH_OPERAND:
3645 must_extract = 1;
3646 return;
3648 case EQ_ATTR_ALT:
3649 must_extract = must_constrain = 1;
3650 break;
3652 case EQ_ATTR:
3653 if (XSTR (exp, 0) == alternative_name)
3654 must_extract = must_constrain = 1;
3655 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3656 length_used = 1;
3657 return;
3659 case MATCH_DUP:
3660 must_extract = 1;
3661 address_used = 1;
3662 return;
3664 case PC:
3665 address_used = 1;
3666 return;
3668 case ATTR_FLAG:
3669 return;
3671 default:
3672 break;
3675 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3676 switch (*fmt++)
3678 case 'e':
3679 case 'u':
3680 walk_attr_value (XEXP (exp, i));
3681 break;
3683 case 'E':
3684 if (XVEC (exp, i) != NULL)
3685 for (j = 0; j < XVECLEN (exp, i); j++)
3686 walk_attr_value (XVECEXP (exp, i, j));
3687 break;
3691 /* Write out a function to obtain the attribute for a given INSN. */
3693 static void
3694 write_attr_get (struct attr_desc *attr)
3696 struct attr_value *av, *common_av;
3698 /* Find the most used attribute value. Handle that as the `default' of the
3699 switch we will generate. */
3700 common_av = find_most_used (attr);
3702 /* Write out start of function, then all values with explicit `case' lines,
3703 then a `default', then the value with the most uses. */
3704 if (attr->static_p)
3705 printf ("static ");
3706 if (!attr->is_numeric)
3707 printf ("enum attr_%s\n", attr->name);
3708 else
3709 printf ("int\n");
3711 /* If the attribute name starts with a star, the remainder is the name of
3712 the subroutine to use, instead of `get_attr_...'. */
3713 if (attr->name[0] == '*')
3714 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3715 else if (attr->is_const == 0)
3716 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3717 else
3719 printf ("get_attr_%s (void)\n", attr->name);
3720 printf ("{\n");
3722 for (av = attr->first_value; av; av = av->next)
3723 if (av->num_insns != 0)
3724 write_attr_set (attr, 2, av->value, "return", ";",
3725 true_rtx, av->first_insn->def->insn_code,
3726 av->first_insn->def->insn_index);
3728 printf ("}\n\n");
3729 return;
3732 printf ("{\n");
3733 printf (" switch (recog_memoized (insn))\n");
3734 printf (" {\n");
3736 for (av = attr->first_value; av; av = av->next)
3737 if (av != common_av)
3738 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3740 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3741 printf (" }\n}\n\n");
3744 /* Given an AND tree of known true terms (because we are inside an `if' with
3745 that as the condition or are in an `else' clause) and an expression,
3746 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3747 the bulk of the work. */
3749 static rtx
3750 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
3752 rtx term;
3754 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3756 if (GET_CODE (known_true) == AND)
3758 exp = eliminate_known_true (XEXP (known_true, 0), exp,
3759 insn_code, insn_index);
3760 exp = eliminate_known_true (XEXP (known_true, 1), exp,
3761 insn_code, insn_index);
3763 else
3765 term = known_true;
3766 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3769 return exp;
3772 /* Write out a series of tests and assignment statements to perform tests and
3773 sets of an attribute value. We are passed an indentation amount and prefix
3774 and suffix strings to write around each attribute value (e.g., "return"
3775 and ";"). */
3777 static void
3778 write_attr_set (struct attr_desc *attr, int indent, rtx value,
3779 const char *prefix, const char *suffix, rtx known_true,
3780 int insn_code, int insn_index)
3782 if (GET_CODE (value) == COND)
3784 /* Assume the default value will be the default of the COND unless we
3785 find an always true expression. */
3786 rtx default_val = XEXP (value, 1);
3787 rtx our_known_true = known_true;
3788 rtx newexp;
3789 int first_if = 1;
3790 int i;
3792 for (i = 0; i < XVECLEN (value, 0); i += 2)
3794 rtx testexp;
3795 rtx inner_true;
3797 testexp = eliminate_known_true (our_known_true,
3798 XVECEXP (value, 0, i),
3799 insn_code, insn_index);
3800 newexp = attr_rtx (NOT, testexp);
3801 newexp = insert_right_side (AND, our_known_true, newexp,
3802 insn_code, insn_index);
3804 /* If the test expression is always true or if the next `known_true'
3805 expression is always false, this is the last case, so break
3806 out and let this value be the `else' case. */
3807 if (testexp == true_rtx || newexp == false_rtx)
3809 default_val = XVECEXP (value, 0, i + 1);
3810 break;
3813 /* Compute the expression to pass to our recursive call as being
3814 known true. */
3815 inner_true = insert_right_side (AND, our_known_true,
3816 testexp, insn_code, insn_index);
3818 /* If this is always false, skip it. */
3819 if (inner_true == false_rtx)
3820 continue;
3822 write_indent (indent);
3823 printf ("%sif ", first_if ? "" : "else ");
3824 first_if = 0;
3825 write_test_expr (testexp, 0);
3826 printf ("\n");
3827 write_indent (indent + 2);
3828 printf ("{\n");
3830 write_attr_set (attr, indent + 4,
3831 XVECEXP (value, 0, i + 1), prefix, suffix,
3832 inner_true, insn_code, insn_index);
3833 write_indent (indent + 2);
3834 printf ("}\n");
3835 our_known_true = newexp;
3838 if (! first_if)
3840 write_indent (indent);
3841 printf ("else\n");
3842 write_indent (indent + 2);
3843 printf ("{\n");
3846 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3847 prefix, suffix, our_known_true, insn_code, insn_index);
3849 if (! first_if)
3851 write_indent (indent + 2);
3852 printf ("}\n");
3855 else
3857 write_indent (indent);
3858 printf ("%s ", prefix);
3859 write_attr_value (attr, value);
3860 printf ("%s\n", suffix);
3864 /* Write a series of case statements for every instruction in list IE.
3865 INDENT is the amount of indentation to write before each case. */
3867 static void
3868 write_insn_cases (struct insn_ent *ie, int indent)
3870 for (; ie != 0; ie = ie->next)
3871 if (ie->def->insn_code != -1)
3873 write_indent (indent);
3874 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
3875 printf ("case %d: /* define_peephole, line %d */\n",
3876 ie->def->insn_code, ie->def->lineno);
3877 else
3878 printf ("case %d: /* %s */\n",
3879 ie->def->insn_code, XSTR (ie->def->def, 0));
3883 /* Write out the computation for one attribute value. */
3885 static void
3886 write_attr_case (struct attr_desc *attr, struct attr_value *av,
3887 int write_case_lines, const char *prefix, const char *suffix,
3888 int indent, rtx known_true)
3890 if (av->num_insns == 0)
3891 return;
3893 if (av->has_asm_insn)
3895 write_indent (indent);
3896 printf ("case -1:\n");
3897 write_indent (indent + 2);
3898 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3899 write_indent (indent + 2);
3900 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3901 write_indent (indent + 2);
3902 printf (" fatal_insn_not_found (insn);\n");
3905 if (write_case_lines)
3906 write_insn_cases (av->first_insn, indent);
3907 else
3909 write_indent (indent);
3910 printf ("default:\n");
3913 /* See what we have to do to output this value. */
3914 must_extract = must_constrain = address_used = 0;
3915 walk_attr_value (av->value);
3917 if (must_constrain)
3919 write_indent (indent + 2);
3920 printf ("extract_constrain_insn_cached (insn);\n");
3922 else if (must_extract)
3924 write_indent (indent + 2);
3925 printf ("extract_insn_cached (insn);\n");
3928 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3929 known_true, av->first_insn->def->insn_code,
3930 av->first_insn->def->insn_index);
3932 if (strncmp (prefix, "return", 6))
3934 write_indent (indent + 2);
3935 printf ("break;\n");
3937 printf ("\n");
3940 /* Search for uses of non-const attributes and write code to cache them. */
3942 static int
3943 write_expr_attr_cache (rtx p, struct attr_desc *attr)
3945 const char *fmt;
3946 int i, ie, j, je;
3948 if (GET_CODE (p) == EQ_ATTR)
3950 if (XSTR (p, 0) != attr->name)
3951 return 0;
3953 if (!attr->is_numeric)
3954 printf (" enum attr_%s ", attr->name);
3955 else
3956 printf (" int ");
3958 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
3959 return 1;
3962 fmt = GET_RTX_FORMAT (GET_CODE (p));
3963 ie = GET_RTX_LENGTH (GET_CODE (p));
3964 for (i = 0; i < ie; i++)
3966 switch (*fmt++)
3968 case 'e':
3969 if (write_expr_attr_cache (XEXP (p, i), attr))
3970 return 1;
3971 break;
3973 case 'E':
3974 je = XVECLEN (p, i);
3975 for (j = 0; j < je; ++j)
3976 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
3977 return 1;
3978 break;
3982 return 0;
3985 /* Utilities to write in various forms. */
3987 static void
3988 write_attr_valueq (struct attr_desc *attr, const char *s)
3990 if (attr->is_numeric)
3992 int num = atoi (s);
3994 printf ("%d", num);
3996 if (num > 9 || num < 0)
3997 printf (" /* 0x%x */", num);
3999 else
4001 write_upcase (attr->name);
4002 printf ("_");
4003 write_upcase (s);
4007 static void
4008 write_attr_value (struct attr_desc *attr, rtx value)
4010 int op;
4012 switch (GET_CODE (value))
4014 case CONST_STRING:
4015 write_attr_valueq (attr, XSTR (value, 0));
4016 break;
4018 case CONST_INT:
4019 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4020 break;
4022 case SYMBOL_REF:
4023 print_c_condition (XSTR (value, 0));
4024 break;
4026 case ATTR:
4028 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4029 printf ("get_attr_%s (%s)", attr2->name,
4030 (attr2->is_const ? "" : "insn"));
4032 break;
4034 case PLUS:
4035 op = '+';
4036 goto do_operator;
4037 case MINUS:
4038 op = '-';
4039 goto do_operator;
4040 case MULT:
4041 op = '*';
4042 goto do_operator;
4043 case DIV:
4044 op = '/';
4045 goto do_operator;
4046 case MOD:
4047 op = '%';
4048 goto do_operator;
4050 do_operator:
4051 write_attr_value (attr, XEXP (value, 0));
4052 putchar (' ');
4053 putchar (op);
4054 putchar (' ');
4055 write_attr_value (attr, XEXP (value, 1));
4056 break;
4058 default:
4059 gcc_unreachable ();
4063 static void
4064 write_upcase (const char *str)
4066 while (*str)
4068 /* The argument of TOUPPER should not have side effects. */
4069 putchar (TOUPPER(*str));
4070 str++;
4074 static void
4075 write_indent (int indent)
4077 for (; indent > 8; indent -= 8)
4078 printf ("\t");
4080 for (; indent; indent--)
4081 printf (" ");
4084 /* Write a subroutine that is given an insn that requires a delay slot, a
4085 delay slot ordinal, and a candidate insn. It returns nonzero if the
4086 candidate can be placed in the specified delay slot of the insn.
4088 We can write as many as three subroutines. `eligible_for_delay'
4089 handles normal delay slots, `eligible_for_annul_true' indicates that
4090 the specified insn can be annulled if the branch is true, and likewise
4091 for `eligible_for_annul_false'.
4093 KIND is a string distinguishing these three cases ("delay", "annul_true",
4094 or "annul_false"). */
4096 static void
4097 write_eligible_delay (const char *kind)
4099 struct delay_desc *delay;
4100 int max_slots;
4101 char str[50];
4102 const char *pstr;
4103 struct attr_desc *attr;
4104 struct attr_value *av, *common_av;
4105 int i;
4107 /* Compute the maximum number of delay slots required. We use the delay
4108 ordinal times this number plus one, plus the slot number as an index into
4109 the appropriate predicate to test. */
4111 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4112 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4113 max_slots = XVECLEN (delay->def, 1) / 3;
4115 /* Write function prelude. */
4117 printf ("int\n");
4118 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4119 kind);
4120 printf ("{\n");
4121 printf (" rtx insn;\n");
4122 printf ("\n");
4123 printf (" gcc_assert (slot < %d);\n", max_slots);
4124 printf ("\n");
4125 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4126 converts a compound instruction into a loop. */
4127 printf (" if (!INSN_P (candidate_insn))\n");
4128 printf (" return 0;\n");
4129 printf ("\n");
4131 /* If more than one delay type, find out which type the delay insn is. */
4133 if (num_delays > 1)
4135 attr = find_attr (&delay_type_str, 0);
4136 gcc_assert (attr);
4137 common_av = find_most_used (attr);
4139 printf (" insn = delay_insn;\n");
4140 printf (" switch (recog_memoized (insn))\n");
4141 printf (" {\n");
4143 sprintf (str, " * %d;\n break;", max_slots);
4144 for (av = attr->first_value; av; av = av->next)
4145 if (av != common_av)
4146 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4148 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4149 printf (" }\n\n");
4151 /* Ensure matched. Otherwise, shouldn't have been called. */
4152 printf (" gcc_assert (slot >= %d);\n\n", max_slots);
4155 /* If just one type of delay slot, write simple switch. */
4156 if (num_delays == 1 && max_slots == 1)
4158 printf (" insn = candidate_insn;\n");
4159 printf (" switch (recog_memoized (insn))\n");
4160 printf (" {\n");
4162 attr = find_attr (&delay_1_0_str, 0);
4163 gcc_assert (attr);
4164 common_av = find_most_used (attr);
4166 for (av = attr->first_value; av; av = av->next)
4167 if (av != common_av)
4168 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4170 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4171 printf (" }\n");
4174 else
4176 /* Write a nested CASE. The first indicates which condition we need to
4177 test, and the inner CASE tests the condition. */
4178 printf (" insn = candidate_insn;\n");
4179 printf (" switch (slot)\n");
4180 printf (" {\n");
4182 for (delay = delays; delay; delay = delay->next)
4183 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4185 printf (" case %d:\n",
4186 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4187 printf (" switch (recog_memoized (insn))\n");
4188 printf ("\t{\n");
4190 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4191 pstr = str;
4192 attr = find_attr (&pstr, 0);
4193 gcc_assert (attr);
4194 common_av = find_most_used (attr);
4196 for (av = attr->first_value; av; av = av->next)
4197 if (av != common_av)
4198 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4200 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4201 printf (" }\n");
4204 printf (" default:\n");
4205 printf (" gcc_unreachable ();\n");
4206 printf (" }\n");
4209 printf ("}\n\n");
4212 /* This page contains miscellaneous utility routines. */
4214 /* Given a pointer to a (char *), return a malloc'ed string containing the
4215 next comma-separated element. Advance the pointer to after the string
4216 scanned, or the end-of-string. Return NULL if at end of string. */
4218 static char *
4219 next_comma_elt (const char **pstr)
4221 const char *start;
4223 start = scan_comma_elt (pstr);
4225 if (start == NULL)
4226 return NULL;
4228 return attr_string (start, *pstr - start);
4231 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4232 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4233 replaced by a pointer to a canonical copy of the string. */
4235 static struct attr_desc *
4236 find_attr (const char **name_p, int create)
4238 struct attr_desc *attr;
4239 int index;
4240 const char *name = *name_p;
4242 /* Before we resort to using `strcmp', see if the string address matches
4243 anywhere. In most cases, it should have been canonicalized to do so. */
4244 if (name == alternative_name)
4245 return NULL;
4247 index = name[0] & (MAX_ATTRS_INDEX - 1);
4248 for (attr = attrs[index]; attr; attr = attr->next)
4249 if (name == attr->name)
4250 return attr;
4252 /* Otherwise, do it the slow way. */
4253 for (attr = attrs[index]; attr; attr = attr->next)
4254 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4256 *name_p = attr->name;
4257 return attr;
4260 if (! create)
4261 return NULL;
4263 attr = oballoc (sizeof (struct attr_desc));
4264 attr->name = DEF_ATTR_STRING (name);
4265 attr->first_value = attr->default_val = NULL;
4266 attr->is_numeric = attr->is_const = attr->is_special = 0;
4267 attr->static_p = 0;
4268 attr->next = attrs[index];
4269 attrs[index] = attr;
4271 *name_p = attr->name;
4273 return attr;
4276 /* Create internal attribute with the given default value. */
4278 void
4279 make_internal_attr (const char *name, rtx value, int special)
4281 struct attr_desc *attr;
4283 attr = find_attr (&name, 1);
4284 gcc_assert (!attr->default_val);
4286 attr->is_numeric = 1;
4287 attr->is_const = 0;
4288 attr->is_special = (special & ATTR_SPECIAL) != 0;
4289 attr->static_p = (special & ATTR_STATIC) != 0;
4290 attr->default_val = get_attr_value (value, attr, -2);
4293 /* Find the most used value of an attribute. */
4295 static struct attr_value *
4296 find_most_used (struct attr_desc *attr)
4298 struct attr_value *av;
4299 struct attr_value *most_used;
4300 int nuses;
4302 most_used = NULL;
4303 nuses = -1;
4305 for (av = attr->first_value; av; av = av->next)
4306 if (av->num_insns > nuses)
4307 nuses = av->num_insns, most_used = av;
4309 return most_used;
4312 /* Return (attr_value "n") */
4315 make_numeric_value (int n)
4317 static rtx int_values[20];
4318 rtx exp;
4319 char *p;
4321 gcc_assert (n >= 0);
4323 if (n < 20 && int_values[n])
4324 return int_values[n];
4326 p = attr_printf (MAX_DIGITS, "%d", n);
4327 exp = attr_rtx (CONST_STRING, p);
4329 if (n < 20)
4330 int_values[n] = exp;
4332 return exp;
4335 static rtx
4336 copy_rtx_unchanging (rtx orig)
4338 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4339 return orig;
4341 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4342 return orig;
4345 /* Determine if an insn has a constant number of delay slots, i.e., the
4346 number of delay slots is not a function of the length of the insn. */
4348 static void
4349 write_const_num_delay_slots (void)
4351 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4352 struct attr_value *av;
4354 if (attr)
4356 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4357 printf ("{\n");
4358 printf (" switch (recog_memoized (insn))\n");
4359 printf (" {\n");
4361 for (av = attr->first_value; av; av = av->next)
4363 length_used = 0;
4364 walk_attr_value (av->value);
4365 if (length_used)
4366 write_insn_cases (av->first_insn, 4);
4369 printf (" default:\n");
4370 printf (" return 1;\n");
4371 printf (" }\n}\n\n");
4376 main (int argc, char **argv)
4378 rtx desc;
4379 struct attr_desc *attr;
4380 struct insn_def *id;
4381 rtx tem;
4382 int i;
4384 progname = "genattrtab";
4386 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
4387 return (FATAL_EXIT_CODE);
4389 obstack_init (hash_obstack);
4390 obstack_init (temp_obstack);
4392 /* Set up true and false rtx's */
4393 true_rtx = rtx_alloc (CONST_INT);
4394 XWINT (true_rtx, 0) = 1;
4395 false_rtx = rtx_alloc (CONST_INT);
4396 XWINT (false_rtx, 0) = 0;
4397 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4398 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
4400 alternative_name = DEF_ATTR_STRING ("alternative");
4401 length_str = DEF_ATTR_STRING ("length");
4402 delay_type_str = DEF_ATTR_STRING ("*delay_type");
4403 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4404 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
4406 printf ("/* Generated automatically by the program `genattrtab'\n\
4407 from the machine description file `md'. */\n\n");
4409 /* Read the machine description. */
4411 initiate_automaton_gen (argc, argv);
4412 while (1)
4414 int lineno;
4416 desc = read_md_rtx (&lineno, &insn_code_number);
4417 if (desc == NULL)
4418 break;
4420 switch (GET_CODE (desc))
4422 case DEFINE_INSN:
4423 case DEFINE_PEEPHOLE:
4424 case DEFINE_ASM_ATTRIBUTES:
4425 gen_insn (desc, lineno);
4426 break;
4428 case DEFINE_ATTR:
4429 gen_attr (desc, lineno);
4430 break;
4432 case DEFINE_DELAY:
4433 gen_delay (desc, lineno);
4434 break;
4436 case DEFINE_CPU_UNIT:
4437 gen_cpu_unit (desc);
4438 break;
4440 case DEFINE_QUERY_CPU_UNIT:
4441 gen_query_cpu_unit (desc);
4442 break;
4444 case DEFINE_BYPASS:
4445 gen_bypass (desc);
4446 break;
4448 case EXCLUSION_SET:
4449 gen_excl_set (desc);
4450 break;
4452 case PRESENCE_SET:
4453 gen_presence_set (desc);
4454 break;
4456 case FINAL_PRESENCE_SET:
4457 gen_final_presence_set (desc);
4458 break;
4460 case ABSENCE_SET:
4461 gen_absence_set (desc);
4462 break;
4464 case FINAL_ABSENCE_SET:
4465 gen_final_absence_set (desc);
4466 break;
4468 case DEFINE_AUTOMATON:
4469 gen_automaton (desc);
4470 break;
4472 case AUTOMATA_OPTION:
4473 gen_automata_option (desc);
4474 break;
4476 case DEFINE_RESERVATION:
4477 gen_reserv (desc);
4478 break;
4480 case DEFINE_INSN_RESERVATION:
4481 gen_insn_reserv (desc);
4482 break;
4484 default:
4485 break;
4487 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
4488 insn_index_number++;
4491 if (have_error)
4492 return FATAL_EXIT_CODE;
4494 insn_code_number++;
4496 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4497 if (! got_define_asm_attributes)
4499 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4500 XVEC (tem, 0) = rtvec_alloc (0);
4501 gen_insn (tem, 0);
4504 /* Expand DEFINE_DELAY information into new attribute. */
4505 if (num_delays)
4506 expand_delays ();
4508 /* Build DFA, output some functions and expand DFA information
4509 to new attributes. */
4510 if (num_dfa_decls)
4511 expand_automata ();
4513 printf ("#include \"config.h\"\n");
4514 printf ("#include \"system.h\"\n");
4515 printf ("#include \"coretypes.h\"\n");
4516 printf ("#include \"tm.h\"\n");
4517 printf ("#include \"rtl.h\"\n");
4518 printf ("#include \"tm_p.h\"\n");
4519 printf ("#include \"insn-config.h\"\n");
4520 printf ("#include \"recog.h\"\n");
4521 printf ("#include \"regs.h\"\n");
4522 printf ("#include \"real.h\"\n");
4523 printf ("#include \"output.h\"\n");
4524 printf ("#include \"insn-attr.h\"\n");
4525 printf ("#include \"toplev.h\"\n");
4526 printf ("#include \"flags.h\"\n");
4527 printf ("#include \"function.h\"\n");
4528 printf ("\n");
4529 printf ("#define operands recog_data.operand\n\n");
4531 /* Make `insn_alternatives'. */
4532 insn_alternatives = oballoc (insn_code_number * sizeof (int));
4533 for (id = defs; id; id = id->next)
4534 if (id->insn_code >= 0)
4535 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4537 /* Make `insn_n_alternatives'. */
4538 insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
4539 for (id = defs; id; id = id->next)
4540 if (id->insn_code >= 0)
4541 insn_n_alternatives[id->insn_code] = id->num_alternatives;
4543 /* Prepare to write out attribute subroutines by checking everything stored
4544 away and building the attribute cases. */
4546 check_defs ();
4548 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4549 for (attr = attrs[i]; attr; attr = attr->next)
4550 attr->default_val->value
4551 = check_attr_value (attr->default_val->value, attr);
4553 if (have_error)
4554 return FATAL_EXIT_CODE;
4556 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4557 for (attr = attrs[i]; attr; attr = attr->next)
4558 fill_attr (attr);
4560 /* Construct extra attributes for `length'. */
4561 make_length_attrs ();
4563 /* Perform any possible optimizations to speed up compilation. */
4564 optimize_attrs ();
4566 /* Now write out all the `gen_attr_...' routines. Do these before the
4567 special routines so that they get defined before they are used. */
4569 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4570 for (attr = attrs[i]; attr; attr = attr->next)
4572 if (! attr->is_special && ! attr->is_const)
4574 int insn_alts_p;
4576 insn_alts_p
4577 = (attr->name [0] == '*'
4578 && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
4579 if (insn_alts_p)
4580 printf ("\n#if AUTOMATON_ALTS\n");
4581 write_attr_get (attr);
4582 if (insn_alts_p)
4583 printf ("#endif\n\n");
4587 /* Write out delay eligibility information, if DEFINE_DELAY present.
4588 (The function to compute the number of delay slots will be written
4589 below.) */
4590 if (num_delays)
4592 write_eligible_delay ("delay");
4593 if (have_annul_true)
4594 write_eligible_delay ("annul_true");
4595 if (have_annul_false)
4596 write_eligible_delay ("annul_false");
4599 /* Output code for pipeline hazards recognition based on DFA
4600 (deterministic finite-state automata). */
4601 if (num_dfa_decls)
4602 write_automata ();
4604 /* Write out constant delay slot info. */
4605 write_const_num_delay_slots ();
4607 write_length_unit_log ();
4609 fflush (stdout);
4610 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
4613 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
4614 const char *
4615 get_insn_name (int code ATTRIBUTE_UNUSED)
4617 return NULL;