In gcc/objc/: 2010-12-29 Nicola Pero <nicola.pero@meta-innovation.com>
[official-gcc.git] / gcc / genattrtab.c
blob497660428c352d97eaa455fa137ccc5f7d872c3c
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
12 version.
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 for more details.
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
34 expression).
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
47 `get_attr_length'.
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
54 used.
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
77 will be written.
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
93 (see attr_rtx). */
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
99 #if 0
100 #define strcmp_check(S1, S2) ((S1) == (S2) \
101 ? 0 \
102 : (gcc_assert (strcmp ((S1), (S2))), 1))
103 #else
104 #define strcmp_check(S1, S2) ((S1) != (S2))
105 #endif
107 #include "bconfig.h"
108 #include "system.h"
109 #include "coretypes.h"
110 #include "tm.h"
111 #include "rtl.h"
112 #include "obstack.h"
113 #include "errors.h"
114 #include "read-md.h"
115 #include "gensupport.h"
116 #include "vecprim.h"
118 /* Flags for make_internal_attr's `special' parameter. */
119 #define ATTR_NONE 0
120 #define ATTR_SPECIAL (1 << 0)
122 static struct obstack obstack1, obstack2;
123 static struct obstack *hash_obstack = &obstack1;
124 static struct obstack *temp_obstack = &obstack2;
126 /* enough space to reserve for printing out ints */
127 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
129 /* Define structures used to record attributes and values. */
131 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
132 encountered, we store all the relevant information into a
133 `struct insn_def'. This is done to allow attribute definitions to occur
134 anywhere in the file. */
136 struct insn_def
138 struct insn_def *next; /* Next insn in chain. */
139 rtx def; /* The DEFINE_... */
140 int insn_code; /* Instruction number. */
141 int insn_index; /* Expression number in file, for errors. */
142 int lineno; /* Line number. */
143 int num_alternatives; /* Number of alternatives. */
144 int vec_idx; /* Index of attribute vector in `def'. */
147 /* Once everything has been read in, we store in each attribute value a list
148 of insn codes that have that value. Here is the structure used for the
149 list. */
151 struct insn_ent
153 struct insn_ent *next; /* Next in chain. */
154 struct insn_def *def; /* Instruction definition. */
157 /* Each value of an attribute (either constant or computed) is assigned a
158 structure which is used as the listhead of the insns that have that
159 value. */
161 struct attr_value
163 rtx value; /* Value of attribute. */
164 struct attr_value *next; /* Next attribute value in chain. */
165 struct insn_ent *first_insn; /* First insn with this value. */
166 int num_insns; /* Number of insns with this value. */
167 int has_asm_insn; /* True if this value used for `asm' insns */
170 /* Structure for each attribute. */
172 struct attr_desc
174 char *name; /* Name of attribute. */
175 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */
176 struct attr_desc *next; /* Next attribute. */
177 struct attr_value *first_value; /* First value of this attribute. */
178 struct attr_value *default_val; /* Default value for this attribute. */
179 int lineno : 24; /* Line number. */
180 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
181 unsigned is_const : 1; /* Attribute value constant for each run. */
182 unsigned is_special : 1; /* Don't call `write_attr_set'. */
185 /* Structure for each DEFINE_DELAY. */
187 struct delay_desc
189 rtx def; /* DEFINE_DELAY expression. */
190 struct delay_desc *next; /* Next DEFINE_DELAY. */
191 int num; /* Number of DEFINE_DELAY, starting at 1. */
192 int lineno; /* Line number. */
195 struct attr_value_list
197 struct attr_value *av;
198 struct insn_ent *ie;
199 struct attr_desc *attr;
200 struct attr_value_list *next;
203 /* Listheads of above structures. */
205 /* This one is indexed by the first character of the attribute name. */
206 #define MAX_ATTRS_INDEX 256
207 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
208 static struct insn_def *defs;
209 static struct delay_desc *delays;
210 struct attr_value_list **insn_code_values;
212 /* Other variables. */
214 static int insn_code_number;
215 static int insn_index_number;
216 static int got_define_asm_attributes;
217 static int must_extract;
218 static int must_constrain;
219 static int address_used;
220 static int length_used;
221 static int num_delays;
222 static int have_annul_true, have_annul_false;
223 static int num_insn_ents;
225 /* Stores, for each insn code, the number of constraint alternatives. */
227 static int *insn_n_alternatives;
229 /* Stores, for each insn code, a bitmap that has bits on for each possible
230 alternative. */
232 static int *insn_alternatives;
234 /* Used to simplify expressions. */
236 static rtx true_rtx, false_rtx;
238 /* Used to reduce calls to `strcmp' */
240 static const char *alternative_name;
241 static const char *length_str;
242 static const char *delay_type_str;
243 static const char *delay_1_0_str;
244 static const char *num_delay_slots_str;
246 /* Simplify an expression. Only call the routine if there is something to
247 simplify. */
248 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
249 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
250 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
252 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
254 /* Forward declarations of functions used before their definitions, only. */
255 static char *attr_string (const char *, int);
256 static char *attr_printf (unsigned int, const char *, ...)
257 ATTRIBUTE_PRINTF_2;
258 static rtx make_numeric_value (int);
259 static struct attr_desc *find_attr (const char **, int);
260 static rtx mk_attr_alt (int);
261 static char *next_comma_elt (const char **);
262 static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
263 static rtx copy_boolean (rtx);
264 static int compares_alternatives_p (rtx);
265 static void make_internal_attr (const char *, rtx, int);
266 static void insert_insn_ent (struct attr_value *, struct insn_ent *);
267 static void walk_attr_value (rtx);
268 static int max_attr_value (rtx, int*);
269 static int min_attr_value (rtx, int*);
270 static int or_attr_value (rtx, int*);
271 static rtx simplify_test_exp (rtx, int, int);
272 static rtx simplify_test_exp_in_temp (rtx, int, int);
273 static rtx copy_rtx_unchanging (rtx);
274 static bool attr_alt_subset_p (rtx, rtx);
275 static bool attr_alt_subset_of_compl_p (rtx, rtx);
276 static void clear_struct_flag (rtx);
277 static void write_attr_valueq (struct attr_desc *, const char *);
278 static struct attr_value *find_most_used (struct attr_desc *);
279 static void write_attr_set (struct attr_desc *, int, rtx,
280 const char *, const char *, rtx,
281 int, int, unsigned int);
282 static void write_attr_case (struct attr_desc *, struct attr_value *,
283 int, const char *, const char *, int, rtx);
284 static void write_attr_value (struct attr_desc *, rtx);
285 static void write_upcase (const char *);
286 static void write_indent (int);
287 static rtx identity_fn (rtx);
288 static rtx zero_fn (rtx);
289 static rtx one_fn (rtx);
290 static rtx max_fn (rtx);
291 static rtx min_fn (rtx);
293 #define oballoc(T) XOBNEW (hash_obstack, T)
294 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
296 /* Hash table for sharing RTL and strings. */
298 /* Each hash table slot is a bucket containing a chain of these structures.
299 Strings are given negative hash codes; RTL expressions are given positive
300 hash codes. */
302 struct attr_hash
304 struct attr_hash *next; /* Next structure in the bucket. */
305 int hashcode; /* Hash code of this rtx or string. */
306 union
308 char *str; /* The string (negative hash codes) */
309 rtx rtl; /* or the RTL recorded here. */
310 } u;
313 /* Now here is the hash table. When recording an RTL, it is added to
314 the slot whose index is the hash code mod the table size. Note
315 that the hash table is used for several kinds of RTL (see attr_rtx)
316 and for strings. While all these live in the same table, they are
317 completely independent, and the hash code is computed differently
318 for each. */
320 #define RTL_HASH_SIZE 4093
321 static struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
323 /* Here is how primitive or already-shared RTL's hash
324 codes are made. */
325 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
327 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
329 static void
330 attr_hash_add_rtx (int hashcode, rtx rtl)
332 struct attr_hash *h;
334 h = XOBNEW (hash_obstack, struct attr_hash);
335 h->hashcode = hashcode;
336 h->u.rtl = rtl;
337 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
338 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
341 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
343 static void
344 attr_hash_add_string (int hashcode, char *str)
346 struct attr_hash *h;
348 h = XOBNEW (hash_obstack, struct attr_hash);
349 h->hashcode = -hashcode;
350 h->u.str = str;
351 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
352 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
355 /* Generate an RTL expression, but avoid duplicates.
356 Set the ATTR_PERMANENT_P flag for these permanent objects.
358 In some cases we cannot uniquify; then we return an ordinary
359 impermanent rtx with ATTR_PERMANENT_P clear.
361 Args are as follows:
363 rtx attr_rtx (code, [element1, ..., elementn]) */
365 static rtx
366 attr_rtx_1 (enum rtx_code code, va_list p)
368 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
369 int hashcode;
370 struct attr_hash *h;
371 struct obstack *old_obstack = rtl_obstack;
373 /* For each of several cases, search the hash table for an existing entry.
374 Use that entry if one is found; otherwise create a new RTL and add it
375 to the table. */
377 if (GET_RTX_CLASS (code) == RTX_UNARY)
379 rtx arg0 = va_arg (p, rtx);
381 /* A permanent object cannot point to impermanent ones. */
382 if (! ATTR_PERMANENT_P (arg0))
384 rt_val = rtx_alloc (code);
385 XEXP (rt_val, 0) = arg0;
386 return rt_val;
389 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
390 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
391 if (h->hashcode == hashcode
392 && GET_CODE (h->u.rtl) == code
393 && XEXP (h->u.rtl, 0) == arg0)
394 return h->u.rtl;
396 if (h == 0)
398 rtl_obstack = hash_obstack;
399 rt_val = rtx_alloc (code);
400 XEXP (rt_val, 0) = arg0;
403 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
404 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
405 || GET_RTX_CLASS (code) == RTX_COMPARE
406 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
408 rtx arg0 = va_arg (p, rtx);
409 rtx arg1 = va_arg (p, rtx);
411 /* A permanent object cannot point to impermanent ones. */
412 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
414 rt_val = rtx_alloc (code);
415 XEXP (rt_val, 0) = arg0;
416 XEXP (rt_val, 1) = arg1;
417 return rt_val;
420 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
421 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
422 if (h->hashcode == hashcode
423 && GET_CODE (h->u.rtl) == code
424 && XEXP (h->u.rtl, 0) == arg0
425 && XEXP (h->u.rtl, 1) == arg1)
426 return h->u.rtl;
428 if (h == 0)
430 rtl_obstack = hash_obstack;
431 rt_val = rtx_alloc (code);
432 XEXP (rt_val, 0) = arg0;
433 XEXP (rt_val, 1) = arg1;
436 else if (GET_RTX_LENGTH (code) == 1
437 && GET_RTX_FORMAT (code)[0] == 's')
439 char *arg0 = va_arg (p, char *);
441 arg0 = DEF_ATTR_STRING (arg0);
443 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
444 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
445 if (h->hashcode == hashcode
446 && GET_CODE (h->u.rtl) == code
447 && XSTR (h->u.rtl, 0) == arg0)
448 return h->u.rtl;
450 if (h == 0)
452 rtl_obstack = hash_obstack;
453 rt_val = rtx_alloc (code);
454 XSTR (rt_val, 0) = arg0;
457 else if (GET_RTX_LENGTH (code) == 2
458 && GET_RTX_FORMAT (code)[0] == 's'
459 && GET_RTX_FORMAT (code)[1] == 's')
461 char *arg0 = va_arg (p, char *);
462 char *arg1 = va_arg (p, char *);
464 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
465 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
466 if (h->hashcode == hashcode
467 && GET_CODE (h->u.rtl) == code
468 && XSTR (h->u.rtl, 0) == arg0
469 && XSTR (h->u.rtl, 1) == arg1)
470 return h->u.rtl;
472 if (h == 0)
474 rtl_obstack = hash_obstack;
475 rt_val = rtx_alloc (code);
476 XSTR (rt_val, 0) = arg0;
477 XSTR (rt_val, 1) = arg1;
480 else if (code == CONST_INT)
482 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
483 if (arg0 == 0)
484 return false_rtx;
485 else if (arg0 == 1)
486 return true_rtx;
487 else
488 goto nohash;
490 else
492 int i; /* Array indices... */
493 const char *fmt; /* Current rtx's format... */
494 nohash:
495 rt_val = rtx_alloc (code); /* Allocate the storage space. */
497 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
498 for (i = 0; i < GET_RTX_LENGTH (code); i++)
500 switch (*fmt++)
502 case '0': /* Unused field. */
503 break;
505 case 'i': /* An integer? */
506 XINT (rt_val, i) = va_arg (p, int);
507 break;
509 case 'w': /* A wide integer? */
510 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
511 break;
513 case 's': /* A string? */
514 XSTR (rt_val, i) = va_arg (p, char *);
515 break;
517 case 'e': /* An expression? */
518 case 'u': /* An insn? Same except when printing. */
519 XEXP (rt_val, i) = va_arg (p, rtx);
520 break;
522 case 'E': /* An RTX vector? */
523 XVEC (rt_val, i) = va_arg (p, rtvec);
524 break;
526 default:
527 gcc_unreachable ();
530 return rt_val;
533 rtl_obstack = old_obstack;
534 attr_hash_add_rtx (hashcode, rt_val);
535 ATTR_PERMANENT_P (rt_val) = 1;
536 return rt_val;
539 static rtx
540 attr_rtx (enum rtx_code code, ...)
542 rtx result;
543 va_list p;
545 va_start (p, code);
546 result = attr_rtx_1 (code, p);
547 va_end (p);
548 return result;
551 /* Create a new string printed with the printf line arguments into a space
552 of at most LEN bytes:
554 rtx attr_printf (len, format, [arg1, ..., argn]) */
556 static char *
557 attr_printf (unsigned int len, const char *fmt, ...)
559 char str[256];
560 va_list p;
562 va_start (p, fmt);
564 gcc_assert (len < sizeof str); /* Leave room for \0. */
566 vsprintf (str, fmt, p);
567 va_end (p);
569 return DEF_ATTR_STRING (str);
572 static rtx
573 attr_eq (const char *name, const char *value)
575 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
578 static const char *
579 attr_numeral (int n)
581 return XSTR (make_numeric_value (n), 0);
584 /* Return a permanent (possibly shared) copy of a string STR (not assumed
585 to be null terminated) with LEN bytes. */
587 static char *
588 attr_string (const char *str, int len)
590 struct attr_hash *h;
591 int hashcode;
592 int i;
593 char *new_str;
595 /* Compute the hash code. */
596 hashcode = (len + 1) * 613 + (unsigned) str[0];
597 for (i = 1; i < len; i += 2)
598 hashcode = ((hashcode * 613) + (unsigned) str[i]);
599 if (hashcode < 0)
600 hashcode = -hashcode;
602 /* Search the table for the string. */
603 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
604 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
605 && !strncmp (h->u.str, str, len))
606 return h->u.str; /* <-- return if found. */
608 /* Not found; create a permanent copy and add it to the hash table. */
609 new_str = XOBNEWVAR (hash_obstack, char, len + 1);
610 memcpy (new_str, str, len);
611 new_str[len] = '\0';
612 attr_hash_add_string (hashcode, new_str);
614 return new_str; /* Return the new string. */
617 /* Check two rtx's for equality of contents,
618 taking advantage of the fact that if both are hashed
619 then they can't be equal unless they are the same object. */
621 static int
622 attr_equal_p (rtx x, rtx y)
624 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
625 && rtx_equal_p (x, y)));
628 /* Copy an attribute value expression,
629 descending to all depths, but not copying any
630 permanent hashed subexpressions. */
632 static rtx
633 attr_copy_rtx (rtx orig)
635 rtx copy;
636 int i, j;
637 RTX_CODE code;
638 const char *format_ptr;
640 /* No need to copy a permanent object. */
641 if (ATTR_PERMANENT_P (orig))
642 return orig;
644 code = GET_CODE (orig);
646 switch (code)
648 case REG:
649 case CONST_INT:
650 case CONST_DOUBLE:
651 case CONST_VECTOR:
652 case SYMBOL_REF:
653 case CODE_LABEL:
654 case PC:
655 case CC0:
656 return orig;
658 default:
659 break;
662 copy = rtx_alloc (code);
663 PUT_MODE (copy, GET_MODE (orig));
664 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
665 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
666 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
668 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
670 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
672 switch (*format_ptr++)
674 case 'e':
675 XEXP (copy, i) = XEXP (orig, i);
676 if (XEXP (orig, i) != NULL)
677 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
678 break;
680 case 'E':
681 case 'V':
682 XVEC (copy, i) = XVEC (orig, i);
683 if (XVEC (orig, i) != NULL)
685 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
686 for (j = 0; j < XVECLEN (copy, i); j++)
687 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
689 break;
691 case 'n':
692 case 'i':
693 XINT (copy, i) = XINT (orig, i);
694 break;
696 case 'w':
697 XWINT (copy, i) = XWINT (orig, i);
698 break;
700 case 's':
701 case 'S':
702 XSTR (copy, i) = XSTR (orig, i);
703 break;
705 default:
706 gcc_unreachable ();
709 return copy;
712 /* Given a test expression for an attribute, ensure it is validly formed.
713 IS_CONST indicates whether the expression is constant for each compiler
714 run (a constant expression may not test any particular insn).
716 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
717 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
718 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
720 Update the string address in EQ_ATTR expression to be the same used
721 in the attribute (or `alternative_name') to speed up subsequent
722 `find_attr' calls and eliminate most `strcmp' calls.
724 Return the new expression, if any. */
726 static rtx
727 check_attr_test (rtx exp, int is_const, int lineno)
729 struct attr_desc *attr;
730 struct attr_value *av;
731 const char *name_ptr, *p;
732 rtx orexp, newexp;
734 switch (GET_CODE (exp))
736 case EQ_ATTR:
737 /* Handle negation test. */
738 if (XSTR (exp, 1)[0] == '!')
739 return check_attr_test (attr_rtx (NOT,
740 attr_eq (XSTR (exp, 0),
741 &XSTR (exp, 1)[1])),
742 is_const, lineno);
744 else if (n_comma_elts (XSTR (exp, 1)) == 1)
746 attr = find_attr (&XSTR (exp, 0), 0);
747 if (attr == NULL)
749 if (! strcmp (XSTR (exp, 0), "alternative"))
750 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
751 else
752 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
755 if (is_const && ! attr->is_const)
756 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
757 XSTR (exp, 0));
759 /* Copy this just to make it permanent,
760 so expressions using it can be permanent too. */
761 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
763 /* It shouldn't be possible to simplify the value given to a
764 constant attribute, so don't expand this until it's time to
765 write the test expression. */
766 if (attr->is_const)
767 ATTR_IND_SIMPLIFIED_P (exp) = 1;
769 if (attr->is_numeric)
771 for (p = XSTR (exp, 1); *p; p++)
772 if (! ISDIGIT (*p))
773 fatal ("attribute `%s' takes only numeric values",
774 XSTR (exp, 0));
776 else
778 for (av = attr->first_value; av; av = av->next)
779 if (GET_CODE (av->value) == CONST_STRING
780 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
781 break;
783 if (av == NULL)
784 fatal ("unknown value `%s' for `%s' attribute",
785 XSTR (exp, 1), XSTR (exp, 0));
788 else
790 if (! strcmp (XSTR (exp, 0), "alternative"))
792 int set = 0;
794 name_ptr = XSTR (exp, 1);
795 while ((p = next_comma_elt (&name_ptr)) != NULL)
796 set |= 1 << atoi (p);
798 return mk_attr_alt (set);
800 else
802 /* Make an IOR tree of the possible values. */
803 orexp = false_rtx;
804 name_ptr = XSTR (exp, 1);
805 while ((p = next_comma_elt (&name_ptr)) != NULL)
807 newexp = attr_eq (XSTR (exp, 0), p);
808 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
811 return check_attr_test (orexp, is_const, lineno);
814 break;
816 case ATTR_FLAG:
817 break;
819 case CONST_INT:
820 /* Either TRUE or FALSE. */
821 if (XWINT (exp, 0))
822 return true_rtx;
823 else
824 return false_rtx;
826 case IOR:
827 case AND:
828 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
829 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
830 break;
832 case NOT:
833 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
834 break;
836 case MATCH_OPERAND:
837 if (is_const)
838 fatal ("RTL operator \"%s\" not valid in constant attribute test",
839 GET_RTX_NAME (GET_CODE (exp)));
840 /* These cases can't be simplified. */
841 ATTR_IND_SIMPLIFIED_P (exp) = 1;
842 break;
844 case LE: case LT: case GT: case GE:
845 case LEU: case LTU: case GTU: case GEU:
846 case NE: case EQ:
847 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
848 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
849 exp = attr_rtx (GET_CODE (exp),
850 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
851 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
852 /* These cases can't be simplified. */
853 ATTR_IND_SIMPLIFIED_P (exp) = 1;
854 break;
856 case SYMBOL_REF:
857 if (is_const)
859 /* These cases are valid for constant attributes, but can't be
860 simplified. */
861 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
862 ATTR_IND_SIMPLIFIED_P (exp) = 1;
863 break;
865 default:
866 fatal ("RTL operator \"%s\" not valid in attribute test",
867 GET_RTX_NAME (GET_CODE (exp)));
870 return exp;
873 /* Given an expression, ensure that it is validly formed and that all named
874 attribute values are valid for the given attribute. Issue a fatal error
875 if not. If no attribute is specified, assume a numeric attribute.
877 Return a perhaps modified replacement expression for the value. */
879 static rtx
880 check_attr_value (rtx exp, struct attr_desc *attr)
882 struct attr_value *av;
883 const char *p;
884 int i;
886 switch (GET_CODE (exp))
888 case CONST_INT:
889 if (attr && ! attr->is_numeric)
891 error_with_line (attr->lineno,
892 "CONST_INT not valid for non-numeric attribute %s",
893 attr->name);
894 break;
897 if (INTVAL (exp) < 0)
899 error_with_line (attr->lineno,
900 "negative numeric value specified for attribute %s",
901 attr->name);
902 break;
904 break;
906 case CONST_STRING:
907 if (! strcmp (XSTR (exp, 0), "*"))
908 break;
910 if (attr == 0 || attr->is_numeric)
912 p = XSTR (exp, 0);
913 for (; *p; p++)
914 if (! ISDIGIT (*p))
916 error_with_line (attr ? attr->lineno : 0,
917 "non-numeric value for numeric attribute %s",
918 attr ? attr->name : "internal");
919 break;
921 break;
924 for (av = attr->first_value; av; av = av->next)
925 if (GET_CODE (av->value) == CONST_STRING
926 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
927 break;
929 if (av == NULL)
930 error_with_line (attr->lineno,
931 "unknown value `%s' for `%s' attribute",
932 XSTR (exp, 0), attr ? attr->name : "internal");
933 break;
935 case IF_THEN_ELSE:
936 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
937 attr ? attr->is_const : 0,
938 attr ? attr->lineno : 0);
939 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
940 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
941 break;
943 case PLUS:
944 case MINUS:
945 case MULT:
946 case DIV:
947 case MOD:
948 if (attr && !attr->is_numeric)
950 error_with_line (attr->lineno,
951 "invalid operation `%s' for non-numeric"
952 " attribute value", GET_RTX_NAME (GET_CODE (exp)));
953 break;
955 /* Fall through. */
957 case IOR:
958 case AND:
959 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
960 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
961 break;
963 case FFS:
964 case CLZ:
965 case CTZ:
966 case POPCOUNT:
967 case PARITY:
968 case BSWAP:
969 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
970 break;
972 case COND:
973 if (XVECLEN (exp, 0) % 2 != 0)
975 error_with_line (attr->lineno,
976 "first operand of COND must have even length");
977 break;
980 for (i = 0; i < XVECLEN (exp, 0); i += 2)
982 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
983 attr ? attr->is_const : 0,
984 attr ? attr->lineno : 0);
985 XVECEXP (exp, 0, i + 1)
986 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
989 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
990 break;
992 case ATTR:
994 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
995 if (attr2 == NULL)
996 error_with_line (attr ? attr->lineno : 0,
997 "unknown attribute `%s' in ATTR",
998 XSTR (exp, 0));
999 else if (attr && attr->is_const && ! attr2->is_const)
1000 error_with_line (attr->lineno,
1001 "non-constant attribute `%s' referenced from `%s'",
1002 XSTR (exp, 0), attr->name);
1003 else if (attr
1004 && attr->is_numeric != attr2->is_numeric)
1005 error_with_line (attr->lineno,
1006 "numeric attribute mismatch calling `%s' from `%s'",
1007 XSTR (exp, 0), attr->name);
1009 break;
1011 case SYMBOL_REF:
1012 /* A constant SYMBOL_REF is valid as a constant attribute test and
1013 is expanded later by make_canonical into a COND. In a non-constant
1014 attribute test, it is left be. */
1015 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1017 default:
1018 error_with_line (attr ? attr->lineno : 0,
1019 "invalid operation `%s' for attribute value",
1020 GET_RTX_NAME (GET_CODE (exp)));
1021 break;
1024 return exp;
1027 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1028 It becomes a COND with each test being (eq_attr "alternative" "n") */
1030 static rtx
1031 convert_set_attr_alternative (rtx exp, struct insn_def *id)
1033 int num_alt = id->num_alternatives;
1034 rtx condexp;
1035 int i;
1037 if (XVECLEN (exp, 1) != num_alt)
1039 error_with_line (id->lineno,
1040 "bad number of entries in SET_ATTR_ALTERNATIVE");
1041 return NULL_RTX;
1044 /* Make a COND with all tests but the last. Select the last value via the
1045 default. */
1046 condexp = rtx_alloc (COND);
1047 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1049 for (i = 0; i < num_alt - 1; i++)
1051 const char *p;
1052 p = attr_numeral (i);
1054 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1055 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1058 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1060 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1063 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1064 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1066 static rtx
1067 convert_set_attr (rtx exp, struct insn_def *id)
1069 rtx newexp;
1070 const char *name_ptr;
1071 char *p;
1072 int n;
1074 /* See how many alternative specified. */
1075 n = n_comma_elts (XSTR (exp, 1));
1076 if (n == 1)
1077 return attr_rtx (SET,
1078 attr_rtx (ATTR, XSTR (exp, 0)),
1079 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1081 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1082 XSTR (newexp, 0) = XSTR (exp, 0);
1083 XVEC (newexp, 1) = rtvec_alloc (n);
1085 /* Process each comma-separated name. */
1086 name_ptr = XSTR (exp, 1);
1087 n = 0;
1088 while ((p = next_comma_elt (&name_ptr)) != NULL)
1089 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1091 return convert_set_attr_alternative (newexp, id);
1094 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1095 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1096 expressions. */
1098 static void
1099 check_defs (void)
1101 struct insn_def *id;
1102 struct attr_desc *attr;
1103 int i;
1104 rtx value;
1106 for (id = defs; id; id = id->next)
1108 if (XVEC (id->def, id->vec_idx) == NULL)
1109 continue;
1111 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1113 value = XVECEXP (id->def, id->vec_idx, i);
1114 switch (GET_CODE (value))
1116 case SET:
1117 if (GET_CODE (XEXP (value, 0)) != ATTR)
1119 error_with_line (id->lineno, "bad attribute set");
1120 value = NULL_RTX;
1122 break;
1124 case SET_ATTR_ALTERNATIVE:
1125 value = convert_set_attr_alternative (value, id);
1126 break;
1128 case SET_ATTR:
1129 value = convert_set_attr (value, id);
1130 break;
1132 default:
1133 error_with_line (id->lineno, "invalid attribute code %s",
1134 GET_RTX_NAME (GET_CODE (value)));
1135 value = NULL_RTX;
1137 if (value == NULL_RTX)
1138 continue;
1140 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
1142 error_with_line (id->lineno, "unknown attribute %s",
1143 XSTR (XEXP (value, 0), 0));
1144 continue;
1147 XVECEXP (id->def, id->vec_idx, i) = value;
1148 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1153 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1154 expressions by converting them into a COND. This removes cases from this
1155 program. Also, replace an attribute value of "*" with the default attribute
1156 value. */
1158 static rtx
1159 make_canonical (struct attr_desc *attr, rtx exp)
1161 int i;
1162 rtx newexp;
1164 switch (GET_CODE (exp))
1166 case CONST_INT:
1167 exp = make_numeric_value (INTVAL (exp));
1168 break;
1170 case CONST_STRING:
1171 if (! strcmp (XSTR (exp, 0), "*"))
1173 if (attr == 0 || attr->default_val == 0)
1174 fatal ("(attr_value \"*\") used in invalid context");
1175 exp = attr->default_val->value;
1177 else
1178 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1180 break;
1182 case SYMBOL_REF:
1183 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1184 break;
1185 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1186 This makes the COND something that won't be considered an arbitrary
1187 expression by walk_attr_value. */
1188 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1189 exp = check_attr_value (exp, attr);
1190 break;
1192 case IF_THEN_ELSE:
1193 newexp = rtx_alloc (COND);
1194 XVEC (newexp, 0) = rtvec_alloc (2);
1195 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1196 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1198 XEXP (newexp, 1) = XEXP (exp, 2);
1200 exp = newexp;
1201 /* Fall through to COND case since this is now a COND. */
1203 case COND:
1205 int allsame = 1;
1206 rtx defval;
1208 /* First, check for degenerate COND. */
1209 if (XVECLEN (exp, 0) == 0)
1210 return make_canonical (attr, XEXP (exp, 1));
1211 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1213 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1215 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1216 XVECEXP (exp, 0, i + 1)
1217 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1218 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1219 allsame = 0;
1221 if (allsame)
1222 return defval;
1224 break;
1226 default:
1227 break;
1230 return exp;
1233 static rtx
1234 copy_boolean (rtx exp)
1236 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1237 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1238 copy_boolean (XEXP (exp, 1)));
1239 if (GET_CODE (exp) == MATCH_OPERAND)
1241 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1242 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1244 else if (GET_CODE (exp) == EQ_ATTR)
1246 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1247 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1250 return exp;
1253 /* Given a value and an attribute description, return a `struct attr_value *'
1254 that represents that value. This is either an existing structure, if the
1255 value has been previously encountered, or a newly-created structure.
1257 `insn_code' is the code of an insn whose attribute has the specified
1258 value (-2 if not processing an insn). We ensure that all insns for
1259 a given value have the same number of alternatives if the value checks
1260 alternatives. */
1262 static struct attr_value *
1263 get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
1265 struct attr_value *av;
1266 int num_alt = 0;
1268 value = make_canonical (attr, value);
1269 if (compares_alternatives_p (value))
1271 if (insn_code < 0 || insn_alternatives == NULL)
1272 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1273 else
1274 num_alt = insn_alternatives[insn_code];
1277 for (av = attr->first_value; av; av = av->next)
1278 if (rtx_equal_p (value, av->value)
1279 && (num_alt == 0 || av->first_insn == NULL
1280 || insn_alternatives[av->first_insn->def->insn_code]))
1281 return av;
1283 av = oballoc (struct attr_value);
1284 av->value = value;
1285 av->next = attr->first_value;
1286 attr->first_value = av;
1287 av->first_insn = NULL;
1288 av->num_insns = 0;
1289 av->has_asm_insn = 0;
1291 return av;
1294 /* After all DEFINE_DELAYs have been read in, create internal attributes
1295 to generate the required routines.
1297 First, we compute the number of delay slots for each insn (as a COND of
1298 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1299 delay type is specified, we compute a similar function giving the
1300 DEFINE_DELAY ordinal for each insn.
1302 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1303 tells whether a given insn can be in that delay slot.
1305 Normal attribute filling and optimization expands these to contain the
1306 information needed to handle delay slots. */
1308 static void
1309 expand_delays (void)
1311 struct delay_desc *delay;
1312 rtx condexp;
1313 rtx newexp;
1314 int i;
1315 char *p;
1317 /* First, generate data for `num_delay_slots' function. */
1319 condexp = rtx_alloc (COND);
1320 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1321 XEXP (condexp, 1) = make_numeric_value (0);
1323 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1325 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1326 XVECEXP (condexp, 0, i + 1)
1327 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1330 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
1332 /* If more than one delay type, do the same for computing the delay type. */
1333 if (num_delays > 1)
1335 condexp = rtx_alloc (COND);
1336 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1337 XEXP (condexp, 1) = make_numeric_value (0);
1339 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1341 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1342 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1345 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
1348 /* For each delay possibility and delay slot, compute an eligibility
1349 attribute for non-annulled insns and for each type of annulled (annul
1350 if true and annul if false). */
1351 for (delay = delays; delay; delay = delay->next)
1353 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1355 condexp = XVECEXP (delay->def, 1, i);
1356 if (condexp == 0)
1357 condexp = false_rtx;
1358 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1359 make_numeric_value (1), make_numeric_value (0));
1361 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1362 "*delay_%d_%d", delay->num, i / 3);
1363 make_internal_attr (p, newexp, ATTR_SPECIAL);
1365 if (have_annul_true)
1367 condexp = XVECEXP (delay->def, 1, i + 1);
1368 if (condexp == 0) condexp = false_rtx;
1369 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1370 make_numeric_value (1),
1371 make_numeric_value (0));
1372 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1373 "*annul_true_%d_%d", delay->num, i / 3);
1374 make_internal_attr (p, newexp, ATTR_SPECIAL);
1377 if (have_annul_false)
1379 condexp = XVECEXP (delay->def, 1, i + 2);
1380 if (condexp == 0) condexp = false_rtx;
1381 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1382 make_numeric_value (1),
1383 make_numeric_value (0));
1384 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1385 "*annul_false_%d_%d", delay->num, i / 3);
1386 make_internal_attr (p, newexp, ATTR_SPECIAL);
1392 /* Once all attributes and insns have been read and checked, we construct for
1393 each attribute value a list of all the insns that have that value for
1394 the attribute. */
1396 static void
1397 fill_attr (struct attr_desc *attr)
1399 struct attr_value *av;
1400 struct insn_ent *ie;
1401 struct insn_def *id;
1402 int i;
1403 rtx value;
1405 /* Don't fill constant attributes. The value is independent of
1406 any particular insn. */
1407 if (attr->is_const)
1408 return;
1410 for (id = defs; id; id = id->next)
1412 /* If no value is specified for this insn for this attribute, use the
1413 default. */
1414 value = NULL;
1415 if (XVEC (id->def, id->vec_idx))
1416 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1417 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1418 attr->name))
1419 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1421 if (value == NULL)
1422 av = attr->default_val;
1423 else
1424 av = get_attr_value (value, attr, id->insn_code);
1426 ie = oballoc (struct insn_ent);
1427 ie->def = id;
1428 insert_insn_ent (av, ie);
1432 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1433 test that checks relative positions of insns (uses MATCH_DUP or PC).
1434 If so, replace it with what is obtained by passing the expression to
1435 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1436 recursively on each value (including the default value). Otherwise,
1437 return the value returned by NO_ADDRESS_FN applied to EXP. */
1439 static rtx
1440 substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1441 rtx (*address_fn) (rtx))
1443 int i;
1444 rtx newexp;
1446 if (GET_CODE (exp) == COND)
1448 /* See if any tests use addresses. */
1449 address_used = 0;
1450 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1451 walk_attr_value (XVECEXP (exp, 0, i));
1453 if (address_used)
1454 return (*address_fn) (exp);
1456 /* Make a new copy of this COND, replacing each element. */
1457 newexp = rtx_alloc (COND);
1458 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1459 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1461 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1462 XVECEXP (newexp, 0, i + 1)
1463 = substitute_address (XVECEXP (exp, 0, i + 1),
1464 no_address_fn, address_fn);
1467 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1468 no_address_fn, address_fn);
1470 return newexp;
1473 else if (GET_CODE (exp) == IF_THEN_ELSE)
1475 address_used = 0;
1476 walk_attr_value (XEXP (exp, 0));
1477 if (address_used)
1478 return (*address_fn) (exp);
1480 return attr_rtx (IF_THEN_ELSE,
1481 substitute_address (XEXP (exp, 0),
1482 no_address_fn, address_fn),
1483 substitute_address (XEXP (exp, 1),
1484 no_address_fn, address_fn),
1485 substitute_address (XEXP (exp, 2),
1486 no_address_fn, address_fn));
1489 return (*no_address_fn) (exp);
1492 /* Make new attributes from the `length' attribute. The following are made,
1493 each corresponding to a function called from `shorten_branches' or
1494 `get_attr_length':
1496 *insn_default_length This is the length of the insn to be returned
1497 by `get_attr_length' before `shorten_branches'
1498 has been called. In each case where the length
1499 depends on relative addresses, the largest
1500 possible is used. This routine is also used
1501 to compute the initial size of the insn.
1503 *insn_variable_length_p This returns 1 if the insn's length depends
1504 on relative addresses, zero otherwise.
1506 *insn_current_length This is only called when it is known that the
1507 insn has a variable length and returns the
1508 current length, based on relative addresses.
1511 static void
1512 make_length_attrs (void)
1514 static const char *new_names[] =
1516 "*insn_default_length",
1517 "*insn_min_length",
1518 "*insn_variable_length_p",
1519 "*insn_current_length"
1521 static rtx (*const no_address_fn[]) (rtx)
1522 = {identity_fn,identity_fn, zero_fn, zero_fn};
1523 static rtx (*const address_fn[]) (rtx)
1524 = {max_fn, min_fn, one_fn, identity_fn};
1525 size_t i;
1526 struct attr_desc *length_attr, *new_attr;
1527 struct attr_value *av, *new_av;
1528 struct insn_ent *ie, *new_ie;
1530 /* See if length attribute is defined. If so, it must be numeric. Make
1531 it special so we don't output anything for it. */
1532 length_attr = find_attr (&length_str, 0);
1533 if (length_attr == 0)
1534 return;
1536 if (! length_attr->is_numeric)
1537 fatal ("length attribute must be numeric");
1539 length_attr->is_const = 0;
1540 length_attr->is_special = 1;
1542 /* Make each new attribute, in turn. */
1543 for (i = 0; i < ARRAY_SIZE (new_names); i++)
1545 make_internal_attr (new_names[i],
1546 substitute_address (length_attr->default_val->value,
1547 no_address_fn[i], address_fn[i]),
1548 ATTR_NONE);
1549 new_attr = find_attr (&new_names[i], 0);
1550 for (av = length_attr->first_value; av; av = av->next)
1551 for (ie = av->first_insn; ie; ie = ie->next)
1553 new_av = get_attr_value (substitute_address (av->value,
1554 no_address_fn[i],
1555 address_fn[i]),
1556 new_attr, ie->def->insn_code);
1557 new_ie = oballoc (struct insn_ent);
1558 new_ie->def = ie->def;
1559 insert_insn_ent (new_av, new_ie);
1564 /* Utility functions called from above routine. */
1566 static rtx
1567 identity_fn (rtx exp)
1569 return exp;
1572 static rtx
1573 zero_fn (rtx exp ATTRIBUTE_UNUSED)
1575 return make_numeric_value (0);
1578 static rtx
1579 one_fn (rtx exp ATTRIBUTE_UNUSED)
1581 return make_numeric_value (1);
1584 static rtx
1585 max_fn (rtx exp)
1587 int unknown;
1588 return make_numeric_value (max_attr_value (exp, &unknown));
1591 static rtx
1592 min_fn (rtx exp)
1594 int unknown;
1595 return make_numeric_value (min_attr_value (exp, &unknown));
1598 static void
1599 write_length_unit_log (void)
1601 struct attr_desc *length_attr = find_attr (&length_str, 0);
1602 struct attr_value *av;
1603 struct insn_ent *ie;
1604 unsigned int length_unit_log, length_or;
1605 int unknown = 0;
1607 if (length_attr == 0)
1608 return;
1609 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1610 for (av = length_attr->first_value; av; av = av->next)
1611 for (ie = av->first_insn; ie; ie = ie->next)
1612 length_or |= or_attr_value (av->value, &unknown);
1614 if (unknown)
1615 length_unit_log = 0;
1616 else
1618 length_or = ~length_or;
1619 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
1620 length_unit_log++;
1622 printf ("EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log);
1625 /* Take a COND expression and see if any of the conditions in it can be
1626 simplified. If any are known true or known false for the particular insn
1627 code, the COND can be further simplified.
1629 Also call ourselves on any COND operations that are values of this COND.
1631 We do not modify EXP; rather, we make and return a new rtx. */
1633 static rtx
1634 simplify_cond (rtx exp, int insn_code, int insn_index)
1636 int i, j;
1637 /* We store the desired contents here,
1638 then build a new expression if they don't match EXP. */
1639 rtx defval = XEXP (exp, 1);
1640 rtx new_defval = XEXP (exp, 1);
1641 int len = XVECLEN (exp, 0);
1642 rtx *tests = XNEWVEC (rtx, len);
1643 int allsame = 1;
1644 rtx ret;
1646 /* This lets us free all storage allocated below, if appropriate. */
1647 obstack_finish (rtl_obstack);
1649 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
1651 /* See if default value needs simplification. */
1652 if (GET_CODE (defval) == COND)
1653 new_defval = simplify_cond (defval, insn_code, insn_index);
1655 /* Simplify the subexpressions, and see what tests we can get rid of. */
1657 for (i = 0; i < len; i += 2)
1659 rtx newtest, newval;
1661 /* Simplify this test. */
1662 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
1663 tests[i] = newtest;
1665 newval = tests[i + 1];
1666 /* See if this value may need simplification. */
1667 if (GET_CODE (newval) == COND)
1668 newval = simplify_cond (newval, insn_code, insn_index);
1670 /* Look for ways to delete or combine this test. */
1671 if (newtest == true_rtx)
1673 /* If test is true, make this value the default
1674 and discard this + any following tests. */
1675 len = i;
1676 defval = tests[i + 1];
1677 new_defval = newval;
1680 else if (newtest == false_rtx)
1682 /* If test is false, discard it and its value. */
1683 for (j = i; j < len - 2; j++)
1684 tests[j] = tests[j + 2];
1685 i -= 2;
1686 len -= 2;
1689 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
1691 /* If this value and the value for the prev test are the same,
1692 merge the tests. */
1694 tests[i - 2]
1695 = insert_right_side (IOR, tests[i - 2], newtest,
1696 insn_code, insn_index);
1698 /* Delete this test/value. */
1699 for (j = i; j < len - 2; j++)
1700 tests[j] = tests[j + 2];
1701 len -= 2;
1702 i -= 2;
1705 else
1706 tests[i + 1] = newval;
1709 /* If the last test in a COND has the same value
1710 as the default value, that test isn't needed. */
1712 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
1713 len -= 2;
1715 /* See if we changed anything. */
1716 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1717 allsame = 0;
1718 else
1719 for (i = 0; i < len; i++)
1720 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
1722 allsame = 0;
1723 break;
1726 if (len == 0)
1728 if (GET_CODE (defval) == COND)
1729 ret = simplify_cond (defval, insn_code, insn_index);
1730 else
1731 ret = defval;
1733 else if (allsame)
1734 ret = exp;
1735 else
1737 rtx newexp = rtx_alloc (COND);
1739 XVEC (newexp, 0) = rtvec_alloc (len);
1740 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
1741 XEXP (newexp, 1) = new_defval;
1742 ret = newexp;
1744 free (tests);
1745 return ret;
1748 /* Remove an insn entry from an attribute value. */
1750 static void
1751 remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
1753 struct insn_ent *previe;
1755 if (av->first_insn == ie)
1756 av->first_insn = ie->next;
1757 else
1759 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1761 previe->next = ie->next;
1764 av->num_insns--;
1765 if (ie->def->insn_code == -1)
1766 av->has_asm_insn = 0;
1768 num_insn_ents--;
1771 /* Insert an insn entry in an attribute value list. */
1773 static void
1774 insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
1776 ie->next = av->first_insn;
1777 av->first_insn = ie;
1778 av->num_insns++;
1779 if (ie->def->insn_code == -1)
1780 av->has_asm_insn = 1;
1782 num_insn_ents++;
1785 /* This is a utility routine to take an expression that is a tree of either
1786 AND or IOR expressions and insert a new term. The new term will be
1787 inserted at the right side of the first node whose code does not match
1788 the root. A new node will be created with the root's code. Its left
1789 side will be the old right side and its right side will be the new
1790 term.
1792 If the `term' is itself a tree, all its leaves will be inserted. */
1794 static rtx
1795 insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
1797 rtx newexp;
1799 /* Avoid consing in some special cases. */
1800 if (code == AND && term == true_rtx)
1801 return exp;
1802 if (code == AND && term == false_rtx)
1803 return false_rtx;
1804 if (code == AND && exp == true_rtx)
1805 return term;
1806 if (code == AND && exp == false_rtx)
1807 return false_rtx;
1808 if (code == IOR && term == true_rtx)
1809 return true_rtx;
1810 if (code == IOR && term == false_rtx)
1811 return exp;
1812 if (code == IOR && exp == true_rtx)
1813 return true_rtx;
1814 if (code == IOR && exp == false_rtx)
1815 return term;
1816 if (attr_equal_p (exp, term))
1817 return exp;
1819 if (GET_CODE (term) == code)
1821 exp = insert_right_side (code, exp, XEXP (term, 0),
1822 insn_code, insn_index);
1823 exp = insert_right_side (code, exp, XEXP (term, 1),
1824 insn_code, insn_index);
1826 return exp;
1829 if (GET_CODE (exp) == code)
1831 rtx new_rtx = insert_right_side (code, XEXP (exp, 1),
1832 term, insn_code, insn_index);
1833 if (new_rtx != XEXP (exp, 1))
1834 /* Make a copy of this expression and call recursively. */
1835 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx);
1836 else
1837 newexp = exp;
1839 else
1841 /* Insert the new term. */
1842 newexp = attr_rtx (code, exp, term);
1845 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
1848 /* If we have an expression which AND's a bunch of
1849 (not (eq_attrq "alternative" "n"))
1850 terms, we may have covered all or all but one of the possible alternatives.
1851 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1853 This routine is passed an expression and either AND or IOR. It returns a
1854 bitmask indicating which alternatives are mentioned within EXP. */
1856 static int
1857 compute_alternative_mask (rtx exp, enum rtx_code code)
1859 const char *string;
1860 if (GET_CODE (exp) == code)
1861 return compute_alternative_mask (XEXP (exp, 0), code)
1862 | compute_alternative_mask (XEXP (exp, 1), code);
1864 else if (code == AND && GET_CODE (exp) == NOT
1865 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1866 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1867 string = XSTR (XEXP (exp, 0), 1);
1869 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1870 && XSTR (exp, 0) == alternative_name)
1871 string = XSTR (exp, 1);
1873 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1875 if (code == AND && XINT (exp, 1))
1876 return XINT (exp, 0);
1878 if (code == IOR && !XINT (exp, 1))
1879 return XINT (exp, 0);
1881 return 0;
1883 else
1884 return 0;
1886 if (string[1] == 0)
1887 return 1 << (string[0] - '0');
1888 return 1 << atoi (string);
1891 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1892 attribute with the value represented by that bit. */
1894 static rtx
1895 make_alternative_compare (int mask)
1897 return mk_attr_alt (mask);
1900 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1901 of "attr" for this insn code. From that value, we can compute a test
1902 showing when the EQ_ATTR will be true. This routine performs that
1903 computation. If a test condition involves an address, we leave the EQ_ATTR
1904 intact because addresses are only valid for the `length' attribute.
1906 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1907 it refers. VALUE is the value of that attribute for the insn
1908 corresponding to INSN_CODE and INSN_INDEX. */
1910 static rtx
1911 evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value,
1912 int insn_code, int insn_index)
1914 rtx orexp, andexp;
1915 rtx right;
1916 rtx newexp;
1917 int i;
1919 switch (GET_CODE (value))
1921 case CONST_STRING:
1922 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
1923 newexp = true_rtx;
1924 else
1925 newexp = false_rtx;
1926 break;
1928 case SYMBOL_REF:
1930 const char *prefix;
1931 char *string, *p;
1933 gcc_assert (GET_CODE (exp) == EQ_ATTR);
1934 prefix = attr->enum_name ? attr->enum_name : attr->name;
1935 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL));
1936 for (p = string; *p; p++)
1937 *p = TOUPPER (*p);
1939 newexp = attr_rtx (EQ, value,
1940 attr_rtx (SYMBOL_REF,
1941 DEF_ATTR_STRING (string)));
1942 break;
1945 case COND:
1946 /* We construct an IOR of all the cases for which the
1947 requested attribute value is present. Since we start with
1948 FALSE, if it is not present, FALSE will be returned.
1950 Each case is the AND of the NOT's of the previous conditions with the
1951 current condition; in the default case the current condition is TRUE.
1953 For each possible COND value, call ourselves recursively.
1955 The extra TRUE and FALSE expressions will be eliminated by another
1956 call to the simplification routine. */
1958 orexp = false_rtx;
1959 andexp = true_rtx;
1961 for (i = 0; i < XVECLEN (value, 0); i += 2)
1963 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
1964 insn_code, insn_index);
1966 right = insert_right_side (AND, andexp, this_cond,
1967 insn_code, insn_index);
1968 right = insert_right_side (AND, right,
1969 evaluate_eq_attr (exp, attr,
1970 XVECEXP (value, 0,
1971 i + 1),
1972 insn_code, insn_index),
1973 insn_code, insn_index);
1974 orexp = insert_right_side (IOR, orexp, right,
1975 insn_code, insn_index);
1977 /* Add this condition into the AND expression. */
1978 newexp = attr_rtx (NOT, this_cond);
1979 andexp = insert_right_side (AND, andexp, newexp,
1980 insn_code, insn_index);
1983 /* Handle the default case. */
1984 right = insert_right_side (AND, andexp,
1985 evaluate_eq_attr (exp, attr, XEXP (value, 1),
1986 insn_code, insn_index),
1987 insn_code, insn_index);
1988 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
1989 break;
1991 default:
1992 gcc_unreachable ();
1995 /* If uses an address, must return original expression. But set the
1996 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
1998 address_used = 0;
1999 walk_attr_value (newexp);
2001 if (address_used)
2003 if (! ATTR_IND_SIMPLIFIED_P (exp))
2004 return copy_rtx_unchanging (exp);
2005 return exp;
2007 else
2008 return newexp;
2011 /* This routine is called when an AND of a term with a tree of AND's is
2012 encountered. If the term or its complement is present in the tree, it
2013 can be replaced with TRUE or FALSE, respectively.
2015 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2016 be true and hence are complementary.
2018 There is one special case: If we see
2019 (and (not (eq_attr "att" "v1"))
2020 (eq_attr "att" "v2"))
2021 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2022 replace the term, not anything in the AND tree. So we pass a pointer to
2023 the term. */
2025 static rtx
2026 simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2028 rtx left, right;
2029 rtx newexp;
2030 rtx temp;
2031 int left_eliminates_term, right_eliminates_term;
2033 if (GET_CODE (exp) == AND)
2035 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2036 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2037 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2039 newexp = attr_rtx (AND, left, right);
2041 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2045 else if (GET_CODE (exp) == IOR)
2047 /* For the IOR case, we do the same as above, except that we can
2048 only eliminate `term' if both sides of the IOR would do so. */
2049 temp = *pterm;
2050 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2051 left_eliminates_term = (temp == true_rtx);
2053 temp = *pterm;
2054 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2055 right_eliminates_term = (temp == true_rtx);
2057 if (left_eliminates_term && right_eliminates_term)
2058 *pterm = true_rtx;
2060 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2062 newexp = attr_rtx (IOR, left, right);
2064 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2068 /* Check for simplifications. Do some extra checking here since this
2069 routine is called so many times. */
2071 if (exp == *pterm)
2072 return true_rtx;
2074 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2075 return false_rtx;
2077 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2078 return false_rtx;
2080 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2082 if (attr_alt_subset_p (*pterm, exp))
2083 return true_rtx;
2085 if (attr_alt_subset_of_compl_p (*pterm, exp))
2086 return false_rtx;
2088 if (attr_alt_subset_p (exp, *pterm))
2089 *pterm = true_rtx;
2091 return exp;
2094 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2096 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2097 return exp;
2099 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
2100 return true_rtx;
2101 else
2102 return false_rtx;
2105 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2106 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2108 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2109 return exp;
2111 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2112 return false_rtx;
2113 else
2114 return true_rtx;
2117 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2118 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2120 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2121 return exp;
2123 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2124 return false_rtx;
2125 else
2126 *pterm = true_rtx;
2129 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2131 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2132 return true_rtx;
2135 else if (GET_CODE (exp) == NOT)
2137 if (attr_equal_p (XEXP (exp, 0), *pterm))
2138 return false_rtx;
2141 else if (GET_CODE (*pterm) == NOT)
2143 if (attr_equal_p (XEXP (*pterm, 0), exp))
2144 return false_rtx;
2147 else if (attr_equal_p (exp, *pterm))
2148 return true_rtx;
2150 return exp;
2153 /* Similar to `simplify_and_tree', but for IOR trees. */
2155 static rtx
2156 simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
2158 rtx left, right;
2159 rtx newexp;
2160 rtx temp;
2161 int left_eliminates_term, right_eliminates_term;
2163 if (GET_CODE (exp) == IOR)
2165 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2166 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2167 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2169 newexp = attr_rtx (GET_CODE (exp), left, right);
2171 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2175 else if (GET_CODE (exp) == AND)
2177 /* For the AND case, we do the same as above, except that we can
2178 only eliminate `term' if both sides of the AND would do so. */
2179 temp = *pterm;
2180 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2181 left_eliminates_term = (temp == false_rtx);
2183 temp = *pterm;
2184 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2185 right_eliminates_term = (temp == false_rtx);
2187 if (left_eliminates_term && right_eliminates_term)
2188 *pterm = false_rtx;
2190 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2192 newexp = attr_rtx (GET_CODE (exp), left, right);
2194 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2198 if (attr_equal_p (exp, *pterm))
2199 return false_rtx;
2201 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2202 return true_rtx;
2204 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2205 return true_rtx;
2207 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2208 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2209 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2210 *pterm = false_rtx;
2212 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2213 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2214 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2215 return false_rtx;
2217 return exp;
2220 /* Compute approximate cost of the expression. Used to decide whether
2221 expression is cheap enough for inline. */
2222 static int
2223 attr_rtx_cost (rtx x)
2225 int cost = 0;
2226 enum rtx_code code;
2227 if (!x)
2228 return 0;
2229 code = GET_CODE (x);
2230 switch (code)
2232 case MATCH_OPERAND:
2233 if (XSTR (x, 1)[0])
2234 return 10;
2235 else
2236 return 0;
2238 case EQ_ATTR_ALT:
2239 return 0;
2241 case EQ_ATTR:
2242 /* Alternatives don't result into function call. */
2243 if (!strcmp_check (XSTR (x, 0), alternative_name))
2244 return 0;
2245 else
2246 return 5;
2247 default:
2249 int i, j;
2250 const char *fmt = GET_RTX_FORMAT (code);
2251 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2253 switch (fmt[i])
2255 case 'V':
2256 case 'E':
2257 for (j = 0; j < XVECLEN (x, i); j++)
2258 cost += attr_rtx_cost (XVECEXP (x, i, j));
2259 break;
2260 case 'e':
2261 cost += attr_rtx_cost (XEXP (x, i));
2262 break;
2266 break;
2268 return cost;
2271 /* Simplify test expression and use temporary obstack in order to avoid
2272 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2273 and avoid unnecessary copying if possible. */
2275 static rtx
2276 simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2278 rtx x;
2279 struct obstack *old;
2280 if (ATTR_IND_SIMPLIFIED_P (exp))
2281 return exp;
2282 old = rtl_obstack;
2283 rtl_obstack = temp_obstack;
2284 x = simplify_test_exp (exp, insn_code, insn_index);
2285 rtl_obstack = old;
2286 if (x == exp || rtl_obstack == temp_obstack)
2287 return x;
2288 return attr_copy_rtx (x);
2291 /* Returns true if S1 is a subset of S2. */
2293 static bool
2294 attr_alt_subset_p (rtx s1, rtx s2)
2296 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2298 case (0 << 1) | 0:
2299 return !(XINT (s1, 0) &~ XINT (s2, 0));
2301 case (0 << 1) | 1:
2302 return !(XINT (s1, 0) & XINT (s2, 0));
2304 case (1 << 1) | 0:
2305 return false;
2307 case (1 << 1) | 1:
2308 return !(XINT (s2, 0) &~ XINT (s1, 0));
2310 default:
2311 gcc_unreachable ();
2315 /* Returns true if S1 is a subset of complement of S2. */
2317 static bool
2318 attr_alt_subset_of_compl_p (rtx s1, rtx s2)
2320 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2322 case (0 << 1) | 0:
2323 return !(XINT (s1, 0) & XINT (s2, 0));
2325 case (0 << 1) | 1:
2326 return !(XINT (s1, 0) & ~XINT (s2, 0));
2328 case (1 << 1) | 0:
2329 return !(XINT (s2, 0) &~ XINT (s1, 0));
2331 case (1 << 1) | 1:
2332 return false;
2334 default:
2335 gcc_unreachable ();
2339 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2341 static rtx
2342 attr_alt_intersection (rtx s1, rtx s2)
2344 rtx result = rtx_alloc (EQ_ATTR_ALT);
2346 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2348 case (0 << 1) | 0:
2349 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2350 break;
2351 case (0 << 1) | 1:
2352 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2353 break;
2354 case (1 << 1) | 0:
2355 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2356 break;
2357 case (1 << 1) | 1:
2358 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2359 break;
2360 default:
2361 gcc_unreachable ();
2363 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2365 return result;
2368 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2370 static rtx
2371 attr_alt_union (rtx s1, rtx s2)
2373 rtx result = rtx_alloc (EQ_ATTR_ALT);
2375 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2377 case (0 << 1) | 0:
2378 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2379 break;
2380 case (0 << 1) | 1:
2381 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2382 break;
2383 case (1 << 1) | 0:
2384 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2385 break;
2386 case (1 << 1) | 1:
2387 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2388 break;
2389 default:
2390 gcc_unreachable ();
2393 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2394 return result;
2397 /* Return EQ_ATTR_ALT expression representing complement of S. */
2399 static rtx
2400 attr_alt_complement (rtx s)
2402 rtx result = rtx_alloc (EQ_ATTR_ALT);
2404 XINT (result, 0) = XINT (s, 0);
2405 XINT (result, 1) = 1 - XINT (s, 1);
2407 return result;
2410 /* Return EQ_ATTR_ALT expression representing set containing elements set
2411 in E. */
2413 static rtx
2414 mk_attr_alt (int e)
2416 rtx result = rtx_alloc (EQ_ATTR_ALT);
2418 XINT (result, 0) = e;
2419 XINT (result, 1) = 0;
2421 return result;
2424 /* Given an expression, see if it can be simplified for a particular insn
2425 code based on the values of other attributes being tested. This can
2426 eliminate nested get_attr_... calls.
2428 Note that if an endless recursion is specified in the patterns, the
2429 optimization will loop. However, it will do so in precisely the cases where
2430 an infinite recursion loop could occur during compilation. It's better that
2431 it occurs here! */
2433 static rtx
2434 simplify_test_exp (rtx exp, int insn_code, int insn_index)
2436 rtx left, right;
2437 struct attr_desc *attr;
2438 struct attr_value *av;
2439 struct insn_ent *ie;
2440 struct attr_value_list *iv;
2441 int i;
2442 rtx newexp = exp;
2443 bool left_alt, right_alt;
2445 /* Don't re-simplify something we already simplified. */
2446 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
2447 return exp;
2449 switch (GET_CODE (exp))
2451 case AND:
2452 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2453 if (left == false_rtx)
2454 return false_rtx;
2455 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2456 if (right == false_rtx)
2457 return false_rtx;
2459 if (GET_CODE (left) == EQ_ATTR_ALT
2460 && GET_CODE (right) == EQ_ATTR_ALT)
2462 exp = attr_alt_intersection (left, right);
2463 return simplify_test_exp (exp, insn_code, insn_index);
2466 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2467 present on both sides, apply the distributive law since this will
2468 yield simplifications. */
2469 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2470 && compute_alternative_mask (left, IOR)
2471 && compute_alternative_mask (right, IOR))
2473 if (GET_CODE (left) == IOR)
2475 rtx tem = left;
2476 left = right;
2477 right = tem;
2480 newexp = attr_rtx (IOR,
2481 attr_rtx (AND, left, XEXP (right, 0)),
2482 attr_rtx (AND, left, XEXP (right, 1)));
2484 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2487 /* Try with the term on both sides. */
2488 right = simplify_and_tree (right, &left, insn_code, insn_index);
2489 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2490 left = simplify_and_tree (left, &right, insn_code, insn_index);
2492 if (left == false_rtx || right == false_rtx)
2493 return false_rtx;
2494 else if (left == true_rtx)
2496 return right;
2498 else if (right == true_rtx)
2500 return left;
2502 /* See if all or all but one of the insn's alternatives are specified
2503 in this tree. Optimize if so. */
2505 if (GET_CODE (left) == NOT)
2506 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2507 && XSTR (XEXP (left, 0), 0) == alternative_name);
2508 else
2509 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2510 && XINT (left, 1));
2512 if (GET_CODE (right) == NOT)
2513 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2514 && XSTR (XEXP (right, 0), 0) == alternative_name);
2515 else
2516 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2517 && XINT (right, 1));
2519 if (insn_code >= 0
2520 && (GET_CODE (left) == AND
2521 || left_alt
2522 || GET_CODE (right) == AND
2523 || right_alt))
2525 i = compute_alternative_mask (exp, AND);
2526 if (i & ~insn_alternatives[insn_code])
2527 fatal ("invalid alternative specified for pattern number %d",
2528 insn_index);
2530 /* If all alternatives are excluded, this is false. */
2531 i ^= insn_alternatives[insn_code];
2532 if (i == 0)
2533 return false_rtx;
2534 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2536 /* If just one excluded, AND a comparison with that one to the
2537 front of the tree. The others will be eliminated by
2538 optimization. We do not want to do this if the insn has one
2539 alternative and we have tested none of them! */
2540 left = make_alternative_compare (i);
2541 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2542 newexp = attr_rtx (AND, left, right);
2544 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2548 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2550 newexp = attr_rtx (AND, left, right);
2551 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2553 break;
2555 case IOR:
2556 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2557 if (left == true_rtx)
2558 return true_rtx;
2559 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2560 if (right == true_rtx)
2561 return true_rtx;
2563 if (GET_CODE (left) == EQ_ATTR_ALT
2564 && GET_CODE (right) == EQ_ATTR_ALT)
2566 exp = attr_alt_union (left, right);
2567 return simplify_test_exp (exp, insn_code, insn_index);
2570 right = simplify_or_tree (right, &left, insn_code, insn_index);
2571 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2572 left = simplify_or_tree (left, &right, insn_code, insn_index);
2574 if (right == true_rtx || left == true_rtx)
2575 return true_rtx;
2576 else if (left == false_rtx)
2578 return right;
2580 else if (right == false_rtx)
2582 return left;
2585 /* Test for simple cases where the distributive law is useful. I.e.,
2586 convert (ior (and (x) (y))
2587 (and (x) (z)))
2588 to (and (x)
2589 (ior (y) (z)))
2592 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2593 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
2595 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2597 left = XEXP (left, 0);
2598 right = newexp;
2599 newexp = attr_rtx (AND, left, right);
2600 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2603 /* See if all or all but one of the insn's alternatives are specified
2604 in this tree. Optimize if so. */
2606 else if (insn_code >= 0
2607 && (GET_CODE (left) == IOR
2608 || (GET_CODE (left) == EQ_ATTR_ALT
2609 && !XINT (left, 1))
2610 || (GET_CODE (left) == EQ_ATTR
2611 && XSTR (left, 0) == alternative_name)
2612 || GET_CODE (right) == IOR
2613 || (GET_CODE (right) == EQ_ATTR_ALT
2614 && !XINT (right, 1))
2615 || (GET_CODE (right) == EQ_ATTR
2616 && XSTR (right, 0) == alternative_name)))
2618 i = compute_alternative_mask (exp, IOR);
2619 if (i & ~insn_alternatives[insn_code])
2620 fatal ("invalid alternative specified for pattern number %d",
2621 insn_index);
2623 /* If all alternatives are included, this is true. */
2624 i ^= insn_alternatives[insn_code];
2625 if (i == 0)
2626 return true_rtx;
2627 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2629 /* If just one excluded, IOR a comparison with that one to the
2630 front of the tree. The others will be eliminated by
2631 optimization. We do not want to do this if the insn has one
2632 alternative and we have tested none of them! */
2633 left = make_alternative_compare (i);
2634 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2635 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2637 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2641 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2643 newexp = attr_rtx (IOR, left, right);
2644 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2646 break;
2648 case NOT:
2649 if (GET_CODE (XEXP (exp, 0)) == NOT)
2651 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2652 insn_code, insn_index);
2653 return left;
2656 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2657 if (GET_CODE (left) == NOT)
2658 return XEXP (left, 0);
2660 if (left == false_rtx)
2661 return true_rtx;
2662 if (left == true_rtx)
2663 return false_rtx;
2665 if (GET_CODE (left) == EQ_ATTR_ALT)
2667 exp = attr_alt_complement (left);
2668 return simplify_test_exp (exp, insn_code, insn_index);
2671 /* Try to apply De`Morgan's laws. */
2672 if (GET_CODE (left) == IOR)
2674 newexp = attr_rtx (AND,
2675 attr_rtx (NOT, XEXP (left, 0)),
2676 attr_rtx (NOT, XEXP (left, 1)));
2678 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2680 else if (GET_CODE (left) == AND)
2682 newexp = attr_rtx (IOR,
2683 attr_rtx (NOT, XEXP (left, 0)),
2684 attr_rtx (NOT, XEXP (left, 1)));
2686 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2688 else if (left != XEXP (exp, 0))
2690 newexp = attr_rtx (NOT, left);
2692 break;
2694 case EQ_ATTR_ALT:
2695 if (!XINT (exp, 0))
2696 return XINT (exp, 1) ? true_rtx : false_rtx;
2697 break;
2699 case EQ_ATTR:
2700 if (XSTR (exp, 0) == alternative_name)
2702 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2703 break;
2706 /* Look at the value for this insn code in the specified attribute.
2707 We normally can replace this comparison with the condition that
2708 would give this insn the values being tested for. */
2709 if (insn_code >= 0
2710 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
2712 rtx x;
2714 av = NULL;
2715 if (insn_code_values)
2717 for (iv = insn_code_values[insn_code]; iv; iv = iv->next)
2718 if (iv->attr == attr)
2720 av = iv->av;
2721 break;
2724 else
2726 for (av = attr->first_value; av; av = av->next)
2727 for (ie = av->first_insn; ie; ie = ie->next)
2728 if (ie->def->insn_code == insn_code)
2729 goto got_av;
2732 if (av)
2734 got_av:
2735 x = evaluate_eq_attr (exp, attr, av->value,
2736 insn_code, insn_index);
2737 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2738 if (attr_rtx_cost(x) < 20)
2739 return x;
2742 break;
2744 default:
2745 break;
2748 /* We have already simplified this expression. Simplifying it again
2749 won't buy anything unless we weren't given a valid insn code
2750 to process (i.e., we are canonicalizing something.). */
2751 if (insn_code != -2
2752 && ! ATTR_IND_SIMPLIFIED_P (newexp))
2753 return copy_rtx_unchanging (newexp);
2755 return newexp;
2758 /* Optimize the attribute lists by seeing if we can determine conditional
2759 values from the known values of other attributes. This will save subroutine
2760 calls during the compilation. */
2762 static void
2763 optimize_attrs (void)
2765 struct attr_desc *attr;
2766 struct attr_value *av;
2767 struct insn_ent *ie;
2768 rtx newexp;
2769 int i;
2770 struct attr_value_list *ivbuf;
2771 struct attr_value_list *iv;
2773 /* For each insn code, make a list of all the insn_ent's for it,
2774 for all values for all attributes. */
2776 if (num_insn_ents == 0)
2777 return;
2779 /* Make 2 extra elements, for "code" values -2 and -1. */
2780 insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2);
2782 /* Offset the table address so we can index by -2 or -1. */
2783 insn_code_values += 2;
2785 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents);
2787 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2788 for (attr = attrs[i]; attr; attr = attr->next)
2789 for (av = attr->first_value; av; av = av->next)
2790 for (ie = av->first_insn; ie; ie = ie->next)
2792 iv->attr = attr;
2793 iv->av = av;
2794 iv->ie = ie;
2795 iv->next = insn_code_values[ie->def->insn_code];
2796 insn_code_values[ie->def->insn_code] = iv;
2797 iv++;
2800 /* Sanity check on num_insn_ents. */
2801 gcc_assert (iv == ivbuf + num_insn_ents);
2803 /* Process one insn code at a time. */
2804 for (i = -2; i < insn_code_number; i++)
2806 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2807 We use it to mean "already simplified for this insn". */
2808 for (iv = insn_code_values[i]; iv; iv = iv->next)
2809 clear_struct_flag (iv->av->value);
2811 for (iv = insn_code_values[i]; iv; iv = iv->next)
2813 struct obstack *old = rtl_obstack;
2815 attr = iv->attr;
2816 av = iv->av;
2817 ie = iv->ie;
2818 if (GET_CODE (av->value) != COND)
2819 continue;
2821 rtl_obstack = temp_obstack;
2822 newexp = av->value;
2823 while (GET_CODE (newexp) == COND)
2825 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2826 ie->def->insn_index);
2827 if (newexp2 == newexp)
2828 break;
2829 newexp = newexp2;
2832 rtl_obstack = old;
2833 if (newexp != av->value)
2835 newexp = attr_copy_rtx (newexp);
2836 remove_insn_ent (av, ie);
2837 av = get_attr_value (newexp, attr, ie->def->insn_code);
2838 iv->av = av;
2839 insert_insn_ent (av, ie);
2844 free (ivbuf);
2845 free (insn_code_values - 2);
2846 insn_code_values = NULL;
2849 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2851 static void
2852 clear_struct_flag (rtx x)
2854 int i;
2855 int j;
2856 enum rtx_code code;
2857 const char *fmt;
2859 ATTR_CURR_SIMPLIFIED_P (x) = 0;
2860 if (ATTR_IND_SIMPLIFIED_P (x))
2861 return;
2863 code = GET_CODE (x);
2865 switch (code)
2867 case REG:
2868 case CONST_INT:
2869 case CONST_DOUBLE:
2870 case CONST_VECTOR:
2871 case SYMBOL_REF:
2872 case CODE_LABEL:
2873 case PC:
2874 case CC0:
2875 case EQ_ATTR:
2876 case ATTR_FLAG:
2877 return;
2879 default:
2880 break;
2883 /* Compare the elements. If any pair of corresponding elements
2884 fail to match, return 0 for the whole things. */
2886 fmt = GET_RTX_FORMAT (code);
2887 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2889 switch (fmt[i])
2891 case 'V':
2892 case 'E':
2893 for (j = 0; j < XVECLEN (x, i); j++)
2894 clear_struct_flag (XVECEXP (x, i, j));
2895 break;
2897 case 'e':
2898 clear_struct_flag (XEXP (x, i));
2899 break;
2904 /* Add attribute value NAME to the beginning of ATTR's list. */
2906 static void
2907 add_attr_value (struct attr_desc *attr, const char *name)
2909 struct attr_value *av;
2911 av = oballoc (struct attr_value);
2912 av->value = attr_rtx (CONST_STRING, name);
2913 av->next = attr->first_value;
2914 attr->first_value = av;
2915 av->first_insn = NULL;
2916 av->num_insns = 0;
2917 av->has_asm_insn = 0;
2920 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
2922 static void
2923 gen_attr (rtx exp, int lineno)
2925 struct enum_type *et;
2926 struct enum_value *ev;
2927 struct attr_desc *attr;
2928 const char *name_ptr;
2929 char *p;
2931 /* Make a new attribute structure. Check for duplicate by looking at
2932 attr->default_val, since it is initialized by this routine. */
2933 attr = find_attr (&XSTR (exp, 0), 1);
2934 if (attr->default_val)
2936 error_with_line (lineno, "duplicate definition for attribute %s",
2937 attr->name);
2938 message_with_line (attr->lineno, "previous definition");
2939 return;
2941 attr->lineno = lineno;
2943 if (GET_CODE (exp) == DEFINE_ENUM_ATTR)
2945 attr->enum_name = XSTR (exp, 1);
2946 et = lookup_enum_type (XSTR (exp, 1));
2947 if (!et || !et->md_p)
2948 error_with_line (lineno, "No define_enum called `%s' defined",
2949 attr->name);
2950 for (ev = et->values; ev; ev = ev->next)
2951 add_attr_value (attr, ev->name);
2953 else if (*XSTR (exp, 1) == '\0')
2954 attr->is_numeric = 1;
2955 else
2957 name_ptr = XSTR (exp, 1);
2958 while ((p = next_comma_elt (&name_ptr)) != NULL)
2959 add_attr_value (attr, p);
2962 if (GET_CODE (XEXP (exp, 2)) == CONST)
2964 attr->is_const = 1;
2965 if (attr->is_numeric)
2966 error_with_line (lineno,
2967 "constant attributes may not take numeric values");
2969 /* Get rid of the CONST node. It is allowed only at top-level. */
2970 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
2973 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
2974 error_with_line (lineno, "`length' attribute must take numeric values");
2976 /* Set up the default value. */
2977 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
2978 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
2981 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2982 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2983 number of alternatives as this should be checked elsewhere. */
2985 static int
2986 count_alternatives (rtx exp)
2988 int i, j, n;
2989 const char *fmt;
2991 if (GET_CODE (exp) == MATCH_OPERAND)
2992 return n_comma_elts (XSTR (exp, 2));
2994 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2995 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2996 switch (*fmt++)
2998 case 'e':
2999 case 'u':
3000 n = count_alternatives (XEXP (exp, i));
3001 if (n)
3002 return n;
3003 break;
3005 case 'E':
3006 case 'V':
3007 if (XVEC (exp, i) != NULL)
3008 for (j = 0; j < XVECLEN (exp, i); j++)
3010 n = count_alternatives (XVECEXP (exp, i, j));
3011 if (n)
3012 return n;
3016 return 0;
3019 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3020 `alternative' attribute. */
3022 static int
3023 compares_alternatives_p (rtx exp)
3025 int i, j;
3026 const char *fmt;
3028 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3029 return 1;
3031 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3032 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3033 switch (*fmt++)
3035 case 'e':
3036 case 'u':
3037 if (compares_alternatives_p (XEXP (exp, i)))
3038 return 1;
3039 break;
3041 case 'E':
3042 for (j = 0; j < XVECLEN (exp, i); j++)
3043 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3044 return 1;
3045 break;
3048 return 0;
3051 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3053 static void
3054 gen_insn (rtx exp, int lineno)
3056 struct insn_def *id;
3058 id = oballoc (struct insn_def);
3059 id->next = defs;
3060 defs = id;
3061 id->def = exp;
3062 id->lineno = lineno;
3064 switch (GET_CODE (exp))
3066 case DEFINE_INSN:
3067 id->insn_code = insn_code_number;
3068 id->insn_index = insn_index_number;
3069 id->num_alternatives = count_alternatives (exp);
3070 if (id->num_alternatives == 0)
3071 id->num_alternatives = 1;
3072 id->vec_idx = 4;
3073 break;
3075 case DEFINE_PEEPHOLE:
3076 id->insn_code = insn_code_number;
3077 id->insn_index = insn_index_number;
3078 id->num_alternatives = count_alternatives (exp);
3079 if (id->num_alternatives == 0)
3080 id->num_alternatives = 1;
3081 id->vec_idx = 3;
3082 break;
3084 case DEFINE_ASM_ATTRIBUTES:
3085 id->insn_code = -1;
3086 id->insn_index = -1;
3087 id->num_alternatives = 1;
3088 id->vec_idx = 0;
3089 got_define_asm_attributes = 1;
3090 break;
3092 default:
3093 gcc_unreachable ();
3097 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3098 true or annul false is specified, and make a `struct delay_desc'. */
3100 static void
3101 gen_delay (rtx def, int lineno)
3103 struct delay_desc *delay;
3104 int i;
3106 if (XVECLEN (def, 1) % 3 != 0)
3108 error_with_line (lineno,
3109 "number of elements in DEFINE_DELAY must"
3110 " be multiple of three");
3111 return;
3114 for (i = 0; i < XVECLEN (def, 1); i += 3)
3116 if (XVECEXP (def, 1, i + 1))
3117 have_annul_true = 1;
3118 if (XVECEXP (def, 1, i + 2))
3119 have_annul_false = 1;
3122 delay = oballoc (struct delay_desc);
3123 delay->def = def;
3124 delay->num = ++num_delays;
3125 delay->next = delays;
3126 delay->lineno = lineno;
3127 delays = delay;
3130 /* Names of attributes that could be possibly cached. */
3131 static const char *cached_attrs[32];
3132 /* Number of such attributes. */
3133 static int cached_attr_count;
3134 /* Bitmasks of possibly cached attributes. */
3135 static unsigned int attrs_seen_once, attrs_seen_more_than_once;
3136 static unsigned int attrs_to_cache;
3137 static unsigned int attrs_cached_inside, attrs_cached_after;
3139 /* Finds non-const attributes that could be possibly cached.
3140 When create is TRUE, fills in cached_attrs array.
3141 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3142 bitmasks. */
3144 static void
3145 find_attrs_to_cache (rtx exp, bool create)
3147 int i;
3148 const char *name;
3149 struct attr_desc *attr;
3151 if (exp == NULL)
3152 return;
3154 switch (GET_CODE (exp))
3156 case NOT:
3157 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3158 find_attrs_to_cache (XEXP (exp, 0), create);
3159 return;
3161 case EQ_ATTR:
3162 name = XSTR (exp, 0);
3163 if (name == alternative_name)
3164 return;
3165 for (i = 0; i < cached_attr_count; i++)
3166 if (name == cached_attrs[i])
3168 if ((attrs_seen_once & (1U << i)) != 0)
3169 attrs_seen_more_than_once |= (1U << i);
3170 else
3171 attrs_seen_once |= (1U << i);
3172 return;
3174 if (!create)
3175 return;
3176 attr = find_attr (&name, 0);
3177 gcc_assert (attr);
3178 if (attr->is_const)
3179 return;
3180 if (cached_attr_count == 32)
3181 return;
3182 cached_attrs[cached_attr_count] = XSTR (exp, 0);
3183 attrs_seen_once |= (1U << cached_attr_count);
3184 cached_attr_count++;
3185 return;
3187 case AND:
3188 case IOR:
3189 find_attrs_to_cache (XEXP (exp, 0), create);
3190 find_attrs_to_cache (XEXP (exp, 1), create);
3191 return;
3193 case COND:
3194 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3195 find_attrs_to_cache (XVECEXP (exp, 0, i), create);
3196 return;
3198 default:
3199 return;
3203 /* Given a piece of RTX, print a C expression to test its truth value.
3204 We use AND and IOR both for logical and bit-wise operations, so
3205 interpret them as logical unless they are inside a comparison expression. */
3207 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3208 #define FLG_BITWISE 1
3209 /* Set if cached attribute will be known initialized in else block after
3210 this condition. This is true for LHS of toplevel && and || and
3211 even for RHS of ||, but not for RHS of &&. */
3212 #define FLG_AFTER 2
3213 /* Set if cached attribute will be known initialized in then block after
3214 this condition. This is true for LHS of toplevel && and || and
3215 even for RHS of &&, but not for RHS of ||. */
3216 #define FLG_INSIDE 4
3217 /* Cleared when an operand of &&. */
3218 #define FLG_OUTSIDE_AND 8
3220 static unsigned int
3221 write_test_expr (rtx exp, unsigned int attrs_cached, int flags)
3223 int comparison_operator = 0;
3224 RTX_CODE code;
3225 struct attr_desc *attr;
3227 /* In order not to worry about operator precedence, surround our part of
3228 the expression with parentheses. */
3230 printf ("(");
3231 code = GET_CODE (exp);
3232 switch (code)
3234 /* Binary operators. */
3235 case GEU: case GTU:
3236 case LEU: case LTU:
3237 printf ("(unsigned) ");
3238 /* Fall through. */
3240 case EQ: case NE:
3241 case GE: case GT:
3242 case LE: case LT:
3243 comparison_operator = FLG_BITWISE;
3245 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3246 case AND: case IOR: case XOR:
3247 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
3248 if ((code != AND && code != IOR) || (flags & FLG_BITWISE))
3250 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3251 write_test_expr (XEXP (exp, 0), attrs_cached,
3252 flags | comparison_operator);
3254 else
3256 if (code == AND)
3257 flags &= ~FLG_OUTSIDE_AND;
3258 if (GET_CODE (XEXP (exp, 0)) == code
3259 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3260 || (GET_CODE (XEXP (exp, 0)) == NOT
3261 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR))
3262 attrs_cached
3263 = write_test_expr (XEXP (exp, 0), attrs_cached, flags);
3264 else
3265 write_test_expr (XEXP (exp, 0), attrs_cached, flags);
3267 switch (code)
3269 case EQ:
3270 printf (" == ");
3271 break;
3272 case NE:
3273 printf (" != ");
3274 break;
3275 case GE:
3276 printf (" >= ");
3277 break;
3278 case GT:
3279 printf (" > ");
3280 break;
3281 case GEU:
3282 printf (" >= (unsigned) ");
3283 break;
3284 case GTU:
3285 printf (" > (unsigned) ");
3286 break;
3287 case LE:
3288 printf (" <= ");
3289 break;
3290 case LT:
3291 printf (" < ");
3292 break;
3293 case LEU:
3294 printf (" <= (unsigned) ");
3295 break;
3296 case LTU:
3297 printf (" < (unsigned) ");
3298 break;
3299 case PLUS:
3300 printf (" + ");
3301 break;
3302 case MINUS:
3303 printf (" - ");
3304 break;
3305 case MULT:
3306 printf (" * ");
3307 break;
3308 case DIV:
3309 printf (" / ");
3310 break;
3311 case MOD:
3312 printf (" %% ");
3313 break;
3314 case AND:
3315 if (flags & FLG_BITWISE)
3316 printf (" & ");
3317 else
3318 printf (" && ");
3319 break;
3320 case IOR:
3321 if (flags & FLG_BITWISE)
3322 printf (" | ");
3323 else
3324 printf (" || ");
3325 break;
3326 case XOR:
3327 printf (" ^ ");
3328 break;
3329 case ASHIFT:
3330 printf (" << ");
3331 break;
3332 case LSHIFTRT:
3333 case ASHIFTRT:
3334 printf (" >> ");
3335 break;
3336 default:
3337 gcc_unreachable ();
3340 if (code == AND)
3342 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3343 cached_x is only known to be initialized in then block. */
3344 flags &= ~FLG_AFTER;
3346 else if (code == IOR)
3348 if (flags & FLG_OUTSIDE_AND)
3349 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3350 cached_x is only known to be initialized in else block
3351 and else if conditions. */
3352 flags &= ~FLG_INSIDE;
3353 else
3354 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3355 && something_else)
3356 cached_x is not know to be initialized anywhere. */
3357 flags &= ~(FLG_AFTER | FLG_INSIDE);
3359 if ((code == AND || code == IOR)
3360 && (GET_CODE (XEXP (exp, 1)) == code
3361 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR
3362 || (GET_CODE (XEXP (exp, 1)) == NOT
3363 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR)))
3364 attrs_cached
3365 = write_test_expr (XEXP (exp, 1), attrs_cached, flags);
3366 else
3367 write_test_expr (XEXP (exp, 1), attrs_cached,
3368 flags | comparison_operator);
3369 break;
3371 case NOT:
3372 /* Special-case (not (eq_attrq "alternative" "x")) */
3373 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3375 if (XSTR (XEXP (exp, 0), 0) == alternative_name)
3377 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3378 break;
3381 printf ("! ");
3382 attrs_cached = write_test_expr (XEXP (exp, 0), attrs_cached, flags);
3383 break;
3386 /* Otherwise, fall through to normal unary operator. */
3388 /* Unary operators. */
3389 case ABS: case NEG:
3390 switch (code)
3392 case NOT:
3393 if (flags & FLG_BITWISE)
3394 printf ("~ ");
3395 else
3396 printf ("! ");
3397 break;
3398 case ABS:
3399 printf ("abs ");
3400 break;
3401 case NEG:
3402 printf ("-");
3403 break;
3404 default:
3405 gcc_unreachable ();
3408 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND);
3409 write_test_expr (XEXP (exp, 0), attrs_cached, flags);
3410 break;
3412 case EQ_ATTR_ALT:
3414 int set = XINT (exp, 0), bit = 0;
3416 if (flags & FLG_BITWISE)
3417 fatal ("EQ_ATTR_ALT not valid inside comparison");
3419 if (!set)
3420 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3422 if (!(set & (set - 1)))
3424 if (!(set & 0xffff))
3426 bit += 16;
3427 set >>= 16;
3429 if (!(set & 0xff))
3431 bit += 8;
3432 set >>= 8;
3434 if (!(set & 0xf))
3436 bit += 4;
3437 set >>= 4;
3439 if (!(set & 0x3))
3441 bit += 2;
3442 set >>= 2;
3444 if (!(set & 1))
3445 bit++;
3447 printf ("which_alternative %s= %d",
3448 XINT (exp, 1) ? "!" : "=", bit);
3450 else
3452 printf ("%s((1 << which_alternative) & %#x)",
3453 XINT (exp, 1) ? "!" : "", set);
3456 break;
3458 /* Comparison test of an attribute with a value. Most of these will
3459 have been removed by optimization. Handle "alternative"
3460 specially and give error if EQ_ATTR present inside a comparison. */
3461 case EQ_ATTR:
3462 if (flags & FLG_BITWISE)
3463 fatal ("EQ_ATTR not valid inside comparison");
3465 if (XSTR (exp, 0) == alternative_name)
3467 printf ("which_alternative == %s", XSTR (exp, 1));
3468 break;
3471 attr = find_attr (&XSTR (exp, 0), 0);
3472 gcc_assert (attr);
3474 /* Now is the time to expand the value of a constant attribute. */
3475 if (attr->is_const)
3477 write_test_expr (evaluate_eq_attr (exp, attr,
3478 attr->default_val->value, -2, -2),
3479 attrs_cached, 0);
3481 else
3483 int i;
3484 for (i = 0; i < cached_attr_count; i++)
3485 if (attr->name == cached_attrs[i])
3486 break;
3487 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0)
3488 printf ("cached_%s", attr->name);
3489 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0)
3491 printf ("(cached_%s = get_attr_%s (insn))",
3492 attr->name, attr->name);
3493 if (flags & FLG_AFTER)
3494 attrs_cached_after |= (1U << i);
3495 if (flags & FLG_INSIDE)
3496 attrs_cached_inside |= (1U << i);
3497 attrs_cached |= (1U << i);
3499 else
3500 printf ("get_attr_%s (insn)", attr->name);
3501 printf (" == ");
3502 write_attr_valueq (attr, XSTR (exp, 1));
3504 break;
3506 /* Comparison test of flags for define_delays. */
3507 case ATTR_FLAG:
3508 if (flags & FLG_BITWISE)
3509 fatal ("ATTR_FLAG not valid inside comparison");
3510 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3511 break;
3513 /* See if an operand matches a predicate. */
3514 case MATCH_OPERAND:
3515 /* If only a mode is given, just ensure the mode matches the operand.
3516 If neither a mode nor predicate is given, error. */
3517 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
3519 if (GET_MODE (exp) == VOIDmode)
3520 fatal ("null MATCH_OPERAND specified as test");
3521 else
3522 printf ("GET_MODE (operands[%d]) == %smode",
3523 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3525 else
3526 printf ("%s (operands[%d], %smode)",
3527 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3528 break;
3530 /* Constant integer. */
3531 case CONST_INT:
3532 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
3533 break;
3535 /* A random C expression. */
3536 case SYMBOL_REF:
3537 print_c_condition (XSTR (exp, 0));
3538 break;
3540 /* The address of the branch target. */
3541 case MATCH_DUP:
3542 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3543 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
3544 break;
3546 case PC:
3547 /* The address of the current insn. We implement this actually as the
3548 address of the current insn for backward branches, but the last
3549 address of the next insn for forward branches, and both with
3550 adjustments that account for the worst-case possible stretching of
3551 intervening alignments between this insn and its destination. */
3552 printf ("insn_current_reference_address (insn)");
3553 break;
3555 case CONST_STRING:
3556 printf ("%s", XSTR (exp, 0));
3557 break;
3559 case IF_THEN_ELSE:
3560 write_test_expr (XEXP (exp, 0), attrs_cached, 0);
3561 printf (" ? ");
3562 write_test_expr (XEXP (exp, 1), attrs_cached, FLG_BITWISE);
3563 printf (" : ");
3564 write_test_expr (XEXP (exp, 2), attrs_cached, FLG_BITWISE);
3565 break;
3567 default:
3568 fatal ("bad RTX code `%s' in attribute calculation\n",
3569 GET_RTX_NAME (code));
3572 printf (")");
3573 return attrs_cached;
3576 /* Given an attribute value, return the maximum CONST_STRING argument
3577 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3579 static int
3580 max_attr_value (rtx exp, int *unknownp)
3582 int current_max;
3583 int i, n;
3585 switch (GET_CODE (exp))
3587 case CONST_STRING:
3588 current_max = atoi (XSTR (exp, 0));
3589 break;
3591 case COND:
3592 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3593 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3595 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3596 if (n > current_max)
3597 current_max = n;
3599 break;
3601 case IF_THEN_ELSE:
3602 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3603 n = max_attr_value (XEXP (exp, 2), unknownp);
3604 if (n > current_max)
3605 current_max = n;
3606 break;
3608 default:
3609 *unknownp = 1;
3610 current_max = INT_MAX;
3611 break;
3614 return current_max;
3617 /* Given an attribute value, return the minimum CONST_STRING argument
3618 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3620 static int
3621 min_attr_value (rtx exp, int *unknownp)
3623 int current_min;
3624 int i, n;
3626 switch (GET_CODE (exp))
3628 case CONST_STRING:
3629 current_min = atoi (XSTR (exp, 0));
3630 break;
3632 case COND:
3633 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3634 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3636 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3637 if (n < current_min)
3638 current_min = n;
3640 break;
3642 case IF_THEN_ELSE:
3643 current_min = min_attr_value (XEXP (exp, 1), unknownp);
3644 n = min_attr_value (XEXP (exp, 2), unknownp);
3645 if (n < current_min)
3646 current_min = n;
3647 break;
3649 default:
3650 *unknownp = 1;
3651 current_min = INT_MAX;
3652 break;
3655 return current_min;
3658 /* Given an attribute value, return the result of ORing together all
3659 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3660 if the numeric value is not known. */
3662 static int
3663 or_attr_value (rtx exp, int *unknownp)
3665 int current_or;
3666 int i;
3668 switch (GET_CODE (exp))
3670 case CONST_STRING:
3671 current_or = atoi (XSTR (exp, 0));
3672 break;
3674 case COND:
3675 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3676 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3677 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3678 break;
3680 case IF_THEN_ELSE:
3681 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3682 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3683 break;
3685 default:
3686 *unknownp = 1;
3687 current_or = -1;
3688 break;
3691 return current_or;
3694 /* Scan an attribute value, possibly a conditional, and record what actions
3695 will be required to do any conditional tests in it.
3697 Specifically, set
3698 `must_extract' if we need to extract the insn operands
3699 `must_constrain' if we must compute `which_alternative'
3700 `address_used' if an address expression was used
3701 `length_used' if an (eq_attr "length" ...) was used
3704 static void
3705 walk_attr_value (rtx exp)
3707 int i, j;
3708 const char *fmt;
3709 RTX_CODE code;
3711 if (exp == NULL)
3712 return;
3714 code = GET_CODE (exp);
3715 switch (code)
3717 case SYMBOL_REF:
3718 if (! ATTR_IND_SIMPLIFIED_P (exp))
3719 /* Since this is an arbitrary expression, it can look at anything.
3720 However, constant expressions do not depend on any particular
3721 insn. */
3722 must_extract = must_constrain = 1;
3723 return;
3725 case MATCH_OPERAND:
3726 must_extract = 1;
3727 return;
3729 case EQ_ATTR_ALT:
3730 must_extract = must_constrain = 1;
3731 break;
3733 case EQ_ATTR:
3734 if (XSTR (exp, 0) == alternative_name)
3735 must_extract = must_constrain = 1;
3736 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
3737 length_used = 1;
3738 return;
3740 case MATCH_DUP:
3741 must_extract = 1;
3742 address_used = 1;
3743 return;
3745 case PC:
3746 address_used = 1;
3747 return;
3749 case ATTR_FLAG:
3750 return;
3752 default:
3753 break;
3756 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3757 switch (*fmt++)
3759 case 'e':
3760 case 'u':
3761 walk_attr_value (XEXP (exp, i));
3762 break;
3764 case 'E':
3765 if (XVEC (exp, i) != NULL)
3766 for (j = 0; j < XVECLEN (exp, i); j++)
3767 walk_attr_value (XVECEXP (exp, i, j));
3768 break;
3772 /* Write out a function to obtain the attribute for a given INSN. */
3774 static void
3775 write_attr_get (struct attr_desc *attr)
3777 struct attr_value *av, *common_av;
3778 int i, j;
3780 /* Find the most used attribute value. Handle that as the `default' of the
3781 switch we will generate. */
3782 common_av = find_most_used (attr);
3784 /* Write out start of function, then all values with explicit `case' lines,
3785 then a `default', then the value with the most uses. */
3786 if (attr->enum_name)
3787 printf ("enum %s\n", attr->enum_name);
3788 else if (!attr->is_numeric)
3789 printf ("enum attr_%s\n", attr->name);
3790 else
3791 printf ("int\n");
3793 /* If the attribute name starts with a star, the remainder is the name of
3794 the subroutine to use, instead of `get_attr_...'. */
3795 if (attr->name[0] == '*')
3796 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3797 else if (attr->is_const == 0)
3798 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3799 else
3801 printf ("get_attr_%s (void)\n", attr->name);
3802 printf ("{\n");
3804 for (av = attr->first_value; av; av = av->next)
3805 if (av->num_insns == 1)
3806 write_attr_set (attr, 2, av->value, "return", ";",
3807 true_rtx, av->first_insn->def->insn_code,
3808 av->first_insn->def->insn_index, 0);
3809 else if (av->num_insns != 0)
3810 write_attr_set (attr, 2, av->value, "return", ";",
3811 true_rtx, -2, 0, 0);
3813 printf ("}\n\n");
3814 return;
3817 printf ("{\n");
3819 /* Find attributes that are worth caching in the conditions. */
3820 cached_attr_count = 0;
3821 attrs_seen_more_than_once = 0;
3822 for (av = attr->first_value; av; av = av->next)
3824 attrs_seen_once = 0;
3825 find_attrs_to_cache (av->value, true);
3827 /* Remove those that aren't worth caching from the array. */
3828 for (i = 0, j = 0; i < cached_attr_count; i++)
3829 if ((attrs_seen_more_than_once & (1U << i)) != 0)
3831 const char *name = cached_attrs[i];
3832 struct attr_desc *cached_attr;
3833 if (i != j)
3834 cached_attrs[j] = name;
3835 cached_attr = find_attr (&name, 0);
3836 gcc_assert (cached_attr && cached_attr->is_const == 0);
3837 if (cached_attr->enum_name)
3838 printf (" enum %s", cached_attr->enum_name);
3839 else if (!cached_attr->is_numeric)
3840 printf (" enum attr_%s", cached_attr->name);
3841 else
3842 printf (" int");
3843 printf (" cached_%s ATTRIBUTE_UNUSED;\n", name);
3844 j++;
3846 cached_attr_count = j;
3847 if (cached_attr_count)
3848 printf ("\n");
3850 printf (" switch (recog_memoized (insn))\n");
3851 printf (" {\n");
3853 for (av = attr->first_value; av; av = av->next)
3854 if (av != common_av)
3855 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3857 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3858 printf (" }\n}\n\n");
3859 cached_attr_count = 0;
3862 /* Given an AND tree of known true terms (because we are inside an `if' with
3863 that as the condition or are in an `else' clause) and an expression,
3864 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3865 the bulk of the work. */
3867 static rtx
3868 eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
3870 rtx term;
3872 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3874 if (GET_CODE (known_true) == AND)
3876 exp = eliminate_known_true (XEXP (known_true, 0), exp,
3877 insn_code, insn_index);
3878 exp = eliminate_known_true (XEXP (known_true, 1), exp,
3879 insn_code, insn_index);
3881 else
3883 term = known_true;
3884 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3887 return exp;
3890 /* Write out a series of tests and assignment statements to perform tests and
3891 sets of an attribute value. We are passed an indentation amount and prefix
3892 and suffix strings to write around each attribute value (e.g., "return"
3893 and ";"). */
3895 static void
3896 write_attr_set (struct attr_desc *attr, int indent, rtx value,
3897 const char *prefix, const char *suffix, rtx known_true,
3898 int insn_code, int insn_index, unsigned int attrs_cached)
3900 if (GET_CODE (value) == COND)
3902 /* Assume the default value will be the default of the COND unless we
3903 find an always true expression. */
3904 rtx default_val = XEXP (value, 1);
3905 rtx our_known_true = known_true;
3906 rtx newexp;
3907 int first_if = 1;
3908 int i;
3910 if (cached_attr_count)
3912 attrs_seen_once = 0;
3913 attrs_seen_more_than_once = 0;
3914 for (i = 0; i < XVECLEN (value, 0); i += 2)
3915 find_attrs_to_cache (XVECEXP (value, 0, i), false);
3916 attrs_to_cache |= attrs_seen_more_than_once;
3919 for (i = 0; i < XVECLEN (value, 0); i += 2)
3921 rtx testexp;
3922 rtx inner_true;
3924 testexp = eliminate_known_true (our_known_true,
3925 XVECEXP (value, 0, i),
3926 insn_code, insn_index);
3927 newexp = attr_rtx (NOT, testexp);
3928 newexp = insert_right_side (AND, our_known_true, newexp,
3929 insn_code, insn_index);
3931 /* If the test expression is always true or if the next `known_true'
3932 expression is always false, this is the last case, so break
3933 out and let this value be the `else' case. */
3934 if (testexp == true_rtx || newexp == false_rtx)
3936 default_val = XVECEXP (value, 0, i + 1);
3937 break;
3940 /* Compute the expression to pass to our recursive call as being
3941 known true. */
3942 inner_true = insert_right_side (AND, our_known_true,
3943 testexp, insn_code, insn_index);
3945 /* If this is always false, skip it. */
3946 if (inner_true == false_rtx)
3947 continue;
3949 attrs_cached_inside = attrs_cached;
3950 attrs_cached_after = attrs_cached;
3951 write_indent (indent);
3952 printf ("%sif ", first_if ? "" : "else ");
3953 first_if = 0;
3954 write_test_expr (testexp, attrs_cached,
3955 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND));
3956 attrs_cached = attrs_cached_after;
3957 printf ("\n");
3958 write_indent (indent + 2);
3959 printf ("{\n");
3961 write_attr_set (attr, indent + 4,
3962 XVECEXP (value, 0, i + 1), prefix, suffix,
3963 inner_true, insn_code, insn_index,
3964 attrs_cached_inside);
3965 write_indent (indent + 2);
3966 printf ("}\n");
3967 our_known_true = newexp;
3970 if (! first_if)
3972 write_indent (indent);
3973 printf ("else\n");
3974 write_indent (indent + 2);
3975 printf ("{\n");
3978 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3979 prefix, suffix, our_known_true, insn_code, insn_index,
3980 attrs_cached);
3982 if (! first_if)
3984 write_indent (indent + 2);
3985 printf ("}\n");
3988 else
3990 write_indent (indent);
3991 printf ("%s ", prefix);
3992 write_attr_value (attr, value);
3993 printf ("%s\n", suffix);
3997 /* Write a series of case statements for every instruction in list IE.
3998 INDENT is the amount of indentation to write before each case. */
4000 static void
4001 write_insn_cases (struct insn_ent *ie, int indent)
4003 for (; ie != 0; ie = ie->next)
4004 if (ie->def->insn_code != -1)
4006 write_indent (indent);
4007 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
4008 printf ("case %d: /* define_peephole, line %d */\n",
4009 ie->def->insn_code, ie->def->lineno);
4010 else
4011 printf ("case %d: /* %s */\n",
4012 ie->def->insn_code, XSTR (ie->def->def, 0));
4016 /* Write out the computation for one attribute value. */
4018 static void
4019 write_attr_case (struct attr_desc *attr, struct attr_value *av,
4020 int write_case_lines, const char *prefix, const char *suffix,
4021 int indent, rtx known_true)
4023 if (av->num_insns == 0)
4024 return;
4026 if (av->has_asm_insn)
4028 write_indent (indent);
4029 printf ("case -1:\n");
4030 write_indent (indent + 2);
4031 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4032 write_indent (indent + 2);
4033 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
4034 write_indent (indent + 2);
4035 printf (" fatal_insn_not_found (insn);\n");
4038 if (write_case_lines)
4039 write_insn_cases (av->first_insn, indent);
4040 else
4042 write_indent (indent);
4043 printf ("default:\n");
4046 /* See what we have to do to output this value. */
4047 must_extract = must_constrain = address_used = 0;
4048 walk_attr_value (av->value);
4050 if (must_constrain)
4052 write_indent (indent + 2);
4053 printf ("extract_constrain_insn_cached (insn);\n");
4055 else if (must_extract)
4057 write_indent (indent + 2);
4058 printf ("extract_insn_cached (insn);\n");
4061 attrs_to_cache = 0;
4062 if (av->num_insns == 1)
4063 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
4064 known_true, av->first_insn->def->insn_code,
4065 av->first_insn->def->insn_index, 0);
4066 else
4067 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
4068 known_true, -2, 0, 0);
4070 if (strncmp (prefix, "return", 6))
4072 write_indent (indent + 2);
4073 printf ("break;\n");
4075 printf ("\n");
4078 /* Utilities to write in various forms. */
4080 static void
4081 write_attr_valueq (struct attr_desc *attr, const char *s)
4083 if (attr->is_numeric)
4085 int num = atoi (s);
4087 printf ("%d", num);
4089 if (num > 9 || num < 0)
4090 printf (" /* %#x */", num);
4092 else
4094 write_upcase (attr->enum_name ? attr->enum_name : attr->name);
4095 printf ("_");
4096 write_upcase (s);
4100 static void
4101 write_attr_value (struct attr_desc *attr, rtx value)
4103 int op;
4105 switch (GET_CODE (value))
4107 case CONST_STRING:
4108 write_attr_valueq (attr, XSTR (value, 0));
4109 break;
4111 case CONST_INT:
4112 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
4113 break;
4115 case SYMBOL_REF:
4116 print_c_condition (XSTR (value, 0));
4117 break;
4119 case ATTR:
4121 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
4122 printf ("get_attr_%s (%s)", attr2->name,
4123 (attr2->is_const ? "" : "insn"));
4125 break;
4127 case PLUS:
4128 op = '+';
4129 goto do_operator;
4130 case MINUS:
4131 op = '-';
4132 goto do_operator;
4133 case MULT:
4134 op = '*';
4135 goto do_operator;
4136 case DIV:
4137 op = '/';
4138 goto do_operator;
4139 case MOD:
4140 op = '%';
4141 goto do_operator;
4143 do_operator:
4144 write_attr_value (attr, XEXP (value, 0));
4145 putchar (' ');
4146 putchar (op);
4147 putchar (' ');
4148 write_attr_value (attr, XEXP (value, 1));
4149 break;
4151 default:
4152 gcc_unreachable ();
4156 static void
4157 write_upcase (const char *str)
4159 while (*str)
4161 /* The argument of TOUPPER should not have side effects. */
4162 putchar (TOUPPER(*str));
4163 str++;
4167 static void
4168 write_indent (int indent)
4170 for (; indent > 8; indent -= 8)
4171 printf ("\t");
4173 for (; indent; indent--)
4174 printf (" ");
4177 /* Write a subroutine that is given an insn that requires a delay slot, a
4178 delay slot ordinal, and a candidate insn. It returns nonzero if the
4179 candidate can be placed in the specified delay slot of the insn.
4181 We can write as many as three subroutines. `eligible_for_delay'
4182 handles normal delay slots, `eligible_for_annul_true' indicates that
4183 the specified insn can be annulled if the branch is true, and likewise
4184 for `eligible_for_annul_false'.
4186 KIND is a string distinguishing these three cases ("delay", "annul_true",
4187 or "annul_false"). */
4189 static void
4190 write_eligible_delay (const char *kind)
4192 struct delay_desc *delay;
4193 int max_slots;
4194 char str[50];
4195 const char *pstr;
4196 struct attr_desc *attr;
4197 struct attr_value *av, *common_av;
4198 int i;
4200 /* Compute the maximum number of delay slots required. We use the delay
4201 ordinal times this number plus one, plus the slot number as an index into
4202 the appropriate predicate to test. */
4204 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4205 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4206 max_slots = XVECLEN (delay->def, 1) / 3;
4208 /* Write function prelude. */
4210 printf ("int\n");
4211 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4212 kind);
4213 printf ("{\n");
4214 printf (" rtx insn;\n");
4215 printf ("\n");
4216 printf (" gcc_assert (slot < %d);\n", max_slots);
4217 printf ("\n");
4218 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4219 converts a compound instruction into a loop. */
4220 printf (" if (!INSN_P (candidate_insn))\n");
4221 printf (" return 0;\n");
4222 printf ("\n");
4224 /* If more than one delay type, find out which type the delay insn is. */
4226 if (num_delays > 1)
4228 attr = find_attr (&delay_type_str, 0);
4229 gcc_assert (attr);
4230 common_av = find_most_used (attr);
4232 printf (" insn = delay_insn;\n");
4233 printf (" switch (recog_memoized (insn))\n");
4234 printf (" {\n");
4236 sprintf (str, " * %d;\n break;", max_slots);
4237 for (av = attr->first_value; av; av = av->next)
4238 if (av != common_av)
4239 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4241 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4242 printf (" }\n\n");
4244 /* Ensure matched. Otherwise, shouldn't have been called. */
4245 printf (" gcc_assert (slot >= %d);\n\n", max_slots);
4248 /* If just one type of delay slot, write simple switch. */
4249 if (num_delays == 1 && max_slots == 1)
4251 printf (" insn = candidate_insn;\n");
4252 printf (" switch (recog_memoized (insn))\n");
4253 printf (" {\n");
4255 attr = find_attr (&delay_1_0_str, 0);
4256 gcc_assert (attr);
4257 common_av = find_most_used (attr);
4259 for (av = attr->first_value; av; av = av->next)
4260 if (av != common_av)
4261 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4263 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4264 printf (" }\n");
4267 else
4269 /* Write a nested CASE. The first indicates which condition we need to
4270 test, and the inner CASE tests the condition. */
4271 printf (" insn = candidate_insn;\n");
4272 printf (" switch (slot)\n");
4273 printf (" {\n");
4275 for (delay = delays; delay; delay = delay->next)
4276 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4278 printf (" case %d:\n",
4279 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4280 printf (" switch (recog_memoized (insn))\n");
4281 printf ("\t{\n");
4283 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
4284 pstr = str;
4285 attr = find_attr (&pstr, 0);
4286 gcc_assert (attr);
4287 common_av = find_most_used (attr);
4289 for (av = attr->first_value; av; av = av->next)
4290 if (av != common_av)
4291 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4293 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4294 printf (" }\n");
4297 printf (" default:\n");
4298 printf (" gcc_unreachable ();\n");
4299 printf (" }\n");
4302 printf ("}\n\n");
4305 /* This page contains miscellaneous utility routines. */
4307 /* Given a pointer to a (char *), return a malloc'ed string containing the
4308 next comma-separated element. Advance the pointer to after the string
4309 scanned, or the end-of-string. Return NULL if at end of string. */
4311 static char *
4312 next_comma_elt (const char **pstr)
4314 const char *start;
4316 start = scan_comma_elt (pstr);
4318 if (start == NULL)
4319 return NULL;
4321 return attr_string (start, *pstr - start);
4324 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4325 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4326 replaced by a pointer to a canonical copy of the string. */
4328 static struct attr_desc *
4329 find_attr (const char **name_p, int create)
4331 struct attr_desc *attr;
4332 int index;
4333 const char *name = *name_p;
4335 /* Before we resort to using `strcmp', see if the string address matches
4336 anywhere. In most cases, it should have been canonicalized to do so. */
4337 if (name == alternative_name)
4338 return NULL;
4340 index = name[0] & (MAX_ATTRS_INDEX - 1);
4341 for (attr = attrs[index]; attr; attr = attr->next)
4342 if (name == attr->name)
4343 return attr;
4345 /* Otherwise, do it the slow way. */
4346 for (attr = attrs[index]; attr; attr = attr->next)
4347 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
4349 *name_p = attr->name;
4350 return attr;
4353 if (! create)
4354 return NULL;
4356 attr = oballoc (struct attr_desc);
4357 attr->name = DEF_ATTR_STRING (name);
4358 attr->enum_name = 0;
4359 attr->first_value = attr->default_val = NULL;
4360 attr->is_numeric = attr->is_const = attr->is_special = 0;
4361 attr->next = attrs[index];
4362 attrs[index] = attr;
4364 *name_p = attr->name;
4366 return attr;
4369 /* Create internal attribute with the given default value. */
4371 static void
4372 make_internal_attr (const char *name, rtx value, int special)
4374 struct attr_desc *attr;
4376 attr = find_attr (&name, 1);
4377 gcc_assert (!attr->default_val);
4379 attr->is_numeric = 1;
4380 attr->is_const = 0;
4381 attr->is_special = (special & ATTR_SPECIAL) != 0;
4382 attr->default_val = get_attr_value (value, attr, -2);
4385 /* Find the most used value of an attribute. */
4387 static struct attr_value *
4388 find_most_used (struct attr_desc *attr)
4390 struct attr_value *av;
4391 struct attr_value *most_used;
4392 int nuses;
4394 most_used = NULL;
4395 nuses = -1;
4397 for (av = attr->first_value; av; av = av->next)
4398 if (av->num_insns > nuses)
4399 nuses = av->num_insns, most_used = av;
4401 return most_used;
4404 /* Return (attr_value "n") */
4406 static rtx
4407 make_numeric_value (int n)
4409 static rtx int_values[20];
4410 rtx exp;
4411 char *p;
4413 gcc_assert (n >= 0);
4415 if (n < 20 && int_values[n])
4416 return int_values[n];
4418 p = attr_printf (MAX_DIGITS, "%d", n);
4419 exp = attr_rtx (CONST_STRING, p);
4421 if (n < 20)
4422 int_values[n] = exp;
4424 return exp;
4427 static rtx
4428 copy_rtx_unchanging (rtx orig)
4430 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
4431 return orig;
4433 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
4434 return orig;
4437 /* Determine if an insn has a constant number of delay slots, i.e., the
4438 number of delay slots is not a function of the length of the insn. */
4440 static void
4441 write_const_num_delay_slots (void)
4443 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
4444 struct attr_value *av;
4446 if (attr)
4448 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4449 printf ("{\n");
4450 printf (" switch (recog_memoized (insn))\n");
4451 printf (" {\n");
4453 for (av = attr->first_value; av; av = av->next)
4455 length_used = 0;
4456 walk_attr_value (av->value);
4457 if (length_used)
4458 write_insn_cases (av->first_insn, 4);
4461 printf (" default:\n");
4462 printf (" return 1;\n");
4463 printf (" }\n}\n\n");
4467 /* Synthetic attributes used by insn-automata.c and the scheduler.
4468 These are primarily concerned with (define_insn_reservation)
4469 patterns. */
4471 struct insn_reserv
4473 struct insn_reserv *next;
4475 const char *name;
4476 int default_latency;
4477 rtx condexp;
4479 /* Sequence number of this insn. */
4480 int insn_num;
4482 /* Whether a (define_bypass) construct names this insn in its
4483 output list. */
4484 bool bypassed;
4487 static struct insn_reserv *all_insn_reservs = 0;
4488 static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs;
4489 static size_t n_insn_reservs;
4491 /* Store information from a DEFINE_INSN_RESERVATION for future
4492 attribute generation. */
4493 static void
4494 gen_insn_reserv (rtx def)
4496 struct insn_reserv *decl = oballoc (struct insn_reserv);
4498 decl->name = DEF_ATTR_STRING (XSTR (def, 0));
4499 decl->default_latency = XINT (def, 1);
4500 decl->condexp = check_attr_test (XEXP (def, 2), 0, 0);
4501 decl->insn_num = n_insn_reservs;
4502 decl->bypassed = false;
4503 decl->next = 0;
4505 *last_insn_reserv_p = decl;
4506 last_insn_reserv_p = &decl->next;
4507 n_insn_reservs++;
4510 /* Store information from a DEFINE_BYPASS for future attribute
4511 generation. The only thing we care about is the list of output
4512 insns, which will later be used to tag reservation structures with
4513 a 'bypassed' bit. */
4515 struct bypass_list
4517 struct bypass_list *next;
4518 const char *insn;
4521 static struct bypass_list *all_bypasses;
4522 static size_t n_bypasses;
4524 static void
4525 gen_bypass_1 (const char *s, size_t len)
4527 struct bypass_list *b;
4529 if (len == 0)
4530 return;
4532 s = attr_string (s, len);
4533 for (b = all_bypasses; b; b = b->next)
4534 if (s == b->insn)
4535 return; /* already got that one */
4537 b = oballoc (struct bypass_list);
4538 b->insn = s;
4539 b->next = all_bypasses;
4540 all_bypasses = b;
4541 n_bypasses++;
4544 static void
4545 gen_bypass (rtx def)
4547 const char *p, *base;
4549 for (p = base = XSTR (def, 1); *p; p++)
4550 if (*p == ',')
4552 gen_bypass_1 (base, p - base);
4554 p++;
4555 while (ISSPACE (*p));
4556 base = p;
4558 gen_bypass_1 (base, p - base);
4561 /* Find and mark all of the bypassed insns. */
4562 static void
4563 process_bypasses (void)
4565 struct bypass_list *b;
4566 struct insn_reserv *r;
4568 /* The reservation list is likely to be much longer than the bypass
4569 list. */
4570 for (r = all_insn_reservs; r; r = r->next)
4571 for (b = all_bypasses; b; b = b->next)
4572 if (r->name == b->insn)
4573 r->bypassed = true;
4576 /* Check that attribute NAME is used in define_insn_reservation condition
4577 EXP. Return true if it is. */
4578 static bool
4579 check_tune_attr (const char *name, rtx exp)
4581 switch (GET_CODE (exp))
4583 case AND:
4584 if (check_tune_attr (name, XEXP (exp, 0)))
4585 return true;
4586 return check_tune_attr (name, XEXP (exp, 1));
4588 case IOR:
4589 return (check_tune_attr (name, XEXP (exp, 0))
4590 && check_tune_attr (name, XEXP (exp, 1)));
4592 case EQ_ATTR:
4593 return XSTR (exp, 0) == name;
4595 default:
4596 return false;
4600 /* Try to find a const attribute (usually cpu or tune) that is used
4601 in all define_insn_reservation conditions. */
4602 static struct attr_desc *
4603 find_tune_attr (rtx exp)
4605 struct attr_desc *attr;
4607 switch (GET_CODE (exp))
4609 case AND:
4610 case IOR:
4611 attr = find_tune_attr (XEXP (exp, 0));
4612 if (attr)
4613 return attr;
4614 return find_tune_attr (XEXP (exp, 1));
4616 case EQ_ATTR:
4617 if (XSTR (exp, 0) == alternative_name)
4618 return NULL;
4620 attr = find_attr (&XSTR (exp, 0), 0);
4621 gcc_assert (attr);
4623 if (attr->is_const && !attr->is_special)
4625 struct insn_reserv *decl;
4627 for (decl = all_insn_reservs; decl; decl = decl->next)
4628 if (! check_tune_attr (attr->name, decl->condexp))
4629 return NULL;
4630 return attr;
4632 return NULL;
4634 default:
4635 return NULL;
4639 /* Create all of the attributes that describe automaton properties. */
4640 static void
4641 make_automaton_attrs (void)
4643 int i;
4644 struct insn_reserv *decl;
4645 rtx code_exp, lats_exp, byps_exp;
4646 struct attr_desc *tune_attr;
4648 if (n_insn_reservs == 0)
4649 return;
4651 tune_attr = find_tune_attr (all_insn_reservs->condexp);
4652 if (tune_attr != NULL)
4654 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3);
4655 struct attr_value *val;
4656 bool first = true;
4658 gcc_assert (tune_attr->is_const
4659 && !tune_attr->is_special
4660 && !tune_attr->is_numeric);
4661 for (val = tune_attr->first_value; val; val = val->next)
4663 if (val == tune_attr->default_val)
4664 continue;
4665 gcc_assert (GET_CODE (val->value) == CONST_STRING);
4666 printf ("static int internal_dfa_insn_code_%s (rtx);\n"
4667 "static int insn_default_latency_%s (rtx);\n",
4668 XSTR (val->value, 0), XSTR (val->value, 0));
4671 printf ("\n");
4672 printf ("int (*internal_dfa_insn_code) (rtx);\n");
4673 printf ("int (*insn_default_latency) (rtx);\n");
4674 printf ("\n");
4675 printf ("void\n");
4676 printf ("init_sched_attrs (void)\n");
4677 printf ("{\n");
4679 for (val = tune_attr->first_value; val; val = val->next)
4681 int j;
4682 char *name;
4683 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0));
4685 if (val == tune_attr->default_val)
4686 continue;
4687 for (decl = all_insn_reservs, i = 0;
4688 decl;
4689 decl = decl->next)
4691 rtx ctest = test;
4692 rtx condexp
4693 = simplify_and_tree (decl->condexp, &ctest, -2, 0);
4694 if (condexp == false_rtx)
4695 continue;
4696 if (condexp == true_rtx)
4697 break;
4698 condexps[i] = condexp;
4699 condexps[i + 1] = make_numeric_value (decl->insn_num);
4700 condexps[i + 2] = make_numeric_value (decl->default_latency);
4701 i += 3;
4704 code_exp = rtx_alloc (COND);
4705 lats_exp = rtx_alloc (COND);
4707 j = i / 3 * 2;
4708 XVEC (code_exp, 0) = rtvec_alloc (j);
4709 XVEC (lats_exp, 0) = rtvec_alloc (j);
4711 if (decl)
4713 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num);
4714 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency);
4716 else
4718 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
4719 XEXP (lats_exp, 1) = make_numeric_value (0);
4722 while (i > 0)
4724 i -= 3;
4725 j -= 2;
4726 XVECEXP (code_exp, 0, j) = condexps[i];
4727 XVECEXP (lats_exp, 0, j) = condexps[i];
4729 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1];
4730 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2];
4733 name = XNEWVEC (char,
4734 sizeof ("*internal_dfa_insn_code_")
4735 + strlen (XSTR (val->value, 0)));
4736 strcpy (name, "*internal_dfa_insn_code_");
4737 strcat (name, XSTR (val->value, 0));
4738 make_internal_attr (name, code_exp, ATTR_NONE);
4739 strcpy (name, "*insn_default_latency_");
4740 strcat (name, XSTR (val->value, 0));
4741 make_internal_attr (name, lats_exp, ATTR_NONE);
4742 XDELETEVEC (name);
4744 if (first)
4746 printf (" if (");
4747 first = false;
4749 else
4750 printf (" else if (");
4751 write_test_expr (test, 0, 0);
4752 printf (")\n");
4753 printf (" {\n");
4754 printf (" internal_dfa_insn_code\n");
4755 printf (" = internal_dfa_insn_code_%s;\n",
4756 XSTR (val->value, 0));
4757 printf (" insn_default_latency\n");
4758 printf (" = insn_default_latency_%s;\n",
4759 XSTR (val->value, 0));
4760 printf (" }\n");
4763 printf (" else\n");
4764 printf (" gcc_unreachable ();\n");
4765 printf ("}\n");
4766 printf ("\n");
4768 XDELETEVEC (condexps);
4770 else
4772 code_exp = rtx_alloc (COND);
4773 lats_exp = rtx_alloc (COND);
4775 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
4776 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2);
4778 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1);
4779 XEXP (lats_exp, 1) = make_numeric_value (0);
4781 for (decl = all_insn_reservs, i = 0;
4782 decl;
4783 decl = decl->next, i += 2)
4785 XVECEXP (code_exp, 0, i) = decl->condexp;
4786 XVECEXP (lats_exp, 0, i) = decl->condexp;
4788 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num);
4789 XVECEXP (lats_exp, 0, i+1)
4790 = make_numeric_value (decl->default_latency);
4792 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE);
4793 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE);
4796 if (n_bypasses == 0)
4797 byps_exp = make_numeric_value (0);
4798 else
4800 process_bypasses ();
4802 byps_exp = rtx_alloc (COND);
4803 XVEC (byps_exp, 0) = rtvec_alloc (n_bypasses * 2);
4804 XEXP (byps_exp, 1) = make_numeric_value (0);
4805 for (decl = all_insn_reservs, i = 0;
4806 decl;
4807 decl = decl->next)
4808 if (decl->bypassed)
4810 XVECEXP (byps_exp, 0, i) = decl->condexp;
4811 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1);
4812 i += 2;
4816 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE);
4820 main (int argc, char **argv)
4822 rtx desc;
4823 struct attr_desc *attr;
4824 struct insn_def *id;
4825 rtx tem;
4826 int i;
4828 progname = "genattrtab";
4830 if (!init_rtx_reader_args (argc, argv))
4831 return (FATAL_EXIT_CODE);
4833 obstack_init (hash_obstack);
4834 obstack_init (temp_obstack);
4836 /* Set up true and false rtx's */
4837 true_rtx = rtx_alloc (CONST_INT);
4838 XWINT (true_rtx, 0) = 1;
4839 false_rtx = rtx_alloc (CONST_INT);
4840 XWINT (false_rtx, 0) = 0;
4841 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4842 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
4844 alternative_name = DEF_ATTR_STRING ("alternative");
4845 length_str = DEF_ATTR_STRING ("length");
4846 delay_type_str = DEF_ATTR_STRING ("*delay_type");
4847 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4848 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
4850 printf ("/* Generated automatically by the program `genattrtab'\n\
4851 from the machine description file `md'. */\n\n");
4853 /* Read the machine description. */
4855 while (1)
4857 int lineno;
4859 desc = read_md_rtx (&lineno, &insn_code_number);
4860 if (desc == NULL)
4861 break;
4863 switch (GET_CODE (desc))
4865 case DEFINE_INSN:
4866 case DEFINE_PEEPHOLE:
4867 case DEFINE_ASM_ATTRIBUTES:
4868 gen_insn (desc, lineno);
4869 break;
4871 case DEFINE_ATTR:
4872 case DEFINE_ENUM_ATTR:
4873 gen_attr (desc, lineno);
4874 break;
4876 case DEFINE_DELAY:
4877 gen_delay (desc, lineno);
4878 break;
4880 case DEFINE_INSN_RESERVATION:
4881 gen_insn_reserv (desc);
4882 break;
4884 case DEFINE_BYPASS:
4885 gen_bypass (desc);
4886 break;
4888 default:
4889 break;
4891 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
4892 insn_index_number++;
4895 if (have_error)
4896 return FATAL_EXIT_CODE;
4898 insn_code_number++;
4900 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4901 if (! got_define_asm_attributes)
4903 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4904 XVEC (tem, 0) = rtvec_alloc (0);
4905 gen_insn (tem, 0);
4908 /* Expand DEFINE_DELAY information into new attribute. */
4909 if (num_delays)
4910 expand_delays ();
4912 printf ("#include \"config.h\"\n");
4913 printf ("#include \"system.h\"\n");
4914 printf ("#include \"coretypes.h\"\n");
4915 printf ("#include \"tm.h\"\n");
4916 printf ("#include \"rtl.h\"\n");
4917 printf ("#include \"insn-attr.h\"\n");
4918 printf ("#include \"tm_p.h\"\n");
4919 printf ("#include \"insn-config.h\"\n");
4920 printf ("#include \"recog.h\"\n");
4921 printf ("#include \"regs.h\"\n");
4922 printf ("#include \"output.h\"\n");
4923 printf ("#include \"diagnostic-core.h\"\n");
4924 printf ("#include \"flags.h\"\n");
4925 printf ("#include \"function.h\"\n");
4926 printf ("\n");
4927 printf ("#define operands recog_data.operand\n\n");
4929 /* Make `insn_alternatives'. */
4930 insn_alternatives = oballocvec (int, insn_code_number);
4931 for (id = defs; id; id = id->next)
4932 if (id->insn_code >= 0)
4933 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4935 /* Make `insn_n_alternatives'. */
4936 insn_n_alternatives = oballocvec (int, insn_code_number);
4937 for (id = defs; id; id = id->next)
4938 if (id->insn_code >= 0)
4939 insn_n_alternatives[id->insn_code] = id->num_alternatives;
4941 /* Construct extra attributes for automata. */
4942 make_automaton_attrs ();
4944 /* Prepare to write out attribute subroutines by checking everything stored
4945 away and building the attribute cases. */
4947 check_defs ();
4949 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4950 for (attr = attrs[i]; attr; attr = attr->next)
4951 attr->default_val->value
4952 = check_attr_value (attr->default_val->value, attr);
4954 if (have_error)
4955 return FATAL_EXIT_CODE;
4957 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4958 for (attr = attrs[i]; attr; attr = attr->next)
4959 fill_attr (attr);
4961 /* Construct extra attributes for `length'. */
4962 make_length_attrs ();
4964 /* Perform any possible optimizations to speed up compilation. */
4965 optimize_attrs ();
4967 /* Now write out all the `gen_attr_...' routines. Do these before the
4968 special routines so that they get defined before they are used. */
4970 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4971 for (attr = attrs[i]; attr; attr = attr->next)
4973 if (! attr->is_special && ! attr->is_const)
4974 write_attr_get (attr);
4977 /* Write out delay eligibility information, if DEFINE_DELAY present.
4978 (The function to compute the number of delay slots will be written
4979 below.) */
4980 if (num_delays)
4982 write_eligible_delay ("delay");
4983 if (have_annul_true)
4984 write_eligible_delay ("annul_true");
4985 if (have_annul_false)
4986 write_eligible_delay ("annul_false");
4989 /* Write out constant delay slot info. */
4990 write_const_num_delay_slots ();
4992 write_length_unit_log ();
4994 fflush (stdout);
4995 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);