Daily bump.
[official-gcc.git] / gcc / genattrtab.c
blob744c951bd476b5b0d7e471eb118fd8dac720cc48
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
34 expression).
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
47 `get_attr_length'.
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
54 used.
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
77 will be written.
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
93 (see attr_rtx).
94 `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
95 EQ_ATTR rtx is true if !volatil and false if volatil. */
97 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
98 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
99 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
100 #define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
102 #if 0
103 #define strcmp_check(S1, S2) ((S1) == (S2) \
104 ? 0 \
105 : (gcc_assert (strcmp ((S1), (S2))), 1))
106 #else
107 #define strcmp_check(S1, S2) ((S1) != (S2))
108 #endif
110 #include "bconfig.h"
111 #include "system.h"
112 #include "coretypes.h"
113 #include "tm.h"
114 #include "rtl.h"
115 #include "ggc.h"
116 #include "gensupport.h"
118 #ifdef HAVE_SYS_RESOURCE_H
119 # include <sys/resource.h>
120 #endif
122 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
123 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
124 #include "obstack.h"
125 #include "errors.h"
127 #include "genattrtab.h"
129 static struct obstack obstack1, obstack2;
130 struct obstack *hash_obstack = &obstack1;
131 struct obstack *temp_obstack = &obstack2;
133 /* enough space to reserve for printing out ints */
134 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
136 /* Define structures used to record attributes and values. */
138 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
139 encountered, we store all the relevant information into a
140 `struct insn_def'. This is done to allow attribute definitions to occur
141 anywhere in the file. */
143 struct insn_def
145 struct insn_def *next; /* Next insn in chain. */
146 rtx def; /* The DEFINE_... */
147 int insn_code; /* Instruction number. */
148 int insn_index; /* Expression numer in file, for errors. */
149 int lineno; /* Line number. */
150 int num_alternatives; /* Number of alternatives. */
151 int vec_idx; /* Index of attribute vector in `def'. */
154 /* Once everything has been read in, we store in each attribute value a list
155 of insn codes that have that value. Here is the structure used for the
156 list. */
158 struct insn_ent
160 struct insn_ent *next; /* Next in chain. */
161 struct insn_def *def; /* Instruction definition. */
164 /* Each value of an attribute (either constant or computed) is assigned a
165 structure which is used as the listhead of the insns that have that
166 value. */
168 struct attr_value
170 rtx value; /* Value of attribute. */
171 struct attr_value *next; /* Next attribute value in chain. */
172 struct insn_ent *first_insn; /* First insn with this value. */
173 int num_insns; /* Number of insns with this value. */
174 int has_asm_insn; /* True if this value used for `asm' insns */
177 /* Structure for each attribute. */
179 struct attr_desc
181 char *name; /* Name of attribute. */
182 struct attr_desc *next; /* Next attribute. */
183 struct attr_value *first_value; /* First value of this attribute. */
184 struct attr_value *default_val; /* Default value for this attribute. */
185 int lineno : 24; /* Line number. */
186 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
187 unsigned negative_ok : 1; /* Allow negative numeric values. */
188 unsigned unsigned_p : 1; /* Make the output function unsigned int. */
189 unsigned is_const : 1; /* Attribute value constant for each run. */
190 unsigned is_special : 1; /* Don't call `write_attr_set'. */
191 unsigned static_p : 1; /* Make the output function static. */
194 #define NULL_ATTR (struct attr_desc *) NULL
196 /* Structure for each DEFINE_DELAY. */
198 struct delay_desc
200 rtx def; /* DEFINE_DELAY expression. */
201 struct delay_desc *next; /* Next DEFINE_DELAY. */
202 int num; /* Number of DEFINE_DELAY, starting at 1. */
203 int lineno; /* Line number. */
206 /* Listheads of above structures. */
208 /* This one is indexed by the first character of the attribute name. */
209 #define MAX_ATTRS_INDEX 256
210 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
211 static struct insn_def *defs;
212 static struct delay_desc *delays;
214 /* Other variables. */
216 static int insn_code_number;
217 static int insn_index_number;
218 static int got_define_asm_attributes;
219 static int must_extract;
220 static int must_constrain;
221 static int address_used;
222 static int length_used;
223 static int num_delays;
224 static int have_annul_true, have_annul_false;
225 static int num_insn_ents;
227 int num_dfa_decls;
229 /* Stores, for each insn code, the number of constraint alternatives. */
231 static int *insn_n_alternatives;
233 /* Stores, for each insn code, a bitmap that has bits on for each possible
234 alternative. */
236 static int *insn_alternatives;
238 /* If nonzero, assume that the `alternative' attr has this value.
239 This is the hashed, unique string for the numeral
240 whose value is chosen alternative. */
242 static const char *current_alternative_string;
244 /* Used to simplify expressions. */
246 static rtx true_rtx, false_rtx;
248 /* Used to reduce calls to `strcmp' */
250 static char *alternative_name;
251 static const char *length_str;
252 static const char *delay_type_str;
253 static const char *delay_1_0_str;
254 static const char *num_delay_slots_str;
256 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
257 called. */
259 int reload_completed = 0;
261 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
262 to define it here. */
264 int optimize = 0;
266 /* Simplify an expression. Only call the routine if there is something to
267 simplify. */
268 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
269 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
270 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
272 /* Simplify (eq_attr ("alternative") ...)
273 when we are working with a particular alternative. */
274 #define SIMPLIFY_ALTERNATIVE(EXP) \
275 if (current_alternative_string \
276 && GET_CODE ((EXP)) == EQ_ATTR \
277 && XSTR ((EXP), 0) == alternative_name) \
278 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
279 ? true_rtx : false_rtx);
281 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
283 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
284 They won't actually be used. */
286 rtx global_rtl[GR_MAX];
287 rtx pic_offset_table_rtx;
289 static void attr_hash_add_rtx (int, rtx);
290 static void attr_hash_add_string (int, char *);
291 static rtx attr_rtx (enum rtx_code, ...);
292 static rtx attr_rtx_1 (enum rtx_code, va_list);
293 static char *attr_string (const char *, int);
294 static rtx check_attr_value (rtx, struct attr_desc *);
295 static rtx convert_set_attr_alternative (rtx, struct insn_def *);
296 static rtx convert_set_attr (rtx, struct insn_def *);
297 static void check_defs (void);
298 static rtx make_canonical (struct attr_desc *, rtx);
299 static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
300 static rtx copy_rtx_unchanging (rtx);
301 static rtx copy_boolean (rtx);
302 static void expand_delays (void);
303 static void fill_attr (struct attr_desc *);
304 static rtx substitute_address (rtx, rtx (*) (rtx), rtx (*) (rtx));
305 static void make_length_attrs (void);
306 static rtx identity_fn (rtx);
307 static rtx zero_fn (rtx);
308 static rtx one_fn (rtx);
309 static rtx max_fn (rtx);
310 static void write_length_unit_log (void);
311 static rtx simplify_cond (rtx, int, int);
312 static void clear_struct_flag (rtx);
313 static void remove_insn_ent (struct attr_value *, struct insn_ent *);
314 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
315 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
316 static rtx make_alternative_compare (int);
317 static int compute_alternative_mask (rtx, enum rtx_code);
318 static rtx evaluate_eq_attr (rtx, rtx, int, int);
319 static rtx simplify_and_tree (rtx, rtx *, int, int);
320 static rtx simplify_or_tree (rtx, rtx *, int, int);
321 static rtx simplify_test_exp (rtx, int, int);
322 static rtx simplify_test_exp_in_temp (rtx, int, int);
323 static void optimize_attrs (void);
324 static void gen_attr (rtx, int);
325 static int count_alternatives (rtx);
326 static int compares_alternatives_p (rtx);
327 static int contained_in_p (rtx, rtx);
328 static void gen_insn (rtx, int);
329 static void gen_delay (rtx, int);
330 static void write_test_expr (rtx, int);
331 static int max_attr_value (rtx, int*);
332 static int or_attr_value (rtx, int*);
333 static void walk_attr_value (rtx);
334 static void write_attr_get (struct attr_desc *);
335 static rtx eliminate_known_true (rtx, rtx, int, int);
336 static void write_attr_set (struct attr_desc *, int, rtx,
337 const char *, const char *, rtx,
338 int, int);
339 static void write_insn_cases (struct insn_ent *, int);
340 static void write_attr_case (struct attr_desc *, struct attr_value *,
341 int, const char *, const char *, int, rtx);
342 static void write_attr_valueq (struct attr_desc *, const char *);
343 static void write_attr_value (struct attr_desc *, rtx);
344 static void write_upcase (const char *);
345 static void write_indent (int);
346 static void write_eligible_delay (const char *);
347 static int write_expr_attr_cache (rtx, struct attr_desc *);
348 static void write_const_num_delay_slots (void);
349 static char *next_comma_elt (const char **);
350 static struct attr_desc *find_attr (const char **, int);
351 static struct attr_value *find_most_used (struct attr_desc *);
352 static rtx attr_eq (const char *, const char *);
353 static const char *attr_numeral (int);
354 static int attr_equal_p (rtx, rtx);
355 static rtx attr_copy_rtx (rtx);
356 static int attr_rtx_cost (rtx);
357 static bool attr_alt_subset_p (rtx, rtx);
358 static bool attr_alt_subset_of_compl_p (rtx, rtx);
359 static rtx attr_alt_intersection (rtx, rtx);
360 static rtx attr_alt_union (rtx, rtx);
361 static rtx attr_alt_complement (rtx);
362 static bool attr_alt_bit_p (rtx, int);
363 static rtx mk_attr_alt (int);
365 #define oballoc(size) obstack_alloc (hash_obstack, size)
367 /* Hash table for sharing RTL and strings. */
369 /* Each hash table slot is a bucket containing a chain of these structures.
370 Strings are given negative hash codes; RTL expressions are given positive
371 hash codes. */
373 struct attr_hash
375 struct attr_hash *next; /* Next structure in the bucket. */
376 int hashcode; /* Hash code of this rtx or string. */
377 union
379 char *str; /* The string (negative hash codes) */
380 rtx rtl; /* or the RTL recorded here. */
381 } u;
384 /* Now here is the hash table. When recording an RTL, it is added to
385 the slot whose index is the hash code mod the table size. Note
386 that the hash table is used for several kinds of RTL (see attr_rtx)
387 and for strings. While all these live in the same table, they are
388 completely independent, and the hash code is computed differently
389 for each. */
391 #define RTL_HASH_SIZE 4093
392 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
394 /* Here is how primitive or already-shared RTL's hash
395 codes are made. */
396 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
398 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
400 static void
401 attr_hash_add_rtx (int hashcode, rtx rtl)
403 struct attr_hash *h;
405 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
406 h->hashcode = hashcode;
407 h->u.rtl = rtl;
408 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
409 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
412 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
414 static void
415 attr_hash_add_string (int hashcode, char *str)
417 struct attr_hash *h;
419 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
420 h->hashcode = -hashcode;
421 h->u.str = str;
422 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
423 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
426 /* Generate an RTL expression, but avoid duplicates.
427 Set the ATTR_PERMANENT_P flag for these permanent objects.
429 In some cases we cannot uniquify; then we return an ordinary
430 impermanent rtx with ATTR_PERMANENT_P clear.
432 Args are as follows:
434 rtx attr_rtx (code, [element1, ..., elementn]) */
436 static rtx
437 attr_rtx_1 (enum rtx_code code, va_list p)
439 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
440 int hashcode;
441 struct attr_hash *h;
442 struct obstack *old_obstack = rtl_obstack;
444 /* For each of several cases, search the hash table for an existing entry.
445 Use that entry if one is found; otherwise create a new RTL and add it
446 to the table. */
448 if (GET_RTX_CLASS (code) == RTX_UNARY)
450 rtx arg0 = va_arg (p, rtx);
452 /* A permanent object cannot point to impermanent ones. */
453 if (! ATTR_PERMANENT_P (arg0))
455 rt_val = rtx_alloc (code);
456 XEXP (rt_val, 0) = arg0;
457 return rt_val;
460 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
461 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
462 if (h->hashcode == hashcode
463 && GET_CODE (h->u.rtl) == code
464 && XEXP (h->u.rtl, 0) == arg0)
465 return h->u.rtl;
467 if (h == 0)
469 rtl_obstack = hash_obstack;
470 rt_val = rtx_alloc (code);
471 XEXP (rt_val, 0) = arg0;
474 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
475 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
476 || GET_RTX_CLASS (code) == RTX_COMPARE
477 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
479 rtx arg0 = va_arg (p, rtx);
480 rtx arg1 = va_arg (p, rtx);
482 /* A permanent object cannot point to impermanent ones. */
483 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
485 rt_val = rtx_alloc (code);
486 XEXP (rt_val, 0) = arg0;
487 XEXP (rt_val, 1) = arg1;
488 return rt_val;
491 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
492 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
493 if (h->hashcode == hashcode
494 && GET_CODE (h->u.rtl) == code
495 && XEXP (h->u.rtl, 0) == arg0
496 && XEXP (h->u.rtl, 1) == arg1)
497 return h->u.rtl;
499 if (h == 0)
501 rtl_obstack = hash_obstack;
502 rt_val = rtx_alloc (code);
503 XEXP (rt_val, 0) = arg0;
504 XEXP (rt_val, 1) = arg1;
507 else if (GET_RTX_LENGTH (code) == 1
508 && GET_RTX_FORMAT (code)[0] == 's')
510 char *arg0 = va_arg (p, char *);
512 arg0 = DEF_ATTR_STRING (arg0);
514 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
515 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
516 if (h->hashcode == hashcode
517 && GET_CODE (h->u.rtl) == code
518 && XSTR (h->u.rtl, 0) == arg0)
519 return h->u.rtl;
521 if (h == 0)
523 rtl_obstack = hash_obstack;
524 rt_val = rtx_alloc (code);
525 XSTR (rt_val, 0) = arg0;
528 else if (GET_RTX_LENGTH (code) == 2
529 && GET_RTX_FORMAT (code)[0] == 's'
530 && GET_RTX_FORMAT (code)[1] == 's')
532 char *arg0 = va_arg (p, char *);
533 char *arg1 = va_arg (p, char *);
535 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
536 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
537 if (h->hashcode == hashcode
538 && GET_CODE (h->u.rtl) == code
539 && XSTR (h->u.rtl, 0) == arg0
540 && XSTR (h->u.rtl, 1) == arg1)
541 return h->u.rtl;
543 if (h == 0)
545 rtl_obstack = hash_obstack;
546 rt_val = rtx_alloc (code);
547 XSTR (rt_val, 0) = arg0;
548 XSTR (rt_val, 1) = arg1;
551 else if (code == CONST_INT)
553 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
554 if (arg0 == 0)
555 return false_rtx;
556 else if (arg0 == 1)
557 return true_rtx;
558 else
559 goto nohash;
561 else
563 int i; /* Array indices... */
564 const char *fmt; /* Current rtx's format... */
565 nohash:
566 rt_val = rtx_alloc (code); /* Allocate the storage space. */
568 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
569 for (i = 0; i < GET_RTX_LENGTH (code); i++)
571 switch (*fmt++)
573 case '0': /* Unused field. */
574 break;
576 case 'i': /* An integer? */
577 XINT (rt_val, i) = va_arg (p, int);
578 break;
580 case 'w': /* A wide integer? */
581 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
582 break;
584 case 's': /* A string? */
585 XSTR (rt_val, i) = va_arg (p, char *);
586 break;
588 case 'e': /* An expression? */
589 case 'u': /* An insn? Same except when printing. */
590 XEXP (rt_val, i) = va_arg (p, rtx);
591 break;
593 case 'E': /* An RTX vector? */
594 XVEC (rt_val, i) = va_arg (p, rtvec);
595 break;
597 default:
598 gcc_unreachable ();
601 return rt_val;
604 rtl_obstack = old_obstack;
605 attr_hash_add_rtx (hashcode, rt_val);
606 ATTR_PERMANENT_P (rt_val) = 1;
607 return rt_val;
610 static rtx
611 attr_rtx (enum rtx_code code, ...)
613 rtx result;
614 va_list p;
616 va_start (p, code);
617 result = attr_rtx_1 (code, p);
618 va_end (p);
619 return result;
622 /* Create a new string printed with the printf line arguments into a space
623 of at most LEN bytes:
625 rtx attr_printf (len, format, [arg1, ..., argn]) */
627 char *
628 attr_printf (unsigned int len, const char *fmt, ...)
630 char str[256];
631 va_list p;
633 va_start (p, fmt);
635 gcc_assert (len < sizeof str); /* Leave room for \0. */
637 vsprintf (str, fmt, p);
638 va_end (p);
640 return DEF_ATTR_STRING (str);
643 static rtx
644 attr_eq (const char *name, const char *value)
646 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
649 static const char *
650 attr_numeral (int n)
652 return XSTR (make_numeric_value (n), 0);
655 /* Return a permanent (possibly shared) copy of a string STR (not assumed
656 to be null terminated) with LEN bytes. */
658 static char *
659 attr_string (const char *str, int len)
661 struct attr_hash *h;
662 int hashcode;
663 int i;
664 char *new_str;
666 /* Compute the hash code. */
667 hashcode = (len + 1) * 613 + (unsigned) str[0];
668 for (i = 1; i <= len; i += 2)
669 hashcode = ((hashcode * 613) + (unsigned) str[i]);
670 if (hashcode < 0)
671 hashcode = -hashcode;
673 /* Search the table for the string. */
674 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
675 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
676 && !strncmp (h->u.str, str, len))
677 return h->u.str; /* <-- return if found. */
679 /* Not found; create a permanent copy and add it to the hash table. */
680 new_str = obstack_alloc (hash_obstack, len + 1);
681 memcpy (new_str, str, len);
682 new_str[len] = '\0';
683 attr_hash_add_string (hashcode, new_str);
685 return new_str; /* Return the new string. */
688 /* Check two rtx's for equality of contents,
689 taking advantage of the fact that if both are hashed
690 then they can't be equal unless they are the same object. */
692 static int
693 attr_equal_p (rtx x, rtx y)
695 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
696 && rtx_equal_p (x, y)));
699 /* Copy an attribute value expression,
700 descending to all depths, but not copying any
701 permanent hashed subexpressions. */
703 static rtx
704 attr_copy_rtx (rtx orig)
706 rtx copy;
707 int i, j;
708 RTX_CODE code;
709 const char *format_ptr;
711 /* No need to copy a permanent object. */
712 if (ATTR_PERMANENT_P (orig))
713 return orig;
715 code = GET_CODE (orig);
717 switch (code)
719 case REG:
720 case CONST_INT:
721 case CONST_DOUBLE:
722 case CONST_VECTOR:
723 case SYMBOL_REF:
724 case CODE_LABEL:
725 case PC:
726 case CC0:
727 return orig;
729 default:
730 break;
733 copy = rtx_alloc (code);
734 PUT_MODE (copy, GET_MODE (orig));
735 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
736 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
737 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
738 ATTR_EQ_ATTR_P (copy) = ATTR_EQ_ATTR_P (orig);
740 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
742 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
744 switch (*format_ptr++)
746 case 'e':
747 XEXP (copy, i) = XEXP (orig, i);
748 if (XEXP (orig, i) != NULL)
749 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
750 break;
752 case 'E':
753 case 'V':
754 XVEC (copy, i) = XVEC (orig, i);
755 if (XVEC (orig, i) != NULL)
757 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
758 for (j = 0; j < XVECLEN (copy, i); j++)
759 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
761 break;
763 case 'n':
764 case 'i':
765 XINT (copy, i) = XINT (orig, i);
766 break;
768 case 'w':
769 XWINT (copy, i) = XWINT (orig, i);
770 break;
772 case 's':
773 case 'S':
774 XSTR (copy, i) = XSTR (orig, i);
775 break;
777 default:
778 gcc_unreachable ();
781 return copy;
784 /* Given a test expression for an attribute, ensure it is validly formed.
785 IS_CONST indicates whether the expression is constant for each compiler
786 run (a constant expression may not test any particular insn).
788 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
789 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
790 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
792 Update the string address in EQ_ATTR expression to be the same used
793 in the attribute (or `alternative_name') to speed up subsequent
794 `find_attr' calls and eliminate most `strcmp' calls.
796 Return the new expression, if any. */
799 check_attr_test (rtx exp, int is_const, int lineno)
801 struct attr_desc *attr;
802 struct attr_value *av;
803 const char *name_ptr, *p;
804 rtx orexp, newexp;
806 switch (GET_CODE (exp))
808 case EQ_ATTR:
809 /* Handle negation test. */
810 if (XSTR (exp, 1)[0] == '!')
811 return check_attr_test (attr_rtx (NOT,
812 attr_eq (XSTR (exp, 0),
813 &XSTR (exp, 1)[1])),
814 is_const, lineno);
816 else if (n_comma_elts (XSTR (exp, 1)) == 1)
818 attr = find_attr (&XSTR (exp, 0), 0);
819 if (attr == NULL)
821 if (! strcmp (XSTR (exp, 0), "alternative"))
822 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
823 else
824 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
827 if (is_const && ! attr->is_const)
828 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
829 XSTR (exp, 0));
831 /* Copy this just to make it permanent,
832 so expressions using it can be permanent too. */
833 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
835 /* It shouldn't be possible to simplify the value given to a
836 constant attribute, so don't expand this until it's time to
837 write the test expression. */
838 if (attr->is_const)
839 ATTR_IND_SIMPLIFIED_P (exp) = 1;
841 if (attr->is_numeric)
843 for (p = XSTR (exp, 1); *p; p++)
844 if (! ISDIGIT (*p))
845 fatal ("attribute `%s' takes only numeric values",
846 XSTR (exp, 0));
848 else
850 for (av = attr->first_value; av; av = av->next)
851 if (GET_CODE (av->value) == CONST_STRING
852 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
853 break;
855 if (av == NULL)
856 fatal ("unknown value `%s' for `%s' attribute",
857 XSTR (exp, 1), XSTR (exp, 0));
860 else
862 if (! strcmp (XSTR (exp, 0), "alternative"))
864 int set = 0;
866 name_ptr = XSTR (exp, 1);
867 while ((p = next_comma_elt (&name_ptr)) != NULL)
868 set |= 1 << atoi (p);
870 return mk_attr_alt (set);
872 else
874 /* Make an IOR tree of the possible values. */
875 orexp = false_rtx;
876 name_ptr = XSTR (exp, 1);
877 while ((p = next_comma_elt (&name_ptr)) != NULL)
879 newexp = attr_eq (XSTR (exp, 0), p);
880 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
883 return check_attr_test (orexp, is_const, lineno);
886 break;
888 case ATTR_FLAG:
889 break;
891 case CONST_INT:
892 /* Either TRUE or FALSE. */
893 if (XWINT (exp, 0))
894 return true_rtx;
895 else
896 return false_rtx;
898 case IOR:
899 case AND:
900 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
901 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
902 break;
904 case NOT:
905 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
906 break;
908 case MATCH_OPERAND:
909 if (is_const)
910 fatal ("RTL operator \"%s\" not valid in constant attribute test",
911 GET_RTX_NAME (GET_CODE (exp)));
912 /* These cases can't be simplified. */
913 ATTR_IND_SIMPLIFIED_P (exp) = 1;
914 break;
916 case LE: case LT: case GT: case GE:
917 case LEU: case LTU: case GTU: case GEU:
918 case NE: case EQ:
919 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
920 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
921 exp = attr_rtx (GET_CODE (exp),
922 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
923 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
924 /* These cases can't be simplified. */
925 ATTR_IND_SIMPLIFIED_P (exp) = 1;
926 break;
928 case SYMBOL_REF:
929 if (is_const)
931 /* These cases are valid for constant attributes, but can't be
932 simplified. */
933 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
934 ATTR_IND_SIMPLIFIED_P (exp) = 1;
935 break;
937 default:
938 fatal ("RTL operator \"%s\" not valid in attribute test",
939 GET_RTX_NAME (GET_CODE (exp)));
942 return exp;
945 /* Given an expression, ensure that it is validly formed and that all named
946 attribute values are valid for the given attribute. Issue a fatal error
947 if not. If no attribute is specified, assume a numeric attribute.
949 Return a perhaps modified replacement expression for the value. */
951 static rtx
952 check_attr_value (rtx exp, struct attr_desc *attr)
954 struct attr_value *av;
955 const char *p;
956 int i;
958 switch (GET_CODE (exp))
960 case CONST_INT:
961 if (attr && ! attr->is_numeric)
963 message_with_line (attr->lineno,
964 "CONST_INT not valid for non-numeric attribute %s",
965 attr->name);
966 have_error = 1;
967 break;
970 if (INTVAL (exp) < 0 && ! attr->negative_ok)
972 message_with_line (attr->lineno,
973 "negative numeric value specified for attribute %s",
974 attr->name);
975 have_error = 1;
976 break;
978 break;
980 case CONST_STRING:
981 if (! strcmp (XSTR (exp, 0), "*"))
982 break;
984 if (attr == 0 || attr->is_numeric)
986 p = XSTR (exp, 0);
987 if (attr && attr->negative_ok && *p == '-')
988 p++;
989 for (; *p; p++)
990 if (! ISDIGIT (*p))
992 message_with_line (attr ? attr->lineno : 0,
993 "non-numeric value for numeric attribute %s",
994 attr ? attr->name : "internal");
995 have_error = 1;
996 break;
998 break;
1001 for (av = attr->first_value; av; av = av->next)
1002 if (GET_CODE (av->value) == CONST_STRING
1003 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1004 break;
1006 if (av == NULL)
1008 message_with_line (attr->lineno,
1009 "unknown value `%s' for `%s' attribute",
1010 XSTR (exp, 0), attr ? attr->name : "internal");
1011 have_error = 1;
1013 break;
1015 case IF_THEN_ELSE:
1016 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1017 attr ? attr->is_const : 0,
1018 attr ? attr->lineno : 0);
1019 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1020 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1021 break;
1023 case PLUS:
1024 case MINUS:
1025 case MULT:
1026 case DIV:
1027 case MOD:
1028 if (attr && !attr->is_numeric)
1030 message_with_line (attr->lineno,
1031 "invalid operation `%s' for non-numeric attribute value",
1032 GET_RTX_NAME (GET_CODE (exp)));
1033 have_error = 1;
1034 break;
1036 /* Fall through. */
1038 case IOR:
1039 case AND:
1040 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1041 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1042 break;
1044 case FFS:
1045 case CLZ:
1046 case CTZ:
1047 case POPCOUNT:
1048 case PARITY:
1049 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1050 break;
1052 case COND:
1053 if (XVECLEN (exp, 0) % 2 != 0)
1055 message_with_line (attr->lineno,
1056 "first operand of COND must have even length");
1057 have_error = 1;
1058 break;
1061 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1063 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1064 attr ? attr->is_const : 0,
1065 attr ? attr->lineno : 0);
1066 XVECEXP (exp, 0, i + 1)
1067 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1070 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1071 break;
1073 case ATTR:
1075 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
1076 if (attr2 == NULL)
1078 message_with_line (attr ? attr->lineno : 0,
1079 "unknown attribute `%s' in ATTR",
1080 XSTR (exp, 0));
1081 have_error = 1;
1083 else if (attr && attr->is_const && ! attr2->is_const)
1085 message_with_line (attr->lineno,
1086 "non-constant attribute `%s' referenced from `%s'",
1087 XSTR (exp, 0), attr->name);
1088 have_error = 1;
1090 else if (attr
1091 && (attr->is_numeric != attr2->is_numeric
1092 || (! attr->negative_ok && attr2->negative_ok)))
1094 message_with_line (attr->lineno,
1095 "numeric attribute mismatch calling `%s' from `%s'",
1096 XSTR (exp, 0), attr->name);
1097 have_error = 1;
1100 break;
1102 case SYMBOL_REF:
1103 /* A constant SYMBOL_REF is valid as a constant attribute test and
1104 is expanded later by make_canonical into a COND. In a non-constant
1105 attribute test, it is left be. */
1106 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1108 default:
1109 message_with_line (attr ? attr->lineno : 0,
1110 "invalid operation `%s' for attribute value",
1111 GET_RTX_NAME (GET_CODE (exp)));
1112 have_error = 1;
1113 break;
1116 return exp;
1119 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1120 It becomes a COND with each test being (eq_attr "alternative "n") */
1122 static rtx
1123 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1125 int num_alt = id->num_alternatives;
1126 rtx condexp;
1127 int i;
1129 if (XVECLEN (exp, 1) != num_alt)
1131 message_with_line (id->lineno,
1132 "bad number of entries in SET_ATTR_ALTERNATIVE");
1133 have_error = 1;
1134 return NULL_RTX;
1137 /* Make a COND with all tests but the last. Select the last value via the
1138 default. */
1139 condexp = rtx_alloc (COND);
1140 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1142 for (i = 0; i < num_alt - 1; i++)
1144 const char *p;
1145 p = attr_numeral (i);
1147 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1148 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1151 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1153 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1156 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1157 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1159 static rtx
1160 convert_set_attr (rtx exp, struct insn_def *id)
1162 rtx newexp;
1163 const char *name_ptr;
1164 char *p;
1165 int n;
1167 /* See how many alternative specified. */
1168 n = n_comma_elts (XSTR (exp, 1));
1169 if (n == 1)
1170 return attr_rtx (SET,
1171 attr_rtx (ATTR, XSTR (exp, 0)),
1172 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1174 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1175 XSTR (newexp, 0) = XSTR (exp, 0);
1176 XVEC (newexp, 1) = rtvec_alloc (n);
1178 /* Process each comma-separated name. */
1179 name_ptr = XSTR (exp, 1);
1180 n = 0;
1181 while ((p = next_comma_elt (&name_ptr)) != NULL)
1182 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1184 return convert_set_attr_alternative (newexp, id);
1187 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1188 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1189 expressions. */
1191 static void
1192 check_defs (void)
1194 struct insn_def *id;
1195 struct attr_desc *attr;
1196 int i;
1197 rtx value;
1199 for (id = defs; id; id = id->next)
1201 if (XVEC (id->def, id->vec_idx) == NULL)
1202 continue;
1204 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1206 value = XVECEXP (id->def, id->vec_idx, i);
1207 switch (GET_CODE (value))
1209 case SET:
1210 if (GET_CODE (XEXP (value, 0)) != ATTR)
1212 message_with_line (id->lineno, "bad attribute set");
1213 have_error = 1;
1214 value = NULL_RTX;
1216 break;
1218 case SET_ATTR_ALTERNATIVE:
1219 value = convert_set_attr_alternative (value, id);
1220 break;
1222 case SET_ATTR:
1223 value = convert_set_attr (value, id);
1224 break;
1226 default:
1227 message_with_line (id->lineno, "invalid attribute code %s",
1228 GET_RTX_NAME (GET_CODE (value)));
1229 have_error = 1;
1230 value = NULL_RTX;
1232 if (value == NULL_RTX)
1233 continue;
1235 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1237 message_with_line (id->lineno, "unknown attribute %s",
1238 XSTR (XEXP (value, 0), 0));
1239 have_error = 1;
1240 continue;
1243 XVECEXP (id->def, id->vec_idx, i) = value;
1244 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1249 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1250 expressions by converting them into a COND. This removes cases from this
1251 program. Also, replace an attribute value of "*" with the default attribute
1252 value. */
1254 static rtx
1255 make_canonical (struct attr_desc *attr, rtx exp)
1257 int i;
1258 rtx newexp;
1260 switch (GET_CODE (exp))
1262 case CONST_INT:
1263 exp = make_numeric_value (INTVAL (exp));
1264 break;
1266 case CONST_STRING:
1267 if (! strcmp (XSTR (exp, 0), "*"))
1269 if (attr == 0 || attr->default_val == 0)
1270 fatal ("(attr_value \"*\") used in invalid context");
1271 exp = attr->default_val->value;
1273 else
1274 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1276 break;
1278 case SYMBOL_REF:
1279 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1280 break;
1281 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1282 This makes the COND something that won't be considered an arbitrary
1283 expression by walk_attr_value. */
1284 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1285 exp = check_attr_value (exp, attr);
1286 break;
1288 case IF_THEN_ELSE:
1289 newexp = rtx_alloc (COND);
1290 XVEC (newexp, 0) = rtvec_alloc (2);
1291 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1292 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1294 XEXP (newexp, 1) = XEXP (exp, 2);
1296 exp = newexp;
1297 /* Fall through to COND case since this is now a COND. */
1299 case COND:
1301 int allsame = 1;
1302 rtx defval;
1304 /* First, check for degenerate COND. */
1305 if (XVECLEN (exp, 0) == 0)
1306 return make_canonical (attr, XEXP (exp, 1));
1307 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1309 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1311 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1312 XVECEXP (exp, 0, i + 1)
1313 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1314 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1315 allsame = 0;
1317 if (allsame)
1318 return defval;
1320 break;
1322 default:
1323 break;
1326 return exp;
1329 static rtx
1330 copy_boolean (rtx exp)
1332 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1333 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1334 copy_boolean (XEXP (exp, 1)));
1335 if (GET_CODE (exp) == MATCH_OPERAND)
1337 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1338 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1340 else if (GET_CODE (exp) == EQ_ATTR)
1342 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1343 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1346 return exp;
1349 /* Given a value and an attribute description, return a `struct attr_value *'
1350 that represents that value. This is either an existing structure, if the
1351 value has been previously encountered, or a newly-created structure.
1353 `insn_code' is the code of an insn whose attribute has the specified
1354 value (-2 if not processing an insn). We ensure that all insns for
1355 a given value have the same number of alternatives if the value checks
1356 alternatives. */
1358 static struct attr_value *
1359 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1361 struct attr_value *av;
1362 int num_alt = 0;
1364 value = make_canonical (attr, value);
1365 if (compares_alternatives_p (value))
1367 if (insn_code < 0 || insn_alternatives == NULL)
1368 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1369 else
1370 num_alt = insn_alternatives[insn_code];
1373 for (av = attr->first_value; av; av = av->next)
1374 if (rtx_equal_p (value, av->value)
1375 && (num_alt == 0 || av->first_insn == NULL
1376 || insn_alternatives[av->first_insn->def->insn_code]))
1377 return av;
1379 av = oballoc (sizeof (struct attr_value));
1380 av->value = value;
1381 av->next = attr->first_value;
1382 attr->first_value = av;
1383 av->first_insn = NULL;
1384 av->num_insns = 0;
1385 av->has_asm_insn = 0;
1387 return av;
1390 /* After all DEFINE_DELAYs have been read in, create internal attributes
1391 to generate the required routines.
1393 First, we compute the number of delay slots for each insn (as a COND of
1394 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1395 delay type is specified, we compute a similar function giving the
1396 DEFINE_DELAY ordinal for each insn.
1398 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1399 tells whether a given insn can be in that delay slot.
1401 Normal attribute filling and optimization expands these to contain the
1402 information needed to handle delay slots. */
1404 static void
1405 expand_delays (void)
1407 struct delay_desc *delay;
1408 rtx condexp;
1409 rtx newexp;
1410 int i;
1411 char *p;
1413 /* First, generate data for `num_delay_slots' function. */
1415 condexp = rtx_alloc (COND);
1416 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1417 XEXP (condexp, 1) = make_numeric_value (0);
1419 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1421 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1422 XVECEXP (condexp, 0, i + 1)
1423 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1426 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1428 /* If more than one delay type, do the same for computing the delay type. */
1429 if (num_delays > 1)
1431 condexp = rtx_alloc (COND);
1432 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1433 XEXP (condexp, 1) = make_numeric_value (0);
1435 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1437 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1438 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1441 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1444 /* For each delay possibility and delay slot, compute an eligibility
1445 attribute for non-annulled insns and for each type of annulled (annul
1446 if true and annul if false). */
1447 for (delay = delays; delay; delay = delay->next)
1449 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1451 condexp = XVECEXP (delay->def, 1, i);
1452 if (condexp == 0)
1453 condexp = false_rtx;
1454 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1455 make_numeric_value (1), make_numeric_value (0));
1457 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1458 "*delay_%d_%d", delay->num, i / 3);
1459 make_internal_attr (p, newexp, ATTR_SPECIAL);
1461 if (have_annul_true)
1463 condexp = XVECEXP (delay->def, 1, i + 1);
1464 if (condexp == 0) condexp = false_rtx;
1465 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1466 make_numeric_value (1),
1467 make_numeric_value (0));
1468 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1469 "*annul_true_%d_%d", delay->num, i / 3);
1470 make_internal_attr (p, newexp, ATTR_SPECIAL);
1473 if (have_annul_false)
1475 condexp = XVECEXP (delay->def, 1, i + 2);
1476 if (condexp == 0) condexp = false_rtx;
1477 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1478 make_numeric_value (1),
1479 make_numeric_value (0));
1480 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1481 "*annul_false_%d_%d", delay->num, i / 3);
1482 make_internal_attr (p, newexp, ATTR_SPECIAL);
1488 /* Once all attributes and insns have been read and checked, we construct for
1489 each attribute value a list of all the insns that have that value for
1490 the attribute. */
1492 static void
1493 fill_attr (struct attr_desc *attr)
1495 struct attr_value *av;
1496 struct insn_ent *ie;
1497 struct insn_def *id;
1498 int i;
1499 rtx value;
1501 /* Don't fill constant attributes. The value is independent of
1502 any particular insn. */
1503 if (attr->is_const)
1504 return;
1506 for (id = defs; id; id = id->next)
1508 /* If no value is specified for this insn for this attribute, use the
1509 default. */
1510 value = NULL;
1511 if (XVEC (id->def, id->vec_idx))
1512 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1513 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1514 attr->name))
1515 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1517 if (value == NULL)
1518 av = attr->default_val;
1519 else
1520 av = get_attr_value (value, attr, id->insn_code);
1522 ie = oballoc (sizeof (struct insn_ent));
1523 ie->def = id;
1524 insert_insn_ent (av, ie);
1528 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1529 test that checks relative positions of insns (uses MATCH_DUP or PC).
1530 If so, replace it with what is obtained by passing the expression to
1531 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1532 recursively on each value (including the default value). Otherwise,
1533 return the value returned by NO_ADDRESS_FN applied to EXP. */
1535 static rtx
1536 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1537 rtx (*address_fn) (rtx))
1539 int i;
1540 rtx newexp;
1542 if (GET_CODE (exp) == COND)
1544 /* See if any tests use addresses. */
1545 address_used = 0;
1546 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1547 walk_attr_value (XVECEXP (exp, 0, i));
1549 if (address_used)
1550 return (*address_fn) (exp);
1552 /* Make a new copy of this COND, replacing each element. */
1553 newexp = rtx_alloc (COND);
1554 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1555 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1557 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1558 XVECEXP (newexp, 0, i + 1)
1559 = substitute_address (XVECEXP (exp, 0, i + 1),
1560 no_address_fn, address_fn);
1563 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1564 no_address_fn, address_fn);
1566 return newexp;
1569 else if (GET_CODE (exp) == IF_THEN_ELSE)
1571 address_used = 0;
1572 walk_attr_value (XEXP (exp, 0));
1573 if (address_used)
1574 return (*address_fn) (exp);
1576 return attr_rtx (IF_THEN_ELSE,
1577 substitute_address (XEXP (exp, 0),
1578 no_address_fn, address_fn),
1579 substitute_address (XEXP (exp, 1),
1580 no_address_fn, address_fn),
1581 substitute_address (XEXP (exp, 2),
1582 no_address_fn, address_fn));
1585 return (*no_address_fn) (exp);
1588 /* Make new attributes from the `length' attribute. The following are made,
1589 each corresponding to a function called from `shorten_branches' or
1590 `get_attr_length':
1592 *insn_default_length This is the length of the insn to be returned
1593 by `get_attr_length' before `shorten_branches'
1594 has been called. In each case where the length
1595 depends on relative addresses, the largest
1596 possible is used. This routine is also used
1597 to compute the initial size of the insn.
1599 *insn_variable_length_p This returns 1 if the insn's length depends
1600 on relative addresses, zero otherwise.
1602 *insn_current_length This is only called when it is known that the
1603 insn has a variable length and returns the
1604 current length, based on relative addresses.
1607 static void
1608 make_length_attrs (void)
1610 static const char *new_names[] =
1612 "*insn_default_length",
1613 "*insn_variable_length_p",
1614 "*insn_current_length"
1616 static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn};
1617 static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn};
1618 size_t i;
1619 struct attr_desc *length_attr, *new_attr;
1620 struct attr_value *av, *new_av;
1621 struct insn_ent *ie, *new_ie;
1623 /* See if length attribute is defined. If so, it must be numeric. Make
1624 it special so we don't output anything for it. */
1625 length_attr = find_attr (&length_str, 0);
1626 if (length_attr == 0)
1627 return;
1629 if (! length_attr->is_numeric)
1630 fatal ("length attribute must be numeric");
1632 length_attr->is_const = 0;
1633 length_attr->is_special = 1;
1635 /* Make each new attribute, in turn. */
1636 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1638 make_internal_attr (new_names[i],
1639 substitute_address (length_attr->default_val->value,
1640 no_address_fn[i], address_fn[i]),
1641 ATTR_NONE);
1642 new_attr = find_attr (&new_names[i], 0);
1643 for (av = length_attr->first_value; av; av = av->next)
1644 for (ie = av->first_insn; ie; ie = ie->next)
1646 new_av = get_attr_value (substitute_address (av->value,
1647 no_address_fn[i],
1648 address_fn[i]),
1649 new_attr, ie->def->insn_code);
1650 new_ie = oballoc (sizeof (struct insn_ent));
1651 new_ie->def = ie->def;
1652 insert_insn_ent (new_av, new_ie);
1657 /* Utility functions called from above routine. */
1659 static rtx
1660 identity_fn (rtx exp)
1662 return exp;
1665 static rtx
1666 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1668 return make_numeric_value (0);
1671 static rtx
1672 one_fn (rtx exp ATTRIBUTE_UNUSED)
1674 return make_numeric_value (1);
1677 static rtx
1678 max_fn (rtx exp)
1680 int unknown;
1681 return make_numeric_value (max_attr_value (exp, &unknown));
1684 static void
1685 write_length_unit_log (void)
1687 struct attr_desc *length_attr = find_attr (&length_str, 0);
1688 struct attr_value *av;
1689 struct insn_ent *ie;
1690 unsigned int length_unit_log, length_or;
1691 int unknown = 0;
1693 if (length_attr == 0)
1694 return;
1695 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1696 for (av = length_attr->first_value; av; av = av->next)
1697 for (ie = av->first_insn; ie; ie = ie->next)
1698 length_or |= or_attr_value (av->value, &unknown);
1700 if (unknown)
1701 length_unit_log = 0;
1702 else
1704 length_or = ~length_or;
1705 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1706 length_unit_log++;
1708 printf ("int length_unit_log = %u;\n", length_unit_log);
1711 /* Take a COND expression and see if any of the conditions in it can be
1712 simplified. If any are known true or known false for the particular insn
1713 code, the COND can be further simplified.
1715 Also call ourselves on any COND operations that are values of this COND.
1717 We do not modify EXP; rather, we make and return a new rtx. */
1719 static rtx
1720 simplify_cond (rtx exp, int insn_code, int insn_index)
1722 int i, j;
1723 /* We store the desired contents here,
1724 then build a new expression if they don't match EXP. */
1725 rtx defval = XEXP (exp, 1);
1726 rtx new_defval = XEXP (exp, 1);
1727 int len = XVECLEN (exp, 0);
1728 rtx *tests = xmalloc (len * sizeof (rtx));
1729 int allsame = 1;
1730 rtx ret;
1732 /* This lets us free all storage allocated below, if appropriate. */
1733 obstack_finish (rtl_obstack);
1735 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1737 /* See if default value needs simplification. */
1738 if (GET_CODE (defval) == COND)
1739 new_defval = simplify_cond (defval, insn_code, insn_index);
1741 /* Simplify the subexpressions, and see what tests we can get rid of. */
1743 for (i = 0; i < len; i += 2)
1745 rtx newtest, newval;
1747 /* Simplify this test. */
1748 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1749 tests[i] = newtest;
1751 newval = tests[i + 1];
1752 /* See if this value may need simplification. */
1753 if (GET_CODE (newval) == COND)
1754 newval = simplify_cond (newval, insn_code, insn_index);
1756 /* Look for ways to delete or combine this test. */
1757 if (newtest == true_rtx)
1759 /* If test is true, make this value the default
1760 and discard this + any following tests. */
1761 len = i;
1762 defval = tests[i + 1];
1763 new_defval = newval;
1766 else if (newtest == false_rtx)
1768 /* If test is false, discard it and its value. */
1769 for (j = i; j < len - 2; j++)
1770 tests[j] = tests[j + 2];
1771 i -= 2;
1772 len -= 2;
1775 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1777 /* If this value and the value for the prev test are the same,
1778 merge the tests. */
1780 tests[i - 2]
1781 = insert_right_side (IOR, tests[i - 2], newtest,
1782 insn_code, insn_index);
1784 /* Delete this test/value. */
1785 for (j = i; j < len - 2; j++)
1786 tests[j] = tests[j + 2];
1787 len -= 2;
1788 i -= 2;
1791 else
1792 tests[i + 1] = newval;
1795 /* If the last test in a COND has the same value
1796 as the default value, that test isn't needed. */
1798 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1799 len -= 2;
1801 /* See if we changed anything. */
1802 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1803 allsame = 0;
1804 else
1805 for (i = 0; i < len; i++)
1806 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1808 allsame = 0;
1809 break;
1812 if (len == 0)
1814 if (GET_CODE (defval) == COND)
1815 ret = simplify_cond (defval, insn_code, insn_index);
1816 else
1817 ret = defval;
1819 else if (allsame)
1820 ret = exp;
1821 else
1823 rtx newexp = rtx_alloc (COND);
1825 XVEC (newexp, 0) = rtvec_alloc (len);
1826 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1827 XEXP (newexp, 1) = new_defval;
1828 ret = newexp;
1830 free (tests);
1831 return ret;
1834 /* Remove an insn entry from an attribute value. */
1836 static void
1837 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1839 struct insn_ent *previe;
1841 if (av->first_insn == ie)
1842 av->first_insn = ie->next;
1843 else
1845 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1847 previe->next = ie->next;
1850 av->num_insns--;
1851 if (ie->def->insn_code == -1)
1852 av->has_asm_insn = 0;
1854 num_insn_ents--;
1857 /* Insert an insn entry in an attribute value list. */
1859 static void
1860 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1862 ie->next = av->first_insn;
1863 av->first_insn = ie;
1864 av->num_insns++;
1865 if (ie->def->insn_code == -1)
1866 av->has_asm_insn = 1;
1868 num_insn_ents++;
1871 /* This is a utility routine to take an expression that is a tree of either
1872 AND or IOR expressions and insert a new term. The new term will be
1873 inserted at the right side of the first node whose code does not match
1874 the root. A new node will be created with the root's code. Its left
1875 side will be the old right side and its right side will be the new
1876 term.
1878 If the `term' is itself a tree, all its leaves will be inserted. */
1880 static rtx
1881 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1883 rtx newexp;
1885 /* Avoid consing in some special cases. */
1886 if (code == AND && term == true_rtx)
1887 return exp;
1888 if (code == AND && term == false_rtx)
1889 return false_rtx;
1890 if (code == AND && exp == true_rtx)
1891 return term;
1892 if (code == AND && exp == false_rtx)
1893 return false_rtx;
1894 if (code == IOR && term == true_rtx)
1895 return true_rtx;
1896 if (code == IOR && term == false_rtx)
1897 return exp;
1898 if (code == IOR && exp == true_rtx)
1899 return true_rtx;
1900 if (code == IOR && exp == false_rtx)
1901 return term;
1902 if (attr_equal_p (exp, term))
1903 return exp;
1905 if (GET_CODE (term) == code)
1907 exp = insert_right_side (code, exp, XEXP (term, 0),
1908 insn_code, insn_index);
1909 exp = insert_right_side (code, exp, XEXP (term, 1),
1910 insn_code, insn_index);
1912 return exp;
1915 if (GET_CODE (exp) == code)
1917 rtx new = insert_right_side (code, XEXP (exp, 1),
1918 term, insn_code, insn_index);
1919 if (new != XEXP (exp, 1))
1920 /* Make a copy of this expression and call recursively. */
1921 newexp = attr_rtx (code, XEXP (exp, 0), new);
1922 else
1923 newexp = exp;
1925 else
1927 /* Insert the new term. */
1928 newexp = attr_rtx (code, exp, term);
1931 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1934 /* If we have an expression which AND's a bunch of
1935 (not (eq_attrq "alternative" "n"))
1936 terms, we may have covered all or all but one of the possible alternatives.
1937 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1939 This routine is passed an expression and either AND or IOR. It returns a
1940 bitmask indicating which alternatives are mentioned within EXP. */
1942 static int
1943 compute_alternative_mask (rtx exp, enum rtx_code code)
1945 const char *string;
1946 if (GET_CODE (exp) == code)
1947 return compute_alternative_mask (XEXP (exp, 0), code)
1948 | compute_alternative_mask (XEXP (exp, 1), code);
1950 else if (code == AND && GET_CODE (exp) == NOT
1951 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1952 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1953 string = XSTR (XEXP (exp, 0), 1);
1955 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1956 && XSTR (exp, 0) == alternative_name)
1957 string = XSTR (exp, 1);
1959 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1961 if (code == AND && XINT (exp, 1))
1962 return XINT (exp, 0);
1964 if (code == IOR && !XINT (exp, 1))
1965 return XINT (exp, 0);
1967 return 0;
1969 else
1970 return 0;
1972 if (string[1] == 0)
1973 return 1 << (string[0] - '0');
1974 return 1 << atoi (string);
1977 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1978 attribute with the value represented by that bit. */
1980 static rtx
1981 make_alternative_compare (int mask)
1983 return mk_attr_alt (mask);
1986 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1987 of "attr" for this insn code. From that value, we can compute a test
1988 showing when the EQ_ATTR will be true. This routine performs that
1989 computation. If a test condition involves an address, we leave the EQ_ATTR
1990 intact because addresses are only valid for the `length' attribute.
1992 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1993 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1995 static rtx
1996 evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
1998 rtx orexp, andexp;
1999 rtx right;
2000 rtx newexp;
2001 int i;
2003 switch (GET_CODE (value))
2005 case CONST_STRING:
2006 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
2007 newexp = true_rtx;
2008 else
2009 newexp = false_rtx;
2010 break;
2012 case SYMBOL_REF:
2014 char *p;
2015 char string[256];
2017 gcc_assert (GET_CODE (exp) == EQ_ATTR);
2018 gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
2019 <= 256);
2021 strcpy (string, XSTR (exp, 0));
2022 strcat (string, "_");
2023 strcat (string, XSTR (exp, 1));
2024 for (p = string; *p; p++)
2025 *p = TOUPPER (*p);
2027 newexp = attr_rtx (EQ, value,
2028 attr_rtx (SYMBOL_REF,
2029 DEF_ATTR_STRING (string)));
2030 break;
2033 case COND:
2034 /* We construct an IOR of all the cases for which the
2035 requested attribute value is present. Since we start with
2036 FALSE, if it is not present, FALSE will be returned.
2038 Each case is the AND of the NOT's of the previous conditions with the
2039 current condition; in the default case the current condition is TRUE.
2041 For each possible COND value, call ourselves recursively.
2043 The extra TRUE and FALSE expressions will be eliminated by another
2044 call to the simplification routine. */
2046 orexp = false_rtx;
2047 andexp = true_rtx;
2049 if (current_alternative_string)
2050 clear_struct_flag (value);
2052 for (i = 0; i < XVECLEN (value, 0); i += 2)
2054 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2055 insn_code, insn_index);
2057 SIMPLIFY_ALTERNATIVE (this);
2059 right = insert_right_side (AND, andexp, this,
2060 insn_code, insn_index);
2061 right = insert_right_side (AND, right,
2062 evaluate_eq_attr (exp,
2063 XVECEXP (value, 0,
2064 i + 1),
2065 insn_code, insn_index),
2066 insn_code, insn_index);
2067 orexp = insert_right_side (IOR, orexp, right,
2068 insn_code, insn_index);
2070 /* Add this condition into the AND expression. */
2071 newexp = attr_rtx (NOT, this);
2072 andexp = insert_right_side (AND, andexp, newexp,
2073 insn_code, insn_index);
2076 /* Handle the default case. */
2077 right = insert_right_side (AND, andexp,
2078 evaluate_eq_attr (exp, XEXP (value, 1),
2079 insn_code, insn_index),
2080 insn_code, insn_index);
2081 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2082 break;
2084 default:
2085 gcc_unreachable ();
2088 /* If uses an address, must return original expression. But set the
2089 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2091 address_used = 0;
2092 walk_attr_value (newexp);
2094 if (address_used)
2096 /* This had `&& current_alternative_string', which seems to be wrong. */
2097 if (! ATTR_IND_SIMPLIFIED_P (exp))
2098 return copy_rtx_unchanging (exp);
2099 return exp;
2101 else
2102 return newexp;
2105 /* This routine is called when an AND of a term with a tree of AND's is
2106 encountered. If the term or its complement is present in the tree, it
2107 can be replaced with TRUE or FALSE, respectively.
2109 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2110 be true and hence are complementary.
2112 There is one special case: If we see
2113 (and (not (eq_attr "att" "v1"))
2114 (eq_attr "att" "v2"))
2115 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2116 replace the term, not anything in the AND tree. So we pass a pointer to
2117 the term. */
2119 static rtx
2120 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2122 rtx left, right;
2123 rtx newexp;
2124 rtx temp;
2125 int left_eliminates_term, right_eliminates_term;
2127 if (GET_CODE (exp) == AND)
2129 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2130 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2131 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2133 newexp = attr_rtx (AND, left, right);
2135 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2139 else if (GET_CODE (exp) == IOR)
2141 /* For the IOR case, we do the same as above, except that we can
2142 only eliminate `term' if both sides of the IOR would do so. */
2143 temp = *pterm;
2144 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2145 left_eliminates_term = (temp == true_rtx);
2147 temp = *pterm;
2148 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2149 right_eliminates_term = (temp == true_rtx);
2151 if (left_eliminates_term && right_eliminates_term)
2152 *pterm = true_rtx;
2154 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2156 newexp = attr_rtx (IOR, left, right);
2158 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2162 /* Check for simplifications. Do some extra checking here since this
2163 routine is called so many times. */
2165 if (exp == *pterm)
2166 return true_rtx;
2168 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2169 return false_rtx;
2171 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2172 return false_rtx;
2174 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2176 if (attr_alt_subset_p (*pterm, exp))
2177 return true_rtx;
2179 if (attr_alt_subset_of_compl_p (*pterm, exp))
2180 return false_rtx;
2182 if (attr_alt_subset_p (exp, *pterm))
2183 *pterm = true_rtx;
2185 return exp;
2188 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2190 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2191 return exp;
2193 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2194 return true_rtx;
2195 else
2196 return false_rtx;
2199 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2200 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2202 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2203 return exp;
2205 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2206 return false_rtx;
2207 else
2208 return true_rtx;
2211 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2212 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2214 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2215 return exp;
2217 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2218 return false_rtx;
2219 else
2220 *pterm = true_rtx;
2223 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2225 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2226 return true_rtx;
2229 else if (GET_CODE (exp) == NOT)
2231 if (attr_equal_p (XEXP (exp, 0), *pterm))
2232 return false_rtx;
2235 else if (GET_CODE (*pterm) == NOT)
2237 if (attr_equal_p (XEXP (*pterm, 0), exp))
2238 return false_rtx;
2241 else if (attr_equal_p (exp, *pterm))
2242 return true_rtx;
2244 return exp;
2247 /* Similar to `simplify_and_tree', but for IOR trees. */
2249 static rtx
2250 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2252 rtx left, right;
2253 rtx newexp;
2254 rtx temp;
2255 int left_eliminates_term, right_eliminates_term;
2257 if (GET_CODE (exp) == IOR)
2259 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2260 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2261 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2263 newexp = attr_rtx (GET_CODE (exp), left, right);
2265 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2269 else if (GET_CODE (exp) == AND)
2271 /* For the AND case, we do the same as above, except that we can
2272 only eliminate `term' if both sides of the AND would do so. */
2273 temp = *pterm;
2274 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2275 left_eliminates_term = (temp == false_rtx);
2277 temp = *pterm;
2278 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2279 right_eliminates_term = (temp == false_rtx);
2281 if (left_eliminates_term && right_eliminates_term)
2282 *pterm = false_rtx;
2284 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2286 newexp = attr_rtx (GET_CODE (exp), left, right);
2288 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2292 if (attr_equal_p (exp, *pterm))
2293 return false_rtx;
2295 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2296 return true_rtx;
2298 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2299 return true_rtx;
2301 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2302 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2303 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2304 *pterm = false_rtx;
2306 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2307 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2308 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2309 return false_rtx;
2311 return exp;
2314 /* Compute approximate cost of the expression. Used to decide whether
2315 expression is cheap enough for inline. */
2316 static int
2317 attr_rtx_cost (rtx x)
2319 int cost = 0;
2320 enum rtx_code code;
2321 if (!x)
2322 return 0;
2323 code = GET_CODE (x);
2324 switch (code)
2326 case MATCH_OPERAND:
2327 if (XSTR (x, 1)[0])
2328 return 10;
2329 else
2330 return 0;
2332 case EQ_ATTR_ALT:
2333 return 0;
2335 case EQ_ATTR:
2336 /* Alternatives don't result into function call. */
2337 if (!strcmp_check (XSTR (x, 0), alternative_name))
2338 return 0;
2339 else
2340 return 5;
2341 default:
2343 int i, j;
2344 const char *fmt = GET_RTX_FORMAT (code);
2345 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2347 switch (fmt[i])
2349 case 'V':
2350 case 'E':
2351 for (j = 0; j < XVECLEN (x, i); j++)
2352 cost += attr_rtx_cost (XVECEXP (x, i, j));
2353 break;
2354 case 'e':
2355 cost += attr_rtx_cost (XEXP (x, i));
2356 break;
2360 break;
2362 return cost;
2365 /* Simplify test expression and use temporary obstack in order to avoid
2366 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2367 and avoid unnecessary copying if possible. */
2369 static rtx
2370 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2372 rtx x;
2373 struct obstack *old;
2374 if (ATTR_IND_SIMPLIFIED_P (exp))
2375 return exp;
2376 old = rtl_obstack;
2377 rtl_obstack = temp_obstack;
2378 x = simplify_test_exp (exp, insn_code, insn_index);
2379 rtl_obstack = old;
2380 if (x == exp || rtl_obstack == temp_obstack)
2381 return x;
2382 return attr_copy_rtx (x);
2385 /* Returns true if S1 is a subset of S2. */
2387 static bool
2388 attr_alt_subset_p (rtx s1, rtx s2)
2390 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2392 case (0 << 1) | 0:
2393 return !(XINT (s1, 0) &~ XINT (s2, 0));
2395 case (0 << 1) | 1:
2396 return !(XINT (s1, 0) & XINT (s2, 0));
2398 case (1 << 1) | 0:
2399 return false;
2401 case (1 << 1) | 1:
2402 return !(XINT (s2, 0) &~ XINT (s1, 0));
2404 default:
2405 gcc_unreachable ();
2409 /* Returns true if S1 is a subset of complement of S2. */
2411 static bool
2412 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2414 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2416 case (0 << 1) | 0:
2417 return !(XINT (s1, 0) & XINT (s2, 0));
2419 case (0 << 1) | 1:
2420 return !(XINT (s1, 0) & ~XINT (s2, 0));
2422 case (1 << 1) | 0:
2423 return !(XINT (s2, 0) &~ XINT (s1, 0));
2425 case (1 << 1) | 1:
2426 return false;
2428 default:
2429 gcc_unreachable ();
2433 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2435 static rtx
2436 attr_alt_intersection (rtx s1, rtx s2)
2438 rtx result = rtx_alloc (EQ_ATTR_ALT);
2440 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2442 case (0 << 1) | 0:
2443 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2444 break;
2445 case (0 << 1) | 1:
2446 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2447 break;
2448 case (1 << 1) | 0:
2449 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2450 break;
2451 case (1 << 1) | 1:
2452 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2453 break;
2454 default:
2455 gcc_unreachable ();
2457 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2459 return result;
2462 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2464 static rtx
2465 attr_alt_union (rtx s1, rtx s2)
2467 rtx result = rtx_alloc (EQ_ATTR_ALT);
2469 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2471 case (0 << 1) | 0:
2472 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2473 break;
2474 case (0 << 1) | 1:
2475 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2476 break;
2477 case (1 << 1) | 0:
2478 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2479 break;
2480 case (1 << 1) | 1:
2481 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2482 break;
2483 default:
2484 gcc_unreachable ();
2487 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2488 return result;
2491 /* Return EQ_ATTR_ALT expression representing complement of S. */
2493 static rtx
2494 attr_alt_complement (rtx s)
2496 rtx result = rtx_alloc (EQ_ATTR_ALT);
2498 XINT (result, 0) = XINT (s, 0);
2499 XINT (result, 1) = 1 - XINT (s, 1);
2501 return result;
2504 /* Tests whether a bit B belongs to the set represented by S. */
2506 static bool
2507 attr_alt_bit_p (rtx s, int b)
2509 return XINT (s, 1) ^ ((XINT (s, 0) >> b) & 1);
2512 /* Return EQ_ATTR_ALT expression representing set containing elements set
2513 in E. */
2515 static rtx
2516 mk_attr_alt (int e)
2518 rtx result = rtx_alloc (EQ_ATTR_ALT);
2520 XINT (result, 0) = e;
2521 XINT (result, 1) = 0;
2523 return result;
2526 /* Given an expression, see if it can be simplified for a particular insn
2527 code based on the values of other attributes being tested. This can
2528 eliminate nested get_attr_... calls.
2530 Note that if an endless recursion is specified in the patterns, the
2531 optimization will loop. However, it will do so in precisely the cases where
2532 an infinite recursion loop could occur during compilation. It's better that
2533 it occurs here! */
2535 static rtx
2536 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2538 rtx left, right;
2539 struct attr_desc *attr;
2540 struct attr_value *av;
2541 struct insn_ent *ie;
2542 int i;
2543 rtx newexp = exp;
2544 bool left_alt, right_alt;
2546 /* Don't re-simplify something we already simplified. */
2547 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2548 return exp;
2550 switch (GET_CODE (exp))
2552 case AND:
2553 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2554 SIMPLIFY_ALTERNATIVE (left);
2555 if (left == false_rtx)
2556 return false_rtx;
2557 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2558 SIMPLIFY_ALTERNATIVE (right);
2559 if (left == false_rtx)
2560 return false_rtx;
2562 if (GET_CODE (left) == EQ_ATTR_ALT
2563 && GET_CODE (right) == EQ_ATTR_ALT)
2565 exp = attr_alt_intersection (left, right);
2566 return simplify_test_exp (exp, insn_code, insn_index);
2569 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2570 present on both sides, apply the distributive law since this will
2571 yield simplifications. */
2572 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2573 && compute_alternative_mask (left, IOR)
2574 && compute_alternative_mask (right, IOR))
2576 if (GET_CODE (left) == IOR)
2578 rtx tem = left;
2579 left = right;
2580 right = tem;
2583 newexp = attr_rtx (IOR,
2584 attr_rtx (AND, left, XEXP (right, 0)),
2585 attr_rtx (AND, left, XEXP (right, 1)));
2587 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2590 /* Try with the term on both sides. */
2591 right = simplify_and_tree (right, &left, insn_code, insn_index);
2592 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2593 left = simplify_and_tree (left, &right, insn_code, insn_index);
2595 if (left == false_rtx || right == false_rtx)
2596 return false_rtx;
2597 else if (left == true_rtx)
2599 return right;
2601 else if (right == true_rtx)
2603 return left;
2605 /* See if all or all but one of the insn's alternatives are specified
2606 in this tree. Optimize if so. */
2608 if (GET_CODE (left) == NOT)
2609 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2610 && XSTR (XEXP (left, 0), 0) == alternative_name);
2611 else
2612 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2613 && XINT (left, 1));
2615 if (GET_CODE (right) == NOT)
2616 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2617 && XSTR (XEXP (right, 0), 0) == alternative_name);
2618 else
2619 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2620 && XINT (right, 1));
2622 if (insn_code >= 0
2623 && (GET_CODE (left) == AND
2624 || left_alt
2625 || GET_CODE (right) == AND
2626 || right_alt))
2628 i = compute_alternative_mask (exp, AND);
2629 if (i & ~insn_alternatives[insn_code])
2630 fatal ("invalid alternative specified for pattern number %d",
2631 insn_index);
2633 /* If all alternatives are excluded, this is false. */
2634 i ^= insn_alternatives[insn_code];
2635 if (i == 0)
2636 return false_rtx;
2637 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2639 /* If just one excluded, AND a comparison with that one to the
2640 front of the tree. The others will be eliminated by
2641 optimization. We do not want to do this if the insn has one
2642 alternative and we have tested none of them! */
2643 left = make_alternative_compare (i);
2644 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2645 newexp = attr_rtx (AND, left, right);
2647 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2651 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2653 newexp = attr_rtx (AND, left, right);
2654 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2656 break;
2658 case IOR:
2659 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2660 SIMPLIFY_ALTERNATIVE (left);
2661 if (left == true_rtx)
2662 return true_rtx;
2663 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2664 SIMPLIFY_ALTERNATIVE (right);
2665 if (right == true_rtx)
2666 return true_rtx;
2668 if (GET_CODE (left) == EQ_ATTR_ALT
2669 && GET_CODE (right) == EQ_ATTR_ALT)
2671 exp = attr_alt_union (left, right);
2672 return simplify_test_exp (exp, insn_code, insn_index);
2675 right = simplify_or_tree (right, &left, insn_code, insn_index);
2676 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2677 left = simplify_or_tree (left, &right, insn_code, insn_index);
2679 if (right == true_rtx || left == true_rtx)
2680 return true_rtx;
2681 else if (left == false_rtx)
2683 return right;
2685 else if (right == false_rtx)
2687 return left;
2690 /* Test for simple cases where the distributive law is useful. I.e.,
2691 convert (ior (and (x) (y))
2692 (and (x) (z)))
2693 to (and (x)
2694 (ior (y) (z)))
2697 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2698 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2700 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2702 left = XEXP (left, 0);
2703 right = newexp;
2704 newexp = attr_rtx (AND, left, right);
2705 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2708 /* See if all or all but one of the insn's alternatives are specified
2709 in this tree. Optimize if so. */
2711 else if (insn_code >= 0
2712 && (GET_CODE (left) == IOR
2713 || (GET_CODE (left) == EQ_ATTR_ALT
2714 && !XINT (left, 1))
2715 || (GET_CODE (left) == EQ_ATTR
2716 && XSTR (left, 0) == alternative_name)
2717 || GET_CODE (right) == IOR
2718 || (GET_CODE (right) == EQ_ATTR_ALT
2719 && !XINT (right, 1))
2720 || (GET_CODE (right) == EQ_ATTR
2721 && XSTR (right, 0) == alternative_name)))
2723 i = compute_alternative_mask (exp, IOR);
2724 if (i & ~insn_alternatives[insn_code])
2725 fatal ("invalid alternative specified for pattern number %d",
2726 insn_index);
2728 /* If all alternatives are included, this is true. */
2729 i ^= insn_alternatives[insn_code];
2730 if (i == 0)
2731 return true_rtx;
2732 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2734 /* If just one excluded, IOR a comparison with that one to the
2735 front of the tree. The others will be eliminated by
2736 optimization. We do not want to do this if the insn has one
2737 alternative and we have tested none of them! */
2738 left = make_alternative_compare (i);
2739 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2740 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2742 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2746 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2748 newexp = attr_rtx (IOR, left, right);
2749 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2751 break;
2753 case NOT:
2754 if (GET_CODE (XEXP (exp, 0)) == NOT)
2756 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2757 insn_code, insn_index);
2758 SIMPLIFY_ALTERNATIVE (left);
2759 return left;
2762 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2763 SIMPLIFY_ALTERNATIVE (left);
2764 if (GET_CODE (left) == NOT)
2765 return XEXP (left, 0);
2767 if (left == false_rtx)
2768 return true_rtx;
2769 if (left == true_rtx)
2770 return false_rtx;
2772 if (GET_CODE (left) == EQ_ATTR_ALT)
2774 exp = attr_alt_complement (left);
2775 return simplify_test_exp (exp, insn_code, insn_index);
2778 /* Try to apply De`Morgan's laws. */
2779 if (GET_CODE (left) == IOR)
2781 newexp = attr_rtx (AND,
2782 attr_rtx (NOT, XEXP (left, 0)),
2783 attr_rtx (NOT, XEXP (left, 1)));
2785 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2787 else if (GET_CODE (left) == AND)
2789 newexp = attr_rtx (IOR,
2790 attr_rtx (NOT, XEXP (left, 0)),
2791 attr_rtx (NOT, XEXP (left, 1)));
2793 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2795 else if (left != XEXP (exp, 0))
2797 newexp = attr_rtx (NOT, left);
2799 break;
2801 case EQ_ATTR_ALT:
2802 if (current_alternative_string)
2803 return attr_alt_bit_p (exp, atoi (current_alternative_string)) ? true_rtx : false_rtx;
2805 if (!XINT (exp, 0))
2806 return XINT (exp, 1) ? true_rtx : false_rtx;
2807 break;
2809 case EQ_ATTR:
2810 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
2811 return (XSTR (exp, 1) == current_alternative_string
2812 ? true_rtx : false_rtx);
2814 if (XSTR (exp, 0) == alternative_name)
2816 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2817 break;
2820 /* Look at the value for this insn code in the specified attribute.
2821 We normally can replace this comparison with the condition that
2822 would give this insn the values being tested for. */
2823 if (XSTR (exp, 0) != alternative_name
2824 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2825 for (av = attr->first_value; av; av = av->next)
2826 for (ie = av->first_insn; ie; ie = ie->next)
2827 if (ie->def->insn_code == insn_code)
2829 rtx x;
2830 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2831 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2832 if (attr_rtx_cost(x) < 20)
2833 return x;
2835 break;
2837 default:
2838 break;
2841 /* We have already simplified this expression. Simplifying it again
2842 won't buy anything unless we weren't given a valid insn code
2843 to process (i.e., we are canonicalizing something.). */
2844 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
2845 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2846 return copy_rtx_unchanging (newexp);
2848 return newexp;
2851 /* Optimize the attribute lists by seeing if we can determine conditional
2852 values from the known values of other attributes. This will save subroutine
2853 calls during the compilation. */
2855 static void
2856 optimize_attrs (void)
2858 struct attr_desc *attr;
2859 struct attr_value *av;
2860 struct insn_ent *ie;
2861 rtx newexp;
2862 int i;
2863 struct attr_value_list
2865 struct attr_value *av;
2866 struct insn_ent *ie;
2867 struct attr_desc *attr;
2868 struct attr_value_list *next;
2870 struct attr_value_list **insn_code_values;
2871 struct attr_value_list *ivbuf;
2872 struct attr_value_list *iv;
2874 /* For each insn code, make a list of all the insn_ent's for it,
2875 for all values for all attributes. */
2877 if (num_insn_ents == 0)
2878 return;
2880 /* Make 2 extra elements, for "code" values -2 and -1. */
2881 insn_code_values = xcalloc ((insn_code_number + 2),
2882 sizeof (struct attr_value_list *));
2884 /* Offset the table address so we can index by -2 or -1. */
2885 insn_code_values += 2;
2887 iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
2889 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2890 for (attr = attrs[i]; attr; attr = attr->next)
2891 for (av = attr->first_value; av; av = av->next)
2892 for (ie = av->first_insn; ie; ie = ie->next)
2894 iv->attr = attr;
2895 iv->av = av;
2896 iv->ie = ie;
2897 iv->next = insn_code_values[ie->def->insn_code];
2898 insn_code_values[ie->def->insn_code] = iv;
2899 iv++;
2902 /* Sanity check on num_insn_ents. */
2903 gcc_assert (iv == ivbuf + num_insn_ents);
2905 /* Process one insn code at a time. */
2906 for (i = -2; i < insn_code_number; i++)
2908 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2909 We use it to mean "already simplified for this insn". */
2910 for (iv = insn_code_values[i]; iv; iv = iv->next)
2911 clear_struct_flag (iv->av->value);
2913 for (iv = insn_code_values[i]; iv; iv = iv->next)
2915 struct obstack *old = rtl_obstack;
2917 attr = iv->attr;
2918 av = iv->av;
2919 ie = iv->ie;
2920 if (GET_CODE (av->value) != COND)
2921 continue;
2923 rtl_obstack = temp_obstack;
2924 newexp = av->value;
2925 while (GET_CODE (newexp) == COND)
2927 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2928 ie->def->insn_index);
2929 if (newexp2 == newexp)
2930 break;
2931 newexp = newexp2;
2934 rtl_obstack = old;
2935 if (newexp != av->value)
2937 newexp = attr_copy_rtx (newexp);
2938 remove_insn_ent (av, ie);
2939 av = get_attr_value (newexp, attr, ie->def->insn_code);
2940 iv->av = av;
2941 insert_insn_ent (av, ie);
2946 free (ivbuf);
2947 free (insn_code_values - 2);
2950 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2952 static void
2953 clear_struct_flag (rtx x)
2955 int i;
2956 int j;
2957 enum rtx_code code;
2958 const char *fmt;
2960 ATTR_CURR_SIMPLIFIED_P (x) = 0;
2961 if (ATTR_IND_SIMPLIFIED_P (x))
2962 return;
2964 code = GET_CODE (x);
2966 switch (code)
2968 case REG:
2969 case CONST_INT:
2970 case CONST_DOUBLE:
2971 case CONST_VECTOR:
2972 case SYMBOL_REF:
2973 case CODE_LABEL:
2974 case PC:
2975 case CC0:
2976 case EQ_ATTR:
2977 case ATTR_FLAG:
2978 return;
2980 default:
2981 break;
2984 /* Compare the elements. If any pair of corresponding elements
2985 fail to match, return 0 for the whole things. */
2987 fmt = GET_RTX_FORMAT (code);
2988 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2990 switch (fmt[i])
2992 case 'V':
2993 case 'E':
2994 for (j = 0; j < XVECLEN (x, i); j++)
2995 clear_struct_flag (XVECEXP (x, i, j));
2996 break;
2998 case 'e':
2999 clear_struct_flag (XEXP (x, i));
3000 break;
3005 /* Create table entries for DEFINE_ATTR. */
3007 static void
3008 gen_attr (rtx exp, int lineno)
3010 struct attr_desc *attr;
3011 struct attr_value *av;
3012 const char *name_ptr;
3013 char *p;
3015 /* Make a new attribute structure. Check for duplicate by looking at
3016 attr->default_val, since it is initialized by this routine. */
3017 attr = find_attr (&XSTR (exp, 0), 1);
3018 if (attr->default_val)
3020 message_with_line (lineno, "duplicate definition for attribute %s",
3021 attr->name);
3022 message_with_line (attr->lineno, "previous definition");
3023 have_error = 1;
3024 return;
3026 attr->lineno = lineno;
3028 if (*XSTR (exp, 1) == '\0')
3029 attr->is_numeric = 1;
3030 else
3032 name_ptr = XSTR (exp, 1);
3033 while ((p = next_comma_elt (&name_ptr)) != NULL)
3035 av = oballoc (sizeof (struct attr_value));
3036 av->value = attr_rtx (CONST_STRING, p);
3037 av->next = attr->first_value;
3038 attr->first_value = av;
3039 av->first_insn = NULL;
3040 av->num_insns = 0;
3041 av->has_asm_insn = 0;
3045 if (GET_CODE (XEXP (exp, 2)) == CONST)
3047 attr->is_const = 1;
3048 if (attr->is_numeric)
3050 message_with_line (lineno,
3051 "constant attributes may not take numeric values");
3052 have_error = 1;
3055 /* Get rid of the CONST node. It is allowed only at top-level. */
3056 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3059 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
3061 message_with_line (lineno,
3062 "`length' attribute must take numeric values");
3063 have_error = 1;
3066 /* Set up the default value. */
3067 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
3068 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3071 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3072 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3073 number of alternatives as this should be checked elsewhere. */
3075 static int
3076 count_alternatives (rtx exp)
3078 int i, j, n;
3079 const char *fmt;
3081 if (GET_CODE (exp) == MATCH_OPERAND)
3082 return n_comma_elts (XSTR (exp, 2));
3084 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3085 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3086 switch (*fmt++)
3088 case 'e':
3089 case 'u':
3090 n = count_alternatives (XEXP (exp, i));
3091 if (n)
3092 return n;
3093 break;
3095 case 'E':
3096 case 'V':
3097 if (XVEC (exp, i) != NULL)
3098 for (j = 0; j < XVECLEN (exp, i); j++)
3100 n = count_alternatives (XVECEXP (exp, i, j));
3101 if (n)
3102 return n;
3106 return 0;
3109 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3110 `alternative' attribute. */
3112 static int
3113 compares_alternatives_p (rtx exp)
3115 int i, j;
3116 const char *fmt;
3118 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3119 return 1;
3121 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3122 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3123 switch (*fmt++)
3125 case 'e':
3126 case 'u':
3127 if (compares_alternatives_p (XEXP (exp, i)))
3128 return 1;
3129 break;
3131 case 'E':
3132 for (j = 0; j < XVECLEN (exp, i); j++)
3133 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3134 return 1;
3135 break;
3138 return 0;
3141 /* Returns nonzero is INNER is contained in EXP. */
3143 static int
3144 contained_in_p (rtx inner, rtx exp)
3146 int i, j;
3147 const char *fmt;
3149 if (rtx_equal_p (inner, exp))
3150 return 1;
3152 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3153 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3154 switch (*fmt++)
3156 case 'e':
3157 case 'u':
3158 if (contained_in_p (inner, XEXP (exp, i)))
3159 return 1;
3160 break;
3162 case 'E':
3163 for (j = 0; j < XVECLEN (exp, i); j++)
3164 if (contained_in_p (inner, XVECEXP (exp, i, j)))
3165 return 1;
3166 break;
3169 return 0;
3172 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3174 static void
3175 gen_insn (rtx exp, int lineno)
3177 struct insn_def *id;
3179 id = oballoc (sizeof (struct insn_def));
3180 id->next = defs;
3181 defs = id;
3182 id->def = exp;
3183 id->lineno = lineno;
3185 switch (GET_CODE (exp))
3187 case DEFINE_INSN:
3188 id->insn_code = insn_code_number;
3189 id->insn_index = insn_index_number;
3190 id->num_alternatives = count_alternatives (exp);
3191 if (id->num_alternatives == 0)
3192 id->num_alternatives = 1;
3193 id->vec_idx = 4;
3194 break;
3196 case DEFINE_PEEPHOLE:
3197 id->insn_code = insn_code_number;
3198 id->insn_index = insn_index_number;
3199 id->num_alternatives = count_alternatives (exp);
3200 if (id->num_alternatives == 0)
3201 id->num_alternatives = 1;
3202 id->vec_idx = 3;
3203 break;
3205 case DEFINE_ASM_ATTRIBUTES:
3206 id->insn_code = -1;
3207 id->insn_index = -1;
3208 id->num_alternatives = 1;
3209 id->vec_idx = 0;
3210 got_define_asm_attributes = 1;
3211 break;
3213 default:
3214 gcc_unreachable ();
3218 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3219 true or annul false is specified, and make a `struct delay_desc'. */
3221 static void
3222 gen_delay (rtx def, int lineno)
3224 struct delay_desc *delay;
3225 int i;
3227 if (XVECLEN (def, 1) % 3 != 0)
3229 message_with_line (lineno,
3230 "number of elements in DEFINE_DELAY must be multiple of three");
3231 have_error = 1;
3232 return;
3235 for (i = 0; i < XVECLEN (def, 1); i += 3)
3237 if (XVECEXP (def, 1, i + 1))
3238 have_annul_true = 1;
3239 if (XVECEXP (def, 1, i + 2))
3240 have_annul_false = 1;
3243 delay = oballoc (sizeof (struct delay_desc));
3244 delay->def = def;
3245 delay->num = ++num_delays;
3246 delay->next = delays;
3247 delay->lineno = lineno;
3248 delays = delay;
3251 /* Given a piece of RTX, print a C expression to test its truth value.
3252 We use AND and IOR both for logical and bit-wise operations, so
3253 interpret them as logical unless they are inside a comparison expression.
3254 The first bit of FLAGS will be nonzero in that case.
3256 Set the second bit of FLAGS to make references to attribute values use
3257 a cached local variable instead of calling a function. */
3259 static void
3260 write_test_expr (rtx exp, int flags)
3262 int comparison_operator = 0;
3263 RTX_CODE code;
3264 struct attr_desc *attr;
3266 /* In order not to worry about operator precedence, surround our part of
3267 the expression with parentheses. */
3269 printf ("(");
3270 code = GET_CODE (exp);
3271 switch (code)
3273 /* Binary operators. */
3274 case GEU: case GTU:
3275 case LEU: case LTU:
3276 printf ("(unsigned) ");
3277 /* Fall through. */
3279 case EQ: case NE:
3280 case GE: case GT:
3281 case LE: case LT:
3282 comparison_operator = 1;
3284 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3285 case AND: case IOR: case XOR:
3286 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3287 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
3288 switch (code)
3290 case EQ:
3291 printf (" == ");
3292 break;
3293 case NE:
3294 printf (" != ");
3295 break;
3296 case GE:
3297 printf (" >= ");
3298 break;
3299 case GT:
3300 printf (" > ");
3301 break;
3302 case GEU:
3303 printf (" >= (unsigned) ");
3304 break;
3305 case GTU:
3306 printf (" > (unsigned) ");
3307 break;
3308 case LE:
3309 printf (" <= ");
3310 break;
3311 case LT:
3312 printf (" < ");
3313 break;
3314 case LEU:
3315 printf (" <= (unsigned) ");
3316 break;
3317 case LTU:
3318 printf (" < (unsigned) ");
3319 break;
3320 case PLUS:
3321 printf (" + ");
3322 break;
3323 case MINUS:
3324 printf (" - ");
3325 break;
3326 case MULT:
3327 printf (" * ");
3328 break;
3329 case DIV:
3330 printf (" / ");
3331 break;
3332 case MOD:
3333 printf (" %% ");
3334 break;
3335 case AND:
3336 if (flags & 1)
3337 printf (" & ");
3338 else
3339 printf (" && ");
3340 break;
3341 case IOR:
3342 if (flags & 1)
3343 printf (" | ");
3344 else
3345 printf (" || ");
3346 break;
3347 case XOR:
3348 printf (" ^ ");
3349 break;
3350 case ASHIFT:
3351 printf (" << ");
3352 break;
3353 case LSHIFTRT:
3354 case ASHIFTRT:
3355 printf (" >> ");
3356 break;
3357 default:
3358 gcc_unreachable ();
3361 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
3362 break;
3364 case NOT:
3365 /* Special-case (not (eq_attrq "alternative" "x")) */
3366 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3367 && XSTR (XEXP (exp, 0), 0) == alternative_name)
3369 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3370 break;
3373 /* Otherwise, fall through to normal unary operator. */
3375 /* Unary operators. */
3376 case ABS: case NEG:
3377 switch (code)
3379 case NOT:
3380 if (flags & 1)
3381 printf ("~ ");
3382 else
3383 printf ("! ");
3384 break;
3385 case ABS:
3386 printf ("abs ");
3387 break;
3388 case NEG:
3389 printf ("-");
3390 break;
3391 default:
3392 gcc_unreachable ();
3395 write_test_expr (XEXP (exp, 0), flags);
3396 break;
3398 case EQ_ATTR_ALT:
3400 int set = XINT (exp, 0), bit = 0;
3402 if (flags & 1)
3403 fatal ("EQ_ATTR_ALT not valid inside comparison");
3405 if (!set)
3406 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3408 if (!(set & (set - 1)))
3410 if (!(set & 0xffff))
3412 bit += 16;
3413 set >>= 16;
3415 if (!(set & 0xff))
3417 bit += 8;
3418 set >>= 8;
3420 if (!(set & 0xf))
3422 bit += 4;
3423 set >>= 4;
3425 if (!(set & 0x3))
3427 bit += 2;
3428 set >>= 2;
3430 if (!(set & 1))
3431 bit++;
3433 printf ("which_alternative %s= %d",
3434 XINT (exp, 1) ? "!" : "=", bit);
3436 else
3438 printf ("%s((1 << which_alternative) & 0x%x)",
3439 XINT (exp, 1) ? "!" : "", set);
3442 break;
3444 /* Comparison test of an attribute with a value. Most of these will
3445 have been removed by optimization. Handle "alternative"
3446 specially and give error if EQ_ATTR present inside a comparison. */
3447 case EQ_ATTR:
3448 if (flags & 1)
3449 fatal ("EQ_ATTR not valid inside comparison");
3451 if (XSTR (exp, 0) == alternative_name)
3453 printf ("which_alternative == %s", XSTR (exp, 1));
3454 break;
3457 attr = find_attr (&XSTR (exp, 0), 0);
3458 gcc_assert (attr);
3460 /* Now is the time to expand the value of a constant attribute. */
3461 if (attr->is_const)
3463 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
3464 -2, -2),
3465 flags);
3467 else
3469 if (flags & 2)
3470 printf ("attr_%s", attr->name);
3471 else
3472 printf ("get_attr_%s (insn)", attr->name);
3473 printf (" == ");
3474 write_attr_valueq (attr, XSTR (exp, 1));
3476 break;
3478 /* Comparison test of flags for define_delays. */
3479 case ATTR_FLAG:
3480 if (flags & 1)
3481 fatal ("ATTR_FLAG not valid inside comparison");
3482 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3483 break;
3485 /* See if an operand matches a predicate. */
3486 case MATCH_OPERAND:
3487 /* If only a mode is given, just ensure the mode matches the operand.
3488 If neither a mode nor predicate is given, error. */
3489 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3491 if (GET_MODE (exp) == VOIDmode)
3492 fatal ("null MATCH_OPERAND specified as test");
3493 else
3494 printf ("GET_MODE (operands[%d]) == %smode",
3495 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3497 else
3498 printf ("%s (operands[%d], %smode)",
3499 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3500 break;
3502 /* Constant integer. */
3503 case CONST_INT:
3504 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3505 break;
3507 /* A random C expression. */
3508 case SYMBOL_REF:
3509 print_c_condition (XSTR (exp, 0));
3510 break;
3512 /* The address of the branch target. */
3513 case MATCH_DUP:
3514 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3515 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3516 break;
3518 case PC:
3519 /* The address of the current insn. We implement this actually as the
3520 address of the current insn for backward branches, but the last
3521 address of the next insn for forward branches, and both with
3522 adjustments that account for the worst-case possible stretching of
3523 intervening alignments between this insn and its destination. */
3524 printf ("insn_current_reference_address (insn)");
3525 break;
3527 case CONST_STRING:
3528 printf ("%s", XSTR (exp, 0));
3529 break;
3531 case IF_THEN_ELSE:
3532 write_test_expr (XEXP (exp, 0), flags & 2);
3533 printf (" ? ");
3534 write_test_expr (XEXP (exp, 1), flags | 1);
3535 printf (" : ");
3536 write_test_expr (XEXP (exp, 2), flags | 1);
3537 break;
3539 default:
3540 fatal ("bad RTX code `%s' in attribute calculation\n",
3541 GET_RTX_NAME (code));
3544 printf (")");
3547 /* Given an attribute value, return the maximum CONST_STRING argument
3548 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3550 static int
3551 max_attr_value (rtx exp, int *unknownp)
3553 int current_max;
3554 int i, n;
3556 switch (GET_CODE (exp))
3558 case CONST_STRING:
3559 current_max = atoi (XSTR (exp, 0));
3560 break;
3562 case COND:
3563 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3564 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3566 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3567 if (n > current_max)
3568 current_max = n;
3570 break;
3572 case IF_THEN_ELSE:
3573 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3574 n = max_attr_value (XEXP (exp, 2), unknownp);
3575 if (n > current_max)
3576 current_max = n;
3577 break;
3579 default:
3580 *unknownp = 1;
3581 current_max = INT_MAX;
3582 break;
3585 return current_max;
3588 /* Given an attribute value, return the result of ORing together all
3589 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3590 if the numeric value is not known. */
3592 static int
3593 or_attr_value (rtx exp, int *unknownp)
3595 int current_or;
3596 int i;
3598 switch (GET_CODE (exp))
3600 case CONST_STRING:
3601 current_or = atoi (XSTR (exp, 0));
3602 break;
3604 case COND:
3605 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3606 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3607 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3608 break;
3610 case IF_THEN_ELSE:
3611 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3612 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3613 break;
3615 default:
3616 *unknownp = 1;
3617 current_or = -1;
3618 break;
3621 return current_or;
3624 /* Scan an attribute value, possibly a conditional, and record what actions
3625 will be required to do any conditional tests in it.
3627 Specifically, set
3628 `must_extract' if we need to extract the insn operands
3629 `must_constrain' if we must compute `which_alternative'
3630 `address_used' if an address expression was used
3631 `length_used' if an (eq_attr "length" ...) was used
3634 static void
3635 walk_attr_value (rtx exp)
3637 int i, j;
3638 const char *fmt;
3639 RTX_CODE code;
3641 if (exp == NULL)
3642 return;
3644 code = GET_CODE (exp);
3645 switch (code)
3647 case SYMBOL_REF:
3648 if (! ATTR_IND_SIMPLIFIED_P (exp))
3649 /* Since this is an arbitrary expression, it can look at anything.
3650 However, constant expressions do not depend on any particular
3651 insn. */
3652 must_extract = must_constrain = 1;
3653 return;
3655 case MATCH_OPERAND:
3656 must_extract = 1;
3657 return;
3659 case EQ_ATTR_ALT:
3660 must_extract = must_constrain = 1;
3661 break;
3663 case EQ_ATTR:
3664 if (XSTR (exp, 0) == alternative_name)
3665 must_extract = must_constrain = 1;
3666 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3667 length_used = 1;
3668 return;
3670 case MATCH_DUP:
3671 must_extract = 1;
3672 address_used = 1;
3673 return;
3675 case PC:
3676 address_used = 1;
3677 return;
3679 case ATTR_FLAG:
3680 return;
3682 default:
3683 break;
3686 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3687 switch (*fmt++)
3689 case 'e':
3690 case 'u':
3691 walk_attr_value (XEXP (exp, i));
3692 break;
3694 case 'E':
3695 if (XVEC (exp, i) != NULL)
3696 for (j = 0; j < XVECLEN (exp, i); j++)
3697 walk_attr_value (XVECEXP (exp, i, j));
3698 break;
3702 /* Write out a function to obtain the attribute for a given INSN. */
3704 static void
3705 write_attr_get (struct attr_desc *attr)
3707 struct attr_value *av, *common_av;
3709 /* Find the most used attribute value. Handle that as the `default' of the
3710 switch we will generate. */
3711 common_av = find_most_used (attr);
3713 /* Write out start of function, then all values with explicit `case' lines,
3714 then a `default', then the value with the most uses. */
3715 if (attr->static_p)
3716 printf ("static ");
3717 if (!attr->is_numeric)
3718 printf ("enum attr_%s\n", attr->name);
3719 else if (attr->unsigned_p)
3720 printf ("unsigned int\n");
3721 else
3722 printf ("int\n");
3724 /* If the attribute name starts with a star, the remainder is the name of
3725 the subroutine to use, instead of `get_attr_...'. */
3726 if (attr->name[0] == '*')
3727 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3728 else if (attr->is_const == 0)
3729 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3730 else
3732 printf ("get_attr_%s (void)\n", attr->name);
3733 printf ("{\n");
3735 for (av = attr->first_value; av; av = av->next)
3736 if (av->num_insns != 0)
3737 write_attr_set (attr, 2, av->value, "return", ";",
3738 true_rtx, av->first_insn->def->insn_code,
3739 av->first_insn->def->insn_index);
3741 printf ("}\n\n");
3742 return;
3745 printf ("{\n");
3746 printf (" switch (recog_memoized (insn))\n");
3747 printf (" {\n");
3749 for (av = attr->first_value; av; av = av->next)
3750 if (av != common_av)
3751 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3753 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3754 printf (" }\n}\n\n");
3757 /* Given an AND tree of known true terms (because we are inside an `if' with
3758 that as the condition or are in an `else' clause) and an expression,
3759 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3760 the bulk of the work. */
3762 static rtx
3763 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
3765 rtx term;
3767 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3769 if (GET_CODE (known_true) == AND)
3771 exp = eliminate_known_true (XEXP (known_true, 0), exp,
3772 insn_code, insn_index);
3773 exp = eliminate_known_true (XEXP (known_true, 1), exp,
3774 insn_code, insn_index);
3776 else
3778 term = known_true;
3779 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3782 return exp;
3785 /* Write out a series of tests and assignment statements to perform tests and
3786 sets of an attribute value. We are passed an indentation amount and prefix
3787 and suffix strings to write around each attribute value (e.g., "return"
3788 and ";"). */
3790 static void
3791 write_attr_set (struct attr_desc *attr, int indent, rtx value,
3792 const char *prefix, const char *suffix, rtx known_true,
3793 int insn_code, int insn_index)
3795 if (GET_CODE (value) == COND)
3797 /* Assume the default value will be the default of the COND unless we
3798 find an always true expression. */
3799 rtx default_val = XEXP (value, 1);
3800 rtx our_known_true = known_true;
3801 rtx newexp;
3802 int first_if = 1;
3803 int i;
3805 for (i = 0; i < XVECLEN (value, 0); i += 2)
3807 rtx testexp;
3808 rtx inner_true;
3810 testexp = eliminate_known_true (our_known_true,
3811 XVECEXP (value, 0, i),
3812 insn_code, insn_index);
3813 newexp = attr_rtx (NOT, testexp);
3814 newexp = insert_right_side (AND, our_known_true, newexp,
3815 insn_code, insn_index);
3817 /* If the test expression is always true or if the next `known_true'
3818 expression is always false, this is the last case, so break
3819 out and let this value be the `else' case. */
3820 if (testexp == true_rtx || newexp == false_rtx)
3822 default_val = XVECEXP (value, 0, i + 1);
3823 break;
3826 /* Compute the expression to pass to our recursive call as being
3827 known true. */
3828 inner_true = insert_right_side (AND, our_known_true,
3829 testexp, insn_code, insn_index);
3831 /* If this is always false, skip it. */
3832 if (inner_true == false_rtx)
3833 continue;
3835 write_indent (indent);
3836 printf ("%sif ", first_if ? "" : "else ");
3837 first_if = 0;
3838 write_test_expr (testexp, 0);
3839 printf ("\n");
3840 write_indent (indent + 2);
3841 printf ("{\n");
3843 write_attr_set (attr, indent + 4,
3844 XVECEXP (value, 0, i + 1), prefix, suffix,
3845 inner_true, insn_code, insn_index);
3846 write_indent (indent + 2);
3847 printf ("}\n");
3848 our_known_true = newexp;
3851 if (! first_if)
3853 write_indent (indent);
3854 printf ("else\n");
3855 write_indent (indent + 2);
3856 printf ("{\n");
3859 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3860 prefix, suffix, our_known_true, insn_code, insn_index);
3862 if (! first_if)
3864 write_indent (indent + 2);
3865 printf ("}\n");
3868 else
3870 write_indent (indent);
3871 printf ("%s ", prefix);
3872 write_attr_value (attr, value);
3873 printf ("%s\n", suffix);
3877 /* Write a series of case statements for every instruction in list IE.
3878 INDENT is the amount of indentation to write before each case. */
3880 static void
3881 write_insn_cases (struct insn_ent *ie, int indent)
3883 for (; ie != 0; ie = ie->next)
3884 if (ie->def->insn_code != -1)
3886 write_indent (indent);
3887 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
3888 printf ("case %d: /* define_peephole, line %d */\n",
3889 ie->def->insn_code, ie->def->lineno);
3890 else
3891 printf ("case %d: /* %s */\n",
3892 ie->def->insn_code, XSTR (ie->def->def, 0));
3896 /* Write out the computation for one attribute value. */
3898 static void
3899 write_attr_case (struct attr_desc *attr, struct attr_value *av,
3900 int write_case_lines, const char *prefix, const char *suffix,
3901 int indent, rtx known_true)
3903 if (av->num_insns == 0)
3904 return;
3906 if (av->has_asm_insn)
3908 write_indent (indent);
3909 printf ("case -1:\n");
3910 write_indent (indent + 2);
3911 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3912 write_indent (indent + 2);
3913 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3914 write_indent (indent + 2);
3915 printf (" fatal_insn_not_found (insn);\n");
3918 if (write_case_lines)
3919 write_insn_cases (av->first_insn, indent);
3920 else
3922 write_indent (indent);
3923 printf ("default:\n");
3926 /* See what we have to do to output this value. */
3927 must_extract = must_constrain = address_used = 0;
3928 walk_attr_value (av->value);
3930 if (must_constrain)
3932 write_indent (indent + 2);
3933 printf ("extract_constrain_insn_cached (insn);\n");
3935 else if (must_extract)
3937 write_indent (indent + 2);
3938 printf ("extract_insn_cached (insn);\n");
3941 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3942 known_true, av->first_insn->def->insn_code,
3943 av->first_insn->def->insn_index);
3945 if (strncmp (prefix, "return", 6))
3947 write_indent (indent + 2);
3948 printf ("break;\n");
3950 printf ("\n");
3953 /* Search for uses of non-const attributes and write code to cache them. */
3955 static int
3956 write_expr_attr_cache (rtx p, struct attr_desc *attr)
3958 const char *fmt;
3959 int i, ie, j, je;
3961 if (GET_CODE (p) == EQ_ATTR)
3963 if (XSTR (p, 0) != attr->name)
3964 return 0;
3966 if (!attr->is_numeric)
3967 printf (" enum attr_%s ", attr->name);
3968 else if (attr->unsigned_p)
3969 printf (" unsigned int ");
3970 else
3971 printf (" int ");
3973 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
3974 return 1;
3977 fmt = GET_RTX_FORMAT (GET_CODE (p));
3978 ie = GET_RTX_LENGTH (GET_CODE (p));
3979 for (i = 0; i < ie; i++)
3981 switch (*fmt++)
3983 case 'e':
3984 if (write_expr_attr_cache (XEXP (p, i), attr))
3985 return 1;
3986 break;
3988 case 'E':
3989 je = XVECLEN (p, i);
3990 for (j = 0; j < je; ++j)
3991 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
3992 return 1;
3993 break;
3997 return 0;
4000 /* Utilities to write in various forms. */
4002 static void
4003 write_attr_valueq (struct attr_desc *attr, const char *s)
4005 if (attr->is_numeric)
4007 int num = atoi (s);
4009 printf ("%d", num);
4011 if (num > 9 || num < 0)
4012 printf (" /* 0x%x */", num);
4014 else
4016 write_upcase (attr->name);
4017 printf ("_");
4018 write_upcase (s);
4022 static void
4023 write_attr_value (struct attr_desc *attr, rtx value)
4025 int op;
4027 switch (GET_CODE (value))
4029 case CONST_STRING:
4030 write_attr_valueq (attr, XSTR (value, 0));
4031 break;
4033 case CONST_INT:
4034 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4035 break;
4037 case SYMBOL_REF:
4038 print_c_condition (XSTR (value, 0));
4039 break;
4041 case ATTR:
4043 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4044 printf ("get_attr_%s (%s)", attr2->name,
4045 (attr2->is_const ? "" : "insn"));
4047 break;
4049 case PLUS:
4050 op = '+';
4051 goto do_operator;
4052 case MINUS:
4053 op = '-';
4054 goto do_operator;
4055 case MULT:
4056 op = '*';
4057 goto do_operator;
4058 case DIV:
4059 op = '/';
4060 goto do_operator;
4061 case MOD:
4062 op = '%';
4063 goto do_operator;
4065 do_operator:
4066 write_attr_value (attr, XEXP (value, 0));
4067 putchar (' ');
4068 putchar (op);
4069 putchar (' ');
4070 write_attr_value (attr, XEXP (value, 1));
4071 break;
4073 default:
4074 gcc_unreachable ();
4078 static void
4079 write_upcase (const char *str)
4081 while (*str)
4083 /* The argument of TOUPPER should not have side effects. */
4084 putchar (TOUPPER(*str));
4085 str++;
4089 static void
4090 write_indent (int indent)
4092 for (; indent > 8; indent -= 8)
4093 printf ("\t");
4095 for (; indent; indent--)
4096 printf (" ");
4099 /* Write a subroutine that is given an insn that requires a delay slot, a
4100 delay slot ordinal, and a candidate insn. It returns nonzero if the
4101 candidate can be placed in the specified delay slot of the insn.
4103 We can write as many as three subroutines. `eligible_for_delay'
4104 handles normal delay slots, `eligible_for_annul_true' indicates that
4105 the specified insn can be annulled if the branch is true, and likewise
4106 for `eligible_for_annul_false'.
4108 KIND is a string distinguishing these three cases ("delay", "annul_true",
4109 or "annul_false"). */
4111 static void
4112 write_eligible_delay (const char *kind)
4114 struct delay_desc *delay;
4115 int max_slots;
4116 char str[50];
4117 const char *pstr;
4118 struct attr_desc *attr;
4119 struct attr_value *av, *common_av;
4120 int i;
4122 /* Compute the maximum number of delay slots required. We use the delay
4123 ordinal times this number plus one, plus the slot number as an index into
4124 the appropriate predicate to test. */
4126 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4127 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4128 max_slots = XVECLEN (delay->def, 1) / 3;
4130 /* Write function prelude. */
4132 printf ("int\n");
4133 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4134 kind);
4135 printf ("{\n");
4136 printf (" rtx insn;\n");
4137 printf ("\n");
4138 printf (" gcc_assert (slot < %d);\n", max_slots);
4139 printf ("\n");
4140 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4141 converts a compound instruction into a loop. */
4142 printf (" if (!INSN_P (candidate_insn))\n");
4143 printf (" return 0;\n");
4144 printf ("\n");
4146 /* If more than one delay type, find out which type the delay insn is. */
4148 if (num_delays > 1)
4150 attr = find_attr (&delay_type_str, 0);
4151 gcc_assert (attr);
4152 common_av = find_most_used (attr);
4154 printf (" insn = delay_insn;\n");
4155 printf (" switch (recog_memoized (insn))\n");
4156 printf (" {\n");
4158 sprintf (str, " * %d;\n break;", max_slots);
4159 for (av = attr->first_value; av; av = av->next)
4160 if (av != common_av)
4161 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4163 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4164 printf (" }\n\n");
4166 /* Ensure matched. Otherwise, shouldn't have been called. */
4167 printf (" gcc_assert (slot >= %d);\n\n", max_slots);
4170 /* If just one type of delay slot, write simple switch. */
4171 if (num_delays == 1 && max_slots == 1)
4173 printf (" insn = candidate_insn;\n");
4174 printf (" switch (recog_memoized (insn))\n");
4175 printf (" {\n");
4177 attr = find_attr (&delay_1_0_str, 0);
4178 gcc_assert (attr);
4179 common_av = find_most_used (attr);
4181 for (av = attr->first_value; av; av = av->next)
4182 if (av != common_av)
4183 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4185 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4186 printf (" }\n");
4189 else
4191 /* Write a nested CASE. The first indicates which condition we need to
4192 test, and the inner CASE tests the condition. */
4193 printf (" insn = candidate_insn;\n");
4194 printf (" switch (slot)\n");
4195 printf (" {\n");
4197 for (delay = delays; delay; delay = delay->next)
4198 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4200 printf (" case %d:\n",
4201 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4202 printf (" switch (recog_memoized (insn))\n");
4203 printf ("\t{\n");
4205 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4206 pstr = str;
4207 attr = find_attr (&pstr, 0);
4208 gcc_assert (attr);
4209 common_av = find_most_used (attr);
4211 for (av = attr->first_value; av; av = av->next)
4212 if (av != common_av)
4213 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4215 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4216 printf (" }\n");
4219 printf (" default:\n");
4220 printf (" gcc_unreachable ();\n");
4221 printf (" }\n");
4224 printf ("}\n\n");
4227 /* This page contains miscellaneous utility routines. */
4229 /* Given a pointer to a (char *), return a malloc'ed string containing the
4230 next comma-separated element. Advance the pointer to after the string
4231 scanned, or the end-of-string. Return NULL if at end of string. */
4233 static char *
4234 next_comma_elt (const char **pstr)
4236 const char *start;
4238 start = scan_comma_elt (pstr);
4240 if (start == NULL)
4241 return NULL;
4243 return attr_string (start, *pstr - start);
4246 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4247 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4248 replaced by a pointer to a canonical copy of the string. */
4250 static struct attr_desc *
4251 find_attr (const char **name_p, int create)
4253 struct attr_desc *attr;
4254 int index;
4255 const char *name = *name_p;
4257 /* Before we resort to using `strcmp', see if the string address matches
4258 anywhere. In most cases, it should have been canonicalized to do so. */
4259 if (name == alternative_name)
4260 return NULL;
4262 index = name[0] & (MAX_ATTRS_INDEX - 1);
4263 for (attr = attrs[index]; attr; attr = attr->next)
4264 if (name == attr->name)
4265 return attr;
4267 /* Otherwise, do it the slow way. */
4268 for (attr = attrs[index]; attr; attr = attr->next)
4269 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4271 *name_p = attr->name;
4272 return attr;
4275 if (! create)
4276 return NULL;
4278 attr = oballoc (sizeof (struct attr_desc));
4279 attr->name = DEF_ATTR_STRING (name);
4280 attr->first_value = attr->default_val = NULL;
4281 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
4282 attr->unsigned_p = attr->static_p = 0;
4283 attr->next = attrs[index];
4284 attrs[index] = attr;
4286 *name_p = attr->name;
4288 return attr;
4291 /* Create internal attribute with the given default value. */
4293 void
4294 make_internal_attr (const char *name, rtx value, int special)
4296 struct attr_desc *attr;
4298 attr = find_attr (&name, 1);
4299 gcc_assert (!attr->default_val);
4301 attr->is_numeric = 1;
4302 attr->is_const = 0;
4303 attr->is_special = (special & ATTR_SPECIAL) != 0;
4304 attr->negative_ok = (special & ATTR_NEGATIVE_OK) != 0;
4305 attr->unsigned_p = (special & ATTR_UNSIGNED) != 0;
4306 attr->static_p = (special & ATTR_STATIC) != 0;
4307 attr->default_val = get_attr_value (value, attr, -2);
4310 /* Find the most used value of an attribute. */
4312 static struct attr_value *
4313 find_most_used (struct attr_desc *attr)
4315 struct attr_value *av;
4316 struct attr_value *most_used;
4317 int nuses;
4319 most_used = NULL;
4320 nuses = -1;
4322 for (av = attr->first_value; av; av = av->next)
4323 if (av->num_insns > nuses)
4324 nuses = av->num_insns, most_used = av;
4326 return most_used;
4329 /* Return (attr_value "n") */
4332 make_numeric_value (int n)
4334 static rtx int_values[20];
4335 rtx exp;
4336 char *p;
4338 gcc_assert (n >= 0);
4340 if (n < 20 && int_values[n])
4341 return int_values[n];
4343 p = attr_printf (MAX_DIGITS, "%d", n);
4344 exp = attr_rtx (CONST_STRING, p);
4346 if (n < 20)
4347 int_values[n] = exp;
4349 return exp;
4352 static rtx
4353 copy_rtx_unchanging (rtx orig)
4355 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4356 return orig;
4358 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4359 return orig;
4362 /* Determine if an insn has a constant number of delay slots, i.e., the
4363 number of delay slots is not a function of the length of the insn. */
4365 static void
4366 write_const_num_delay_slots (void)
4368 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4369 struct attr_value *av;
4371 if (attr)
4373 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4374 printf ("{\n");
4375 printf (" switch (recog_memoized (insn))\n");
4376 printf (" {\n");
4378 for (av = attr->first_value; av; av = av->next)
4380 length_used = 0;
4381 walk_attr_value (av->value);
4382 if (length_used)
4383 write_insn_cases (av->first_insn, 4);
4386 printf (" default:\n");
4387 printf (" return 1;\n");
4388 printf (" }\n}\n\n");
4393 main (int argc, char **argv)
4395 rtx desc;
4396 struct attr_desc *attr;
4397 struct insn_def *id;
4398 rtx tem;
4399 int i;
4401 progname = "genattrtab";
4403 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
4404 return (FATAL_EXIT_CODE);
4406 obstack_init (hash_obstack);
4407 obstack_init (temp_obstack);
4409 /* Set up true and false rtx's */
4410 true_rtx = rtx_alloc (CONST_INT);
4411 XWINT (true_rtx, 0) = 1;
4412 false_rtx = rtx_alloc (CONST_INT);
4413 XWINT (false_rtx, 0) = 0;
4414 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4415 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
4417 alternative_name = DEF_ATTR_STRING ("alternative");
4418 length_str = DEF_ATTR_STRING ("length");
4419 delay_type_str = DEF_ATTR_STRING ("*delay_type");
4420 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4421 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
4423 printf ("/* Generated automatically by the program `genattrtab'\n\
4424 from the machine description file `md'. */\n\n");
4426 /* Read the machine description. */
4428 initiate_automaton_gen (argc, argv);
4429 while (1)
4431 int lineno;
4433 desc = read_md_rtx (&lineno, &insn_code_number);
4434 if (desc == NULL)
4435 break;
4437 switch (GET_CODE (desc))
4439 case DEFINE_INSN:
4440 case DEFINE_PEEPHOLE:
4441 case DEFINE_ASM_ATTRIBUTES:
4442 gen_insn (desc, lineno);
4443 break;
4445 case DEFINE_ATTR:
4446 gen_attr (desc, lineno);
4447 break;
4449 case DEFINE_DELAY:
4450 gen_delay (desc, lineno);
4451 break;
4453 case DEFINE_CPU_UNIT:
4454 gen_cpu_unit (desc);
4455 break;
4457 case DEFINE_QUERY_CPU_UNIT:
4458 gen_query_cpu_unit (desc);
4459 break;
4461 case DEFINE_BYPASS:
4462 gen_bypass (desc);
4463 break;
4465 case EXCLUSION_SET:
4466 gen_excl_set (desc);
4467 break;
4469 case PRESENCE_SET:
4470 gen_presence_set (desc);
4471 break;
4473 case FINAL_PRESENCE_SET:
4474 gen_final_presence_set (desc);
4475 break;
4477 case ABSENCE_SET:
4478 gen_absence_set (desc);
4479 break;
4481 case FINAL_ABSENCE_SET:
4482 gen_final_absence_set (desc);
4483 break;
4485 case DEFINE_AUTOMATON:
4486 gen_automaton (desc);
4487 break;
4489 case AUTOMATA_OPTION:
4490 gen_automata_option (desc);
4491 break;
4493 case DEFINE_RESERVATION:
4494 gen_reserv (desc);
4495 break;
4497 case DEFINE_INSN_RESERVATION:
4498 gen_insn_reserv (desc);
4499 break;
4501 default:
4502 break;
4504 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
4505 insn_index_number++;
4508 if (have_error)
4509 return FATAL_EXIT_CODE;
4511 insn_code_number++;
4513 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4514 if (! got_define_asm_attributes)
4516 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4517 XVEC (tem, 0) = rtvec_alloc (0);
4518 gen_insn (tem, 0);
4521 /* Expand DEFINE_DELAY information into new attribute. */
4522 if (num_delays)
4523 expand_delays ();
4525 /* Build DFA, output some functions and expand DFA information
4526 to new attributes. */
4527 if (num_dfa_decls)
4528 expand_automata ();
4530 printf ("#include \"config.h\"\n");
4531 printf ("#include \"system.h\"\n");
4532 printf ("#include \"coretypes.h\"\n");
4533 printf ("#include \"tm.h\"\n");
4534 printf ("#include \"rtl.h\"\n");
4535 printf ("#include \"tm_p.h\"\n");
4536 printf ("#include \"insn-config.h\"\n");
4537 printf ("#include \"recog.h\"\n");
4538 printf ("#include \"regs.h\"\n");
4539 printf ("#include \"real.h\"\n");
4540 printf ("#include \"output.h\"\n");
4541 printf ("#include \"insn-attr.h\"\n");
4542 printf ("#include \"toplev.h\"\n");
4543 printf ("#include \"flags.h\"\n");
4544 printf ("#include \"function.h\"\n");
4545 printf ("\n");
4546 printf ("#define operands recog_data.operand\n\n");
4548 /* Make `insn_alternatives'. */
4549 insn_alternatives = oballoc (insn_code_number * sizeof (int));
4550 for (id = defs; id; id = id->next)
4551 if (id->insn_code >= 0)
4552 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4554 /* Make `insn_n_alternatives'. */
4555 insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
4556 for (id = defs; id; id = id->next)
4557 if (id->insn_code >= 0)
4558 insn_n_alternatives[id->insn_code] = id->num_alternatives;
4560 /* Prepare to write out attribute subroutines by checking everything stored
4561 away and building the attribute cases. */
4563 check_defs ();
4565 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4566 for (attr = attrs[i]; attr; attr = attr->next)
4567 attr->default_val->value
4568 = check_attr_value (attr->default_val->value, attr);
4570 if (have_error)
4571 return FATAL_EXIT_CODE;
4573 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4574 for (attr = attrs[i]; attr; attr = attr->next)
4575 fill_attr (attr);
4577 /* Construct extra attributes for `length'. */
4578 make_length_attrs ();
4580 /* Perform any possible optimizations to speed up compilation. */
4581 optimize_attrs ();
4583 /* Now write out all the `gen_attr_...' routines. Do these before the
4584 special routines so that they get defined before they are used. */
4586 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4587 for (attr = attrs[i]; attr; attr = attr->next)
4589 if (! attr->is_special && ! attr->is_const)
4591 int insn_alts_p;
4593 insn_alts_p
4594 = (attr->name [0] == '*'
4595 && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
4596 if (insn_alts_p)
4597 printf ("\n#if AUTOMATON_ALTS\n");
4598 write_attr_get (attr);
4599 if (insn_alts_p)
4600 printf ("#endif\n\n");
4604 /* Write out delay eligibility information, if DEFINE_DELAY present.
4605 (The function to compute the number of delay slots will be written
4606 below.) */
4607 if (num_delays)
4609 write_eligible_delay ("delay");
4610 if (have_annul_true)
4611 write_eligible_delay ("annul_true");
4612 if (have_annul_false)
4613 write_eligible_delay ("annul_false");
4616 /* Output code for pipeline hazards recognition based on DFA
4617 (deterministic finite-state automata). */
4618 if (num_dfa_decls)
4619 write_automata ();
4621 /* Write out constant delay slot info. */
4622 write_const_num_delay_slots ();
4624 write_length_unit_log ();
4626 fflush (stdout);
4627 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
4630 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
4631 const char *
4632 get_insn_name (int code ATTRIBUTE_UNUSED)
4634 return NULL;