]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genattrtab.c
* primary.c (match_hollerith_constant): Fix typo.
[thirdparty/gcc.git] / gcc / genattrtab.c
CommitLineData
41299f41 1/* Generate code from machine description to compute values of attributes.
d050d723 2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
25f99665 3 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
9e1b6503 4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
41299f41 5
1322177d 6This file is part of GCC.
41299f41 7
1322177d
LB
8GCC is free software; you can redistribute it and/or modify it under
9the terms of the GNU General Public License as published by the Free
10Software Foundation; either version 2, or (at your option) any later
11version.
41299f41 12
1322177d
LB
13GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14WARRANTY; without even the implied warranty of MERCHANTABILITY or
15FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16for more details.
41299f41
TW
17
18You should have received a copy of the GNU General Public License
1322177d 19along with GCC; see the file COPYING. If not, write to the Free
366ccddb
KC
20Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2102110-1301, USA. */
41299f41 22
6dc42e49 23/* This program handles insn attributes and the DEFINE_DELAY and
fa0aee89 24 DEFINE_INSN_RESERVATION definitions.
41299f41 25
3e7b5313 26 It produces a series of functions named `get_attr_...', one for each insn
41299f41
TW
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
29
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).
35
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
0eadeb15 38 an operand is found, `extract_insn' is called.
41299f41 39
c9541287 40 The special attribute `length' is also recognized. For this operand,
41299f41
TW
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'.
48
3e7b5313
TW
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.
c9541287 55
41299f41 56 Internal attributes are defined to handle DEFINE_DELAY and
fa0aee89 57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
41299f41
TW
58
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.
62
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.
67
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.
72
fa0aee89
PB
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
41299f41
TW
75
76 Once optimization is complete, any required routines and definitions
3e7b5313
TW
77 will be written.
78
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
3715a518
RS
85 definitions (each would be accessed through a pointer).
86
87 We use the flags in an RTX as follows:
2adc7f12 88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
3715a518 89 independent of the insn code.
2adc7f12 90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
3715a518 91 for the insn code currently being processed (see optimize_attrs).
6de9cd9a 92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
0ad420fe 93 (see attr_rtx). */
3715a518 94
2adc7f12
JJ
95#define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96#define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
6de9cd9a 97#define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
2adc7f12 98
8653a1ed 99#if 0
75669493
ZD
100#define strcmp_check(S1, S2) ((S1) == (S2) \
101 ? 0 \
b2d59f6f 102 : (gcc_assert (strcmp ((S1), (S2))), 1))
75669493
ZD
103#else
104#define strcmp_check(S1, S2) ((S1) != (S2))
105#endif
106
4977bab6 107#include "bconfig.h"
0b93b64e 108#include "system.h"
4977bab6
ZW
109#include "coretypes.h"
110#include "tm.h"
41299f41 111#include "rtl.h"
a3770a81 112#include "ggc.h"
c88c0d42 113#include "gensupport.h"
41299f41 114
956d6950
JL
115#ifdef HAVE_SYS_RESOURCE_H
116# include <sys/resource.h>
f0cdf2b2
RK
117#endif
118
31f0534c
RS
119/* We must include obstack.h after <sys/time.h>, to avoid lossage with
120 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
121#include "obstack.h"
f8b6598e 122#include "errors.h"
31f0534c 123
fae15c93
VM
124#include "genattrtab.h"
125
3916d6d8 126static struct obstack obstack1, obstack2;
7339c88d 127struct obstack *hash_obstack = &obstack1;
81fd4c6e 128struct obstack *temp_obstack = &obstack2;
41299f41 129
0e9414fd
MM
130/* enough space to reserve for printing out ints */
131#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
132
41299f41
TW
133/* Define structures used to record attributes and values. */
134
135/* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
136 encountered, we store all the relevant information into a
137 `struct insn_def'. This is done to allow attribute definitions to occur
138 anywhere in the file. */
139
140struct insn_def
141{
0f41302f
MS
142 struct insn_def *next; /* Next insn in chain. */
143 rtx def; /* The DEFINE_... */
a4cad544
RH
144 int insn_code; /* Instruction number. */
145 int insn_index; /* Expression numer in file, for errors. */
146 int lineno; /* Line number. */
41299f41 147 int num_alternatives; /* Number of alternatives. */
0f41302f 148 int vec_idx; /* Index of attribute vector in `def'. */
41299f41
TW
149};
150
151/* Once everything has been read in, we store in each attribute value a list
152 of insn codes that have that value. Here is the structure used for the
153 list. */
154
155struct insn_ent
156{
a4cad544 157 struct insn_ent *next; /* Next in chain. */
1e9c8405 158 struct insn_def *def; /* Instruction definition. */
41299f41
TW
159};
160
161/* Each value of an attribute (either constant or computed) is assigned a
162 structure which is used as the listhead of the insns that have that
163 value. */
164
165struct attr_value
166{
167 rtx value; /* Value of attribute. */
168 struct attr_value *next; /* Next attribute value in chain. */
169 struct insn_ent *first_insn; /* First insn with this value. */
170 int num_insns; /* Number of insns with this value. */
171 int has_asm_insn; /* True if this value used for `asm' insns */
172};
173
174/* Structure for each attribute. */
175
176struct attr_desc
177{
0f41302f
MS
178 char *name; /* Name of attribute. */
179 struct attr_desc *next; /* Next attribute. */
11597bc9
KG
180 struct attr_value *first_value; /* First value of this attribute. */
181 struct attr_value *default_val; /* Default value for this attribute. */
182 int lineno : 24; /* Line number. */
6f6074ea 183 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
6f6074ea
MM
184 unsigned is_const : 1; /* Attribute value constant for each run. */
185 unsigned is_special : 1; /* Don't call `write_attr_set'. */
ec049fdb 186 unsigned static_p : 1; /* Make the output function static. */
41299f41
TW
187};
188
189/* Structure for each DEFINE_DELAY. */
190
191struct delay_desc
192{
193 rtx def; /* DEFINE_DELAY expression. */
0f41302f 194 struct delay_desc *next; /* Next DEFINE_DELAY. */
41299f41 195 int num; /* Number of DEFINE_DELAY, starting at 1. */
a4cad544 196 int lineno; /* Line number. */
41299f41
TW
197};
198
41299f41
TW
199/* Listheads of above structures. */
200
3715a518
RS
201/* This one is indexed by the first character of the attribute name. */
202#define MAX_ATTRS_INDEX 256
203static struct attr_desc *attrs[MAX_ATTRS_INDEX];
41299f41
TW
204static struct insn_def *defs;
205static struct delay_desc *delays;
f75d38a7 206
0f41302f 207/* Other variables. */
41299f41
TW
208
209static int insn_code_number;
210static int insn_index_number;
211static int got_define_asm_attributes;
212static int must_extract;
213static int must_constrain;
214static int address_used;
d7c665bf 215static int length_used;
41299f41
TW
216static int num_delays;
217static int have_annul_true, have_annul_false;
1c69865d 218static int num_insn_ents;
41299f41 219
fae15c93
VM
220int num_dfa_decls;
221
3715a518
RS
222/* Stores, for each insn code, the number of constraint alternatives. */
223
224static int *insn_n_alternatives;
225
41299f41
TW
226/* Stores, for each insn code, a bitmap that has bits on for each possible
227 alternative. */
228
229static int *insn_alternatives;
230
231/* Used to simplify expressions. */
232
233static rtx true_rtx, false_rtx;
234
235/* Used to reduce calls to `strcmp' */
236
b01896cc 237static const char *alternative_name;
75669493
ZD
238static const char *length_str;
239static const char *delay_type_str;
240static const char *delay_1_0_str;
241static const char *num_delay_slots_str;
41299f41 242
21ca87b8
MS
243/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
244 called. */
245
246int reload_completed = 0;
247
9ec36da5
JL
248/* Some machines test `optimize' in macros called from rtlanal.c, so we need
249 to define it here. */
250
c5afbb49
JL
251int optimize = 0;
252
41299f41
TW
253/* Simplify an expression. Only call the routine if there is something to
254 simplify. */
255#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
2adc7f12 256 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
41299f41 257 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
c9541287 258
75669493
ZD
259#define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
260
41299f41
TW
261/* These are referenced by rtlanal.c and hence need to be defined somewhere.
262 They won't actually be used. */
263
5da077de 264rtx global_rtl[GR_MAX];
e5e809f4 265rtx pic_offset_table_rtx;
41299f41 266
16610927
AJ
267static void attr_hash_add_rtx (int, rtx);
268static void attr_hash_add_string (int, char *);
269static rtx attr_rtx (enum rtx_code, ...);
270static rtx attr_rtx_1 (enum rtx_code, va_list);
271static char *attr_string (const char *, int);
272static rtx check_attr_value (rtx, struct attr_desc *);
273static rtx convert_set_attr_alternative (rtx, struct insn_def *);
274static rtx convert_set_attr (rtx, struct insn_def *);
275static void check_defs (void);
276static rtx make_canonical (struct attr_desc *, rtx);
277static struct attr_value *get_attr_value (rtx, struct attr_desc *, int);
278static rtx copy_rtx_unchanging (rtx);
279static rtx copy_boolean (rtx);
280static void expand_delays (void);
16610927
AJ
281static void fill_attr (struct attr_desc *);
282static rtx substitute_address (rtx, rtx (*) (rtx), rtx (*) (rtx));
283static void make_length_attrs (void);
284static rtx identity_fn (rtx);
285static rtx zero_fn (rtx);
286static rtx one_fn (rtx);
287static rtx max_fn (rtx);
288static void write_length_unit_log (void);
289static rtx simplify_cond (rtx, int, int);
16610927 290static void clear_struct_flag (rtx);
16610927
AJ
291static void remove_insn_ent (struct attr_value *, struct insn_ent *);
292static void insert_insn_ent (struct attr_value *, struct insn_ent *);
293static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int);
294static rtx make_alternative_compare (int);
295static int compute_alternative_mask (rtx, enum rtx_code);
296static rtx evaluate_eq_attr (rtx, rtx, int, int);
297static rtx simplify_and_tree (rtx, rtx *, int, int);
298static rtx simplify_or_tree (rtx, rtx *, int, int);
299static rtx simplify_test_exp (rtx, int, int);
300static rtx simplify_test_exp_in_temp (rtx, int, int);
301static void optimize_attrs (void);
302static void gen_attr (rtx, int);
303static int count_alternatives (rtx);
304static int compares_alternatives_p (rtx);
305static int contained_in_p (rtx, rtx);
306static void gen_insn (rtx, int);
307static void gen_delay (rtx, int);
16610927
AJ
308static void write_test_expr (rtx, int);
309static int max_attr_value (rtx, int*);
310static int or_attr_value (rtx, int*);
311static void walk_attr_value (rtx);
312static void write_attr_get (struct attr_desc *);
313static rtx eliminate_known_true (rtx, rtx, int, int);
314static void write_attr_set (struct attr_desc *, int, rtx,
315 const char *, const char *, rtx,
316 int, int);
c1a404bd 317static void write_insn_cases (struct insn_ent *, int);
16610927
AJ
318static void write_attr_case (struct attr_desc *, struct attr_value *,
319 int, const char *, const char *, int, rtx);
16610927
AJ
320static void write_attr_valueq (struct attr_desc *, const char *);
321static void write_attr_value (struct attr_desc *, rtx);
322static void write_upcase (const char *);
323static void write_indent (int);
324static void write_eligible_delay (const char *);
16610927 325static int write_expr_attr_cache (rtx, struct attr_desc *);
16610927
AJ
326static void write_const_num_delay_slots (void);
327static char *next_comma_elt (const char **);
75669493 328static struct attr_desc *find_attr (const char **, int);
16610927 329static struct attr_value *find_most_used (struct attr_desc *);
16610927
AJ
330static rtx attr_eq (const char *, const char *);
331static const char *attr_numeral (int);
332static int attr_equal_p (rtx, rtx);
333static rtx attr_copy_rtx (rtx);
334static int attr_rtx_cost (rtx);
8653a1ed
ZD
335static bool attr_alt_subset_p (rtx, rtx);
336static bool attr_alt_subset_of_compl_p (rtx, rtx);
337static rtx attr_alt_intersection (rtx, rtx);
338static rtx attr_alt_union (rtx, rtx);
339static rtx attr_alt_complement (rtx);
8653a1ed 340static rtx mk_attr_alt (int);
0e9414fd
MM
341
342#define oballoc(size) obstack_alloc (hash_obstack, size)
16610927 343
3e7b5313
TW
344/* Hash table for sharing RTL and strings. */
345
346/* Each hash table slot is a bucket containing a chain of these structures.
347 Strings are given negative hash codes; RTL expressions are given positive
348 hash codes. */
349
350struct attr_hash
351{
352 struct attr_hash *next; /* Next structure in the bucket. */
353 int hashcode; /* Hash code of this rtx or string. */
354 union
355 {
356 char *str; /* The string (negative hash codes) */
357 rtx rtl; /* or the RTL recorded here. */
358 } u;
359};
360
361/* Now here is the hash table. When recording an RTL, it is added to
362 the slot whose index is the hash code mod the table size. Note
363 that the hash table is used for several kinds of RTL (see attr_rtx)
364 and for strings. While all these live in the same table, they are
365 completely independent, and the hash code is computed differently
366 for each. */
367
368#define RTL_HASH_SIZE 4093
369struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
370
371/* Here is how primitive or already-shared RTL's hash
372 codes are made. */
2e0dd623 373#define RTL_HASH(RTL) ((long) (RTL) & 0777777)
3e7b5313
TW
374
375/* Add an entry to the hash table for RTL with hash code HASHCODE. */
376
377static void
16610927 378attr_hash_add_rtx (int hashcode, rtx rtl)
3e7b5313 379{
b3694847 380 struct attr_hash *h;
3e7b5313 381
703ad42b 382 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
3e7b5313
TW
383 h->hashcode = hashcode;
384 h->u.rtl = rtl;
385 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
386 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
387}
388
389/* Add an entry to the hash table for STRING with hash code HASHCODE. */
390
391static void
16610927 392attr_hash_add_string (int hashcode, char *str)
3e7b5313 393{
b3694847 394 struct attr_hash *h;
3e7b5313 395
703ad42b 396 h = obstack_alloc (hash_obstack, sizeof (struct attr_hash));
3e7b5313
TW
397 h->hashcode = -hashcode;
398 h->u.str = str;
399 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
400 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
401}
402
81fd4c6e 403/* Generate an RTL expression, but avoid duplicates.
2adc7f12 404 Set the ATTR_PERMANENT_P flag for these permanent objects.
81fd4c6e
RS
405
406 In some cases we cannot uniquify; then we return an ordinary
2adc7f12 407 impermanent rtx with ATTR_PERMANENT_P clear.
81fd4c6e 408
a2a8cc44 409 Args are as follows:
3e7b5313
TW
410
411 rtx attr_rtx (code, [element1, ..., elementn]) */
412
3e7b5313 413static rtx
16610927 414attr_rtx_1 (enum rtx_code code, va_list p)
3e7b5313 415{
b3694847 416 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
3e7b5313 417 int hashcode;
b3694847 418 struct attr_hash *h;
7339c88d 419 struct obstack *old_obstack = rtl_obstack;
3e7b5313 420
3e7b5313
TW
421 /* For each of several cases, search the hash table for an existing entry.
422 Use that entry if one is found; otherwise create a new RTL and add it
423 to the table. */
424
ec8e098d 425 if (GET_RTX_CLASS (code) == RTX_UNARY)
3e7b5313
TW
426 {
427 rtx arg0 = va_arg (p, rtx);
428
81fd4c6e 429 /* A permanent object cannot point to impermanent ones. */
2adc7f12 430 if (! ATTR_PERMANENT_P (arg0))
81fd4c6e
RS
431 {
432 rt_val = rtx_alloc (code);
433 XEXP (rt_val, 0) = arg0;
81fd4c6e
RS
434 return rt_val;
435 }
436
d98c1e33 437 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
3e7b5313
TW
438 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
439 if (h->hashcode == hashcode
440 && GET_CODE (h->u.rtl) == code
441 && XEXP (h->u.rtl, 0) == arg0)
0d35f155 442 return h->u.rtl;
3e7b5313
TW
443
444 if (h == 0)
445 {
7339c88d 446 rtl_obstack = hash_obstack;
3e7b5313
TW
447 rt_val = rtx_alloc (code);
448 XEXP (rt_val, 0) = arg0;
449 }
450 }
ec8e098d
PB
451 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH
452 || GET_RTX_CLASS (code) == RTX_COMM_ARITH
453 || GET_RTX_CLASS (code) == RTX_COMPARE
454 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE)
3e7b5313
TW
455 {
456 rtx arg0 = va_arg (p, rtx);
457 rtx arg1 = va_arg (p, rtx);
458
81fd4c6e 459 /* A permanent object cannot point to impermanent ones. */
2adc7f12 460 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
81fd4c6e
RS
461 {
462 rt_val = rtx_alloc (code);
463 XEXP (rt_val, 0) = arg0;
464 XEXP (rt_val, 1) = arg1;
81fd4c6e
RS
465 return rt_val;
466 }
467
d98c1e33 468 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
3e7b5313
TW
469 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
470 if (h->hashcode == hashcode
471 && GET_CODE (h->u.rtl) == code
472 && XEXP (h->u.rtl, 0) == arg0
473 && XEXP (h->u.rtl, 1) == arg1)
0d35f155 474 return h->u.rtl;
3e7b5313
TW
475
476 if (h == 0)
477 {
7339c88d 478 rtl_obstack = hash_obstack;
3e7b5313
TW
479 rt_val = rtx_alloc (code);
480 XEXP (rt_val, 0) = arg0;
481 XEXP (rt_val, 1) = arg1;
482 }
483 }
484 else if (GET_RTX_LENGTH (code) == 1
485 && GET_RTX_FORMAT (code)[0] == 's')
486 {
770ae6cc 487 char *arg0 = va_arg (p, char *);
3e7b5313 488
75669493 489 arg0 = DEF_ATTR_STRING (arg0);
81fd4c6e 490
d98c1e33 491 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
3e7b5313
TW
492 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
493 if (h->hashcode == hashcode
494 && GET_CODE (h->u.rtl) == code
495 && XSTR (h->u.rtl, 0) == arg0)
0d35f155 496 return h->u.rtl;
3e7b5313
TW
497
498 if (h == 0)
499 {
7339c88d 500 rtl_obstack = hash_obstack;
3e7b5313
TW
501 rt_val = rtx_alloc (code);
502 XSTR (rt_val, 0) = arg0;
503 }
504 }
505 else if (GET_RTX_LENGTH (code) == 2
506 && GET_RTX_FORMAT (code)[0] == 's'
507 && GET_RTX_FORMAT (code)[1] == 's')
508 {
81fd4c6e
RS
509 char *arg0 = va_arg (p, char *);
510 char *arg1 = va_arg (p, char *);
3e7b5313 511
d98c1e33 512 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
3e7b5313
TW
513 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
514 if (h->hashcode == hashcode
515 && GET_CODE (h->u.rtl) == code
516 && XSTR (h->u.rtl, 0) == arg0
517 && XSTR (h->u.rtl, 1) == arg1)
0d35f155 518 return h->u.rtl;
3e7b5313
TW
519
520 if (h == 0)
521 {
7339c88d 522 rtl_obstack = hash_obstack;
3e7b5313
TW
523 rt_val = rtx_alloc (code);
524 XSTR (rt_val, 0) = arg0;
525 XSTR (rt_val, 1) = arg1;
526 }
527 }
81fd4c6e
RS
528 else if (code == CONST_INT)
529 {
3d678dca 530 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
81fd4c6e 531 if (arg0 == 0)
0d35f155
KG
532 return false_rtx;
533 else if (arg0 == 1)
534 return true_rtx;
535 else
536 goto nohash;
81fd4c6e 537 }
3e7b5313
TW
538 else
539 {
0d35f155
KG
540 int i; /* Array indices... */
541 const char *fmt; /* Current rtx's format... */
81fd4c6e 542 nohash:
3e7b5313 543 rt_val = rtx_alloc (code); /* Allocate the storage space. */
c9541287 544
3e7b5313
TW
545 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
546 for (i = 0; i < GET_RTX_LENGTH (code); i++)
547 {
548 switch (*fmt++)
549 {
550 case '0': /* Unused field. */
551 break;
552
553 case 'i': /* An integer? */
554 XINT (rt_val, i) = va_arg (p, int);
555 break;
556
3d678dca
RS
557 case 'w': /* A wide integer? */
558 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
559 break;
560
3e7b5313
TW
561 case 's': /* A string? */
562 XSTR (rt_val, i) = va_arg (p, char *);
563 break;
564
565 case 'e': /* An expression? */
566 case 'u': /* An insn? Same except when printing. */
567 XEXP (rt_val, i) = va_arg (p, rtx);
568 break;
569
570 case 'E': /* An RTX vector? */
571 XVEC (rt_val, i) = va_arg (p, rtvec);
572 break;
573
574 default:
b2d59f6f 575 gcc_unreachable ();
3e7b5313
TW
576 }
577 }
3e7b5313
TW
578 return rt_val;
579 }
580
7339c88d 581 rtl_obstack = old_obstack;
3e7b5313 582 attr_hash_add_rtx (hashcode, rt_val);
2adc7f12 583 ATTR_PERMANENT_P (rt_val) = 1;
3e7b5313 584 return rt_val;
0d35f155 585}
3e7b5313 586
0d35f155 587static rtx
e34d07f2 588attr_rtx (enum rtx_code code, ...)
0d35f155
KG
589{
590 rtx result;
e34d07f2 591 va_list p;
16610927 592
e34d07f2 593 va_start (p, code);
0d35f155 594 result = attr_rtx_1 (code, p);
e34d07f2 595 va_end (p);
0d35f155 596 return result;
3e7b5313
TW
597}
598
599/* Create a new string printed with the printf line arguments into a space
600 of at most LEN bytes:
601
602 rtx attr_printf (len, format, [arg1, ..., argn]) */
603
fae15c93 604char *
e34d07f2 605attr_printf (unsigned int len, const char *fmt, ...)
3e7b5313 606{
b548dffb 607 char str[256];
e34d07f2 608 va_list p;
16610927 609
e34d07f2 610 va_start (p, fmt);
16610927 611
b2d59f6f 612 gcc_assert (len < sizeof str); /* Leave room for \0. */
b548dffb 613
3e7b5313 614 vsprintf (str, fmt, p);
e34d07f2 615 va_end (p);
3e7b5313 616
75669493 617 return DEF_ATTR_STRING (str);
3e7b5313
TW
618}
619
69277eec 620static rtx
16610927 621attr_eq (const char *name, const char *value)
81fd4c6e 622{
75669493 623 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value));
81fd4c6e
RS
624}
625
3cce094d 626static const char *
16610927 627attr_numeral (int n)
81fd4c6e
RS
628{
629 return XSTR (make_numeric_value (n), 0);
630}
631
3e7b5313
TW
632/* Return a permanent (possibly shared) copy of a string STR (not assumed
633 to be null terminated) with LEN bytes. */
634
635static char *
16610927 636attr_string (const char *str, int len)
3e7b5313 637{
b3694847 638 struct attr_hash *h;
3e7b5313
TW
639 int hashcode;
640 int i;
b3694847 641 char *new_str;
3e7b5313
TW
642
643 /* Compute the hash code. */
c9541287 644 hashcode = (len + 1) * 613 + (unsigned) str[0];
3e7b5313 645 for (i = 1; i <= len; i += 2)
c9541287 646 hashcode = ((hashcode * 613) + (unsigned) str[i]);
3e7b5313
TW
647 if (hashcode < 0)
648 hashcode = -hashcode;
649
650 /* Search the table for the string. */
651 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
81fd4c6e 652 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
d45cf215 653 && !strncmp (h->u.str, str, len))
3e7b5313
TW
654 return h->u.str; /* <-- return if found. */
655
656 /* Not found; create a permanent copy and add it to the hash table. */
703ad42b 657 new_str = obstack_alloc (hash_obstack, len + 1);
4e135bdd 658 memcpy (new_str, str, len);
3e7b5313
TW
659 new_str[len] = '\0';
660 attr_hash_add_string (hashcode, new_str);
661
662 return new_str; /* Return the new string. */
663}
81fd4c6e
RS
664
665/* Check two rtx's for equality of contents,
666 taking advantage of the fact that if both are hashed
667 then they can't be equal unless they are the same object. */
668
69277eec 669static int
16610927 670attr_equal_p (rtx x, rtx y)
81fd4c6e 671{
2adc7f12 672 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
81fd4c6e
RS
673 && rtx_equal_p (x, y)));
674}
16610927 675
81fd4c6e
RS
676/* Copy an attribute value expression,
677 descending to all depths, but not copying any
678 permanent hashed subexpressions. */
679
69277eec 680static rtx
16610927 681attr_copy_rtx (rtx orig)
81fd4c6e 682{
b3694847
SS
683 rtx copy;
684 int i, j;
685 RTX_CODE code;
686 const char *format_ptr;
81fd4c6e
RS
687
688 /* No need to copy a permanent object. */
2adc7f12 689 if (ATTR_PERMANENT_P (orig))
81fd4c6e
RS
690 return orig;
691
692 code = GET_CODE (orig);
693
694 switch (code)
695 {
696 case REG:
81fd4c6e
RS
697 case CONST_INT:
698 case CONST_DOUBLE:
69ef87e2 699 case CONST_VECTOR:
81fd4c6e
RS
700 case SYMBOL_REF:
701 case CODE_LABEL:
702 case PC:
703 case CC0:
704 return orig;
e9a25f70
JL
705
706 default:
707 break;
81fd4c6e
RS
708 }
709
710 copy = rtx_alloc (code);
711 PUT_MODE (copy, GET_MODE (orig));
2adc7f12
JJ
712 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
713 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
714 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
c9541287 715
81fd4c6e
RS
716 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
717
718 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
719 {
720 switch (*format_ptr++)
721 {
722 case 'e':
723 XEXP (copy, i) = XEXP (orig, i);
724 if (XEXP (orig, i) != NULL)
725 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
726 break;
727
728 case 'E':
729 case 'V':
730 XVEC (copy, i) = XVEC (orig, i);
731 if (XVEC (orig, i) != NULL)
732 {
733 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
734 for (j = 0; j < XVECLEN (copy, i); j++)
735 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
736 }
737 break;
738
3d678dca
RS
739 case 'n':
740 case 'i':
81fd4c6e
RS
741 XINT (copy, i) = XINT (orig, i);
742 break;
3d678dca
RS
743
744 case 'w':
745 XWINT (copy, i) = XWINT (orig, i);
746 break;
747
748 case 's':
749 case 'S':
750 XSTR (copy, i) = XSTR (orig, i);
751 break;
752
753 default:
b2d59f6f 754 gcc_unreachable ();
81fd4c6e
RS
755 }
756 }
757 return copy;
758}
16610927 759
41299f41 760/* Given a test expression for an attribute, ensure it is validly formed.
3e7b5313
TW
761 IS_CONST indicates whether the expression is constant for each compiler
762 run (a constant expression may not test any particular insn).
763
41299f41
TW
764 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
765 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
766 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
767
768 Update the string address in EQ_ATTR expression to be the same used
769 in the attribute (or `alternative_name') to speed up subsequent
770 `find_attr' calls and eliminate most `strcmp' calls.
771
6d2f8887 772 Return the new expression, if any. */
41299f41 773
fae15c93 774rtx
16610927 775check_attr_test (rtx exp, int is_const, int lineno)
41299f41
TW
776{
777 struct attr_desc *attr;
778 struct attr_value *av;
3cce094d 779 const char *name_ptr, *p;
41299f41
TW
780 rtx orexp, newexp;
781
782 switch (GET_CODE (exp))
783 {
784 case EQ_ATTR:
785 /* Handle negation test. */
786 if (XSTR (exp, 1)[0] == '!')
3e7b5313 787 return check_attr_test (attr_rtx (NOT,
81fd4c6e
RS
788 attr_eq (XSTR (exp, 0),
789 &XSTR (exp, 1)[1])),
a4cad544 790 is_const, lineno);
41299f41
TW
791
792 else if (n_comma_elts (XSTR (exp, 1)) == 1)
793 {
75669493 794 attr = find_attr (&XSTR (exp, 0), 0);
41299f41
TW
795 if (attr == NULL)
796 {
797 if (! strcmp (XSTR (exp, 0), "alternative"))
8653a1ed 798 return mk_attr_alt (1 << atoi (XSTR (exp, 1)));
7339c88d 799 else
1f978f5f 800 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
41299f41
TW
801 }
802
3e7b5313 803 if (is_const && ! attr->is_const)
1f978f5f 804 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
487a6e06 805 XSTR (exp, 0));
3e7b5313 806
81fd4c6e
RS
807 /* Copy this just to make it permanent,
808 so expressions using it can be permanent too. */
809 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
41299f41 810
f72aed24 811 /* It shouldn't be possible to simplify the value given to a
b31a5831 812 constant attribute, so don't expand this until it's time to
c9541287 813 write the test expression. */
b31a5831 814 if (attr->is_const)
2adc7f12 815 ATTR_IND_SIMPLIFIED_P (exp) = 1;
b31a5831 816
41299f41
TW
817 if (attr->is_numeric)
818 {
819 for (p = XSTR (exp, 1); *p; p++)
0df6c2c7 820 if (! ISDIGIT (*p))
1f978f5f 821 fatal ("attribute `%s' takes only numeric values",
c9541287 822 XSTR (exp, 0));
41299f41
TW
823 }
824 else
825 {
826 for (av = attr->first_value; av; av = av->next)
827 if (GET_CODE (av->value) == CONST_STRING
828 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
829 break;
830
831 if (av == NULL)
1f978f5f 832 fatal ("unknown value `%s' for `%s' attribute",
487a6e06 833 XSTR (exp, 1), XSTR (exp, 0));
41299f41
TW
834 }
835 }
836 else
837 {
8653a1ed 838 if (! strcmp (XSTR (exp, 0), "alternative"))
41299f41 839 {
8653a1ed
ZD
840 int set = 0;
841
842 name_ptr = XSTR (exp, 1);
843 while ((p = next_comma_elt (&name_ptr)) != NULL)
844 set |= 1 << atoi (p);
845
846 return mk_attr_alt (set);
41299f41 847 }
8653a1ed
ZD
848 else
849 {
850 /* Make an IOR tree of the possible values. */
851 orexp = false_rtx;
852 name_ptr = XSTR (exp, 1);
853 while ((p = next_comma_elt (&name_ptr)) != NULL)
854 {
855 newexp = attr_eq (XSTR (exp, 0), p);
856 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
857 }
41299f41 858
8653a1ed
ZD
859 return check_attr_test (orexp, is_const, lineno);
860 }
41299f41
TW
861 }
862 break;
863
0b0316dc
JL
864 case ATTR_FLAG:
865 break;
866
41299f41
TW
867 case CONST_INT:
868 /* Either TRUE or FALSE. */
3d678dca 869 if (XWINT (exp, 0))
41299f41
TW
870 return true_rtx;
871 else
872 return false_rtx;
873
874 case IOR:
875 case AND:
a4cad544
RH
876 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
877 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
41299f41
TW
878 break;
879
880 case NOT:
a4cad544 881 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
41299f41
TW
882 break;
883
884 case MATCH_OPERAND:
3e7b5313
TW
885 if (is_const)
886 fatal ("RTL operator \"%s\" not valid in constant attribute test",
8450a694 887 GET_RTX_NAME (GET_CODE (exp)));
81fd4c6e 888 /* These cases can't be simplified. */
2adc7f12 889 ATTR_IND_SIMPLIFIED_P (exp) = 1;
81fd4c6e 890 break;
c9541287 891
41299f41
TW
892 case LE: case LT: case GT: case GE:
893 case LEU: case LTU: case GTU: case GEU:
894 case NE: case EQ:
81fd4c6e
RS
895 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
896 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
897 exp = attr_rtx (GET_CODE (exp),
898 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
899 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
41299f41 900 /* These cases can't be simplified. */
2adc7f12 901 ATTR_IND_SIMPLIFIED_P (exp) = 1;
41299f41
TW
902 break;
903
3e7b5313
TW
904 case SYMBOL_REF:
905 if (is_const)
906 {
907 /* These cases are valid for constant attributes, but can't be
908 simplified. */
81fd4c6e 909 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
2adc7f12 910 ATTR_IND_SIMPLIFIED_P (exp) = 1;
3e7b5313
TW
911 break;
912 }
41299f41
TW
913 default:
914 fatal ("RTL operator \"%s\" not valid in attribute test",
915 GET_RTX_NAME (GET_CODE (exp)));
916 }
917
918 return exp;
919}
16610927 920
41299f41
TW
921/* Given an expression, ensure that it is validly formed and that all named
922 attribute values are valid for the given attribute. Issue a fatal error
81fd4c6e 923 if not. If no attribute is specified, assume a numeric attribute.
41299f41 924
81fd4c6e
RS
925 Return a perhaps modified replacement expression for the value. */
926
927static rtx
16610927 928check_attr_value (rtx exp, struct attr_desc *attr)
41299f41
TW
929{
930 struct attr_value *av;
3cce094d 931 const char *p;
41299f41
TW
932 int i;
933
934 switch (GET_CODE (exp))
935 {
936 case CONST_INT:
937 if (attr && ! attr->is_numeric)
a4cad544
RH
938 {
939 message_with_line (attr->lineno,
940 "CONST_INT not valid for non-numeric attribute %s",
941 attr->name);
942 have_error = 1;
943 break;
944 }
41299f41 945
db77171d 946 if (INTVAL (exp) < 0)
a4cad544
RH
947 {
948 message_with_line (attr->lineno,
c9541287
KH
949 "negative numeric value specified for attribute %s",
950 attr->name);
a4cad544
RH
951 have_error = 1;
952 break;
953 }
41299f41
TW
954 break;
955
956 case CONST_STRING:
957 if (! strcmp (XSTR (exp, 0), "*"))
958 break;
959
960 if (attr == 0 || attr->is_numeric)
961 {
72f1215c 962 p = XSTR (exp, 0);
72f1215c 963 for (; *p; p++)
0df6c2c7 964 if (! ISDIGIT (*p))
a4cad544
RH
965 {
966 message_with_line (attr ? attr->lineno : 0,
967 "non-numeric value for numeric attribute %s",
968 attr ? attr->name : "internal");
969 have_error = 1;
970 break;
971 }
41299f41
TW
972 break;
973 }
974
975 for (av = attr->first_value; av; av = av->next)
976 if (GET_CODE (av->value) == CONST_STRING
977 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
978 break;
979
980 if (av == NULL)
a4cad544
RH
981 {
982 message_with_line (attr->lineno,
983 "unknown value `%s' for `%s' attribute",
984 XSTR (exp, 0), attr ? attr->name : "internal");
985 have_error = 1;
986 }
81fd4c6e 987 break;
41299f41
TW
988
989 case IF_THEN_ELSE:
3e7b5313 990 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
a4cad544
RH
991 attr ? attr->is_const : 0,
992 attr ? attr->lineno : 0);
81fd4c6e
RS
993 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
994 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
995 break;
41299f41 996
7ee37ba4
RH
997 case PLUS:
998 case MINUS:
999 case MULT:
1000 case DIV:
1001 case MOD:
1002 if (attr && !attr->is_numeric)
a4cad544
RH
1003 {
1004 message_with_line (attr->lineno,
c9541287
KH
1005 "invalid operation `%s' for non-numeric attribute value",
1006 GET_RTX_NAME (GET_CODE (exp)));
a4cad544
RH
1007 have_error = 1;
1008 break;
1009 }
5d3cc252 1010 /* Fall through. */
7ee37ba4 1011
71d9b493
RH
1012 case IOR:
1013 case AND:
1014 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1015 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1016 break;
1017
1018 case FFS:
2928cd7a
RH
1019 case CLZ:
1020 case CTZ:
1021 case POPCOUNT:
1022 case PARITY:
71d9b493
RH
1023 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1024 break;
1025
41299f41
TW
1026 case COND:
1027 if (XVECLEN (exp, 0) % 2 != 0)
a4cad544
RH
1028 {
1029 message_with_line (attr->lineno,
1030 "first operand of COND must have even length");
1031 have_error = 1;
1032 break;
1033 }
41299f41
TW
1034
1035 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1036 {
3e7b5313 1037 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
a4cad544
RH
1038 attr ? attr->is_const : 0,
1039 attr ? attr->lineno : 0);
81fd4c6e
RS
1040 XVECEXP (exp, 0, i + 1)
1041 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
41299f41
TW
1042 }
1043
81fd4c6e
RS
1044 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1045 break;
41299f41 1046
7ee37ba4
RH
1047 case ATTR:
1048 {
75669493 1049 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0);
7ee37ba4 1050 if (attr2 == NULL)
a4cad544
RH
1051 {
1052 message_with_line (attr ? attr->lineno : 0,
1053 "unknown attribute `%s' in ATTR",
1054 XSTR (exp, 0));
1055 have_error = 1;
1056 }
1057 else if (attr && attr->is_const && ! attr2->is_const)
1058 {
1059 message_with_line (attr->lineno,
1060 "non-constant attribute `%s' referenced from `%s'",
1061 XSTR (exp, 0), attr->name);
1062 have_error = 1;
1063 }
c9541287 1064 else if (attr
db77171d 1065 && attr->is_numeric != attr2->is_numeric)
a4cad544
RH
1066 {
1067 message_with_line (attr->lineno,
1068 "numeric attribute mismatch calling `%s' from `%s'",
1069 XSTR (exp, 0), attr->name);
1070 have_error = 1;
1071 }
7ee37ba4
RH
1072 }
1073 break;
1074
3e7b5313 1075 case SYMBOL_REF:
7ee37ba4
RH
1076 /* A constant SYMBOL_REF is valid as a constant attribute test and
1077 is expanded later by make_canonical into a COND. In a non-constant
1078 attribute test, it is left be. */
1079 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
3e7b5313 1080
41299f41 1081 default:
a4cad544
RH
1082 message_with_line (attr ? attr->lineno : 0,
1083 "invalid operation `%s' for attribute value",
1084 GET_RTX_NAME (GET_CODE (exp)));
1085 have_error = 1;
1086 break;
41299f41 1087 }
81fd4c6e
RS
1088
1089 return exp;
41299f41 1090}
16610927 1091
41299f41 1092/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
b01896cc 1093 It becomes a COND with each test being (eq_attr "alternative" "n") */
41299f41
TW
1094
1095static rtx
16610927 1096convert_set_attr_alternative (rtx exp, struct insn_def *id)
41299f41 1097{
a4cad544 1098 int num_alt = id->num_alternatives;
41299f41
TW
1099 rtx condexp;
1100 int i;
1101
1102 if (XVECLEN (exp, 1) != num_alt)
a4cad544
RH
1103 {
1104 message_with_line (id->lineno,
c9541287 1105 "bad number of entries in SET_ATTR_ALTERNATIVE");
a4cad544
RH
1106 have_error = 1;
1107 return NULL_RTX;
1108 }
41299f41
TW
1109
1110 /* Make a COND with all tests but the last. Select the last value via the
1111 default. */
1112 condexp = rtx_alloc (COND);
1113 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1114
1115 for (i = 0; i < num_alt - 1; i++)
1116 {
3cce094d 1117 const char *p;
81fd4c6e 1118 p = attr_numeral (i);
3e7b5313 1119
81fd4c6e 1120 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
41299f41
TW
1121 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1122 }
1123
1124 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1125
3e7b5313 1126 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
41299f41 1127}
16610927 1128
41299f41
TW
1129/* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1130 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1131
1132static rtx
16610927 1133convert_set_attr (rtx exp, struct insn_def *id)
41299f41
TW
1134{
1135 rtx newexp;
3cce094d 1136 const char *name_ptr;
41299f41
TW
1137 char *p;
1138 int n;
1139
1140 /* See how many alternative specified. */
1141 n = n_comma_elts (XSTR (exp, 1));
1142 if (n == 1)
3e7b5313
TW
1143 return attr_rtx (SET,
1144 attr_rtx (ATTR, XSTR (exp, 0)),
1145 attr_rtx (CONST_STRING, XSTR (exp, 1)));
41299f41
TW
1146
1147 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1148 XSTR (newexp, 0) = XSTR (exp, 0);
1149 XVEC (newexp, 1) = rtvec_alloc (n);
1150
1151 /* Process each comma-separated name. */
1152 name_ptr = XSTR (exp, 1);
1153 n = 0;
1154 while ((p = next_comma_elt (&name_ptr)) != NULL)
3e7b5313 1155 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
41299f41 1156
a4cad544 1157 return convert_set_attr_alternative (newexp, id);
41299f41 1158}
16610927 1159
41299f41
TW
1160/* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1161 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
0f41302f 1162 expressions. */
41299f41
TW
1163
1164static void
16610927 1165check_defs (void)
41299f41
TW
1166{
1167 struct insn_def *id;
1168 struct attr_desc *attr;
1169 int i;
1170 rtx value;
1171
1172 for (id = defs; id; id = id->next)
1173 {
1174 if (XVEC (id->def, id->vec_idx) == NULL)
1175 continue;
1176
1177 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1178 {
1179 value = XVECEXP (id->def, id->vec_idx, i);
1180 switch (GET_CODE (value))
1181 {
1182 case SET:
1183 if (GET_CODE (XEXP (value, 0)) != ATTR)
a4cad544
RH
1184 {
1185 message_with_line (id->lineno, "bad attribute set");
1186 have_error = 1;
1187 value = NULL_RTX;
1188 }
41299f41
TW
1189 break;
1190
1191 case SET_ATTR_ALTERNATIVE:
a4cad544 1192 value = convert_set_attr_alternative (value, id);
41299f41
TW
1193 break;
1194
1195 case SET_ATTR:
a4cad544 1196 value = convert_set_attr (value, id);
41299f41
TW
1197 break;
1198
1199 default:
a4cad544
RH
1200 message_with_line (id->lineno, "invalid attribute code %s",
1201 GET_RTX_NAME (GET_CODE (value)));
1202 have_error = 1;
1203 value = NULL_RTX;
41299f41 1204 }
a4cad544
RH
1205 if (value == NULL_RTX)
1206 continue;
41299f41 1207
75669493 1208 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL)
a4cad544
RH
1209 {
1210 message_with_line (id->lineno, "unknown attribute %s",
1211 XSTR (XEXP (value, 0), 0));
1212 have_error = 1;
1213 continue;
1214 }
41299f41
TW
1215
1216 XVECEXP (id->def, id->vec_idx, i) = value;
81fd4c6e 1217 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
41299f41
TW
1218 }
1219 }
1220}
3e7b5313 1221
41299f41
TW
1222/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1223 expressions by converting them into a COND. This removes cases from this
1224 program. Also, replace an attribute value of "*" with the default attribute
1225 value. */
1226
1227static rtx
16610927 1228make_canonical (struct attr_desc *attr, rtx exp)
41299f41
TW
1229{
1230 int i;
1231 rtx newexp;
1232
1233 switch (GET_CODE (exp))
1234 {
1235 case CONST_INT:
1236 exp = make_numeric_value (INTVAL (exp));
1237 break;
1238
1239 case CONST_STRING:
1240 if (! strcmp (XSTR (exp, 0), "*"))
1241 {
1242 if (attr == 0 || attr->default_val == 0)
357351e5 1243 fatal ("(attr_value \"*\") used in invalid context");
41299f41
TW
1244 exp = attr->default_val->value;
1245 }
75669493
ZD
1246 else
1247 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
41299f41
TW
1248
1249 break;
1250
3e7b5313 1251 case SYMBOL_REF:
2adc7f12 1252 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
3e7b5313 1253 break;
3715a518
RS
1254 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1255 This makes the COND something that won't be considered an arbitrary
1256 expression by walk_attr_value. */
2adc7f12 1257 ATTR_IND_SIMPLIFIED_P (exp) = 1;
71d9b493
RH
1258 exp = check_attr_value (exp, attr);
1259 break;
3e7b5313 1260
41299f41
TW
1261 case IF_THEN_ELSE:
1262 newexp = rtx_alloc (COND);
1263 XVEC (newexp, 0) = rtvec_alloc (2);
1264 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1265 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1266
1267 XEXP (newexp, 1) = XEXP (exp, 2);
1268
1269 exp = newexp;
1270 /* Fall through to COND case since this is now a COND. */
1271
1272 case COND:
7339c88d
RS
1273 {
1274 int allsame = 1;
1275 rtx defval;
41299f41 1276
0f41302f 1277 /* First, check for degenerate COND. */
7339c88d
RS
1278 if (XVECLEN (exp, 0) == 0)
1279 return make_canonical (attr, XEXP (exp, 1));
1280 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
41299f41 1281
7339c88d
RS
1282 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1283 {
81fd4c6e 1284 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
7339c88d
RS
1285 XVECEXP (exp, 0, i + 1)
1286 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1287 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1288 allsame = 0;
1289 }
1290 if (allsame)
1291 return defval;
7339c88d 1292 }
e9a25f70
JL
1293 break;
1294
1295 default:
1296 break;
41299f41
TW
1297 }
1298
1299 return exp;
1300}
81fd4c6e
RS
1301
1302static rtx
16610927 1303copy_boolean (rtx exp)
81fd4c6e
RS
1304{
1305 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1306 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1307 copy_boolean (XEXP (exp, 1)));
75669493
ZD
1308 if (GET_CODE (exp) == MATCH_OPERAND)
1309 {
1310 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1311 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2));
1312 }
1313 else if (GET_CODE (exp) == EQ_ATTR)
1314 {
1315 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0));
1316 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1));
1317 }
1318
81fd4c6e
RS
1319 return exp;
1320}
16610927 1321
41299f41
TW
1322/* Given a value and an attribute description, return a `struct attr_value *'
1323 that represents that value. This is either an existing structure, if the
1324 value has been previously encountered, or a newly-created structure.
1325
1326 `insn_code' is the code of an insn whose attribute has the specified
1327 value (-2 if not processing an insn). We ensure that all insns for
1328 a given value have the same number of alternatives if the value checks
1329 alternatives. */
1330
1331static struct attr_value *
16610927 1332get_attr_value (rtx value, struct attr_desc *attr, int insn_code)
41299f41
TW
1333{
1334 struct attr_value *av;
1335 int num_alt = 0;
1336
1337 value = make_canonical (attr, value);
1338 if (compares_alternatives_p (value))
1339 {
1340 if (insn_code < 0 || insn_alternatives == NULL)
1341 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1342 else
1343 num_alt = insn_alternatives[insn_code];
1344 }
1345
1346 for (av = attr->first_value; av; av = av->next)
1347 if (rtx_equal_p (value, av->value)
1348 && (num_alt == 0 || av->first_insn == NULL
1e9c8405 1349 || insn_alternatives[av->first_insn->def->insn_code]))
41299f41
TW
1350 return av;
1351
703ad42b 1352 av = oballoc (sizeof (struct attr_value));
41299f41
TW
1353 av->value = value;
1354 av->next = attr->first_value;
1355 attr->first_value = av;
1356 av->first_insn = NULL;
1357 av->num_insns = 0;
1358 av->has_asm_insn = 0;
1359
1360 return av;
1361}
16610927 1362
41299f41
TW
1363/* After all DEFINE_DELAYs have been read in, create internal attributes
1364 to generate the required routines.
1365
1366 First, we compute the number of delay slots for each insn (as a COND of
1367 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1368 delay type is specified, we compute a similar function giving the
1369 DEFINE_DELAY ordinal for each insn.
1370
1371 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1372 tells whether a given insn can be in that delay slot.
1373
6dc42e49 1374 Normal attribute filling and optimization expands these to contain the
41299f41
TW
1375 information needed to handle delay slots. */
1376
1377static void
16610927 1378expand_delays (void)
41299f41
TW
1379{
1380 struct delay_desc *delay;
1381 rtx condexp;
1382 rtx newexp;
1383 int i;
1384 char *p;
1385
1386 /* First, generate data for `num_delay_slots' function. */
1387
1388 condexp = rtx_alloc (COND);
1389 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1390 XEXP (condexp, 1) = make_numeric_value (0);
1391
1392 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1393 {
1394 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1395 XVECEXP (condexp, 0, i + 1)
1396 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1397 }
1398
75669493 1399 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE);
41299f41
TW
1400
1401 /* If more than one delay type, do the same for computing the delay type. */
1402 if (num_delays > 1)
1403 {
1404 condexp = rtx_alloc (COND);
1405 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1406 XEXP (condexp, 1) = make_numeric_value (0);
1407
1408 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1409 {
1410 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1411 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1412 }
1413
75669493 1414 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL);
41299f41
TW
1415 }
1416
6dc42e49
RS
1417 /* For each delay possibility and delay slot, compute an eligibility
1418 attribute for non-annulled insns and for each type of annulled (annul
41299f41 1419 if true and annul if false). */
c9541287
KH
1420 for (delay = delays; delay; delay = delay->next)
1421 {
1422 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1423 {
1424 condexp = XVECEXP (delay->def, 1, i);
1425 if (condexp == 0)
1426 condexp = false_rtx;
1427 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1428 make_numeric_value (1), make_numeric_value (0));
1429
7b9e1fcf
RK
1430 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1431 "*delay_%d_%d", delay->num, i / 3);
11597bc9 1432 make_internal_attr (p, newexp, ATTR_SPECIAL);
c9541287
KH
1433
1434 if (have_annul_true)
1435 {
1436 condexp = XVECEXP (delay->def, 1, i + 1);
1437 if (condexp == 0) condexp = false_rtx;
1438 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1439 make_numeric_value (1),
1440 make_numeric_value (0));
7b9e1fcf 1441 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
c9541287 1442 "*annul_true_%d_%d", delay->num, i / 3);
11597bc9 1443 make_internal_attr (p, newexp, ATTR_SPECIAL);
c9541287
KH
1444 }
1445
1446 if (have_annul_false)
1447 {
1448 condexp = XVECEXP (delay->def, 1, i + 2);
1449 if (condexp == 0) condexp = false_rtx;
1450 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1451 make_numeric_value (1),
1452 make_numeric_value (0));
7b9e1fcf 1453 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
c9541287 1454 "*annul_false_%d_%d", delay->num, i / 3);
11597bc9 1455 make_internal_attr (p, newexp, ATTR_SPECIAL);
c9541287
KH
1456 }
1457 }
1458 }
41299f41 1459}
16610927 1460
41299f41
TW
1461/* Once all attributes and insns have been read and checked, we construct for
1462 each attribute value a list of all the insns that have that value for
1463 the attribute. */
1464
1465static void
16610927 1466fill_attr (struct attr_desc *attr)
41299f41
TW
1467{
1468 struct attr_value *av;
1469 struct insn_ent *ie;
1470 struct insn_def *id;
1471 int i;
1472 rtx value;
1473
b31a5831
RS
1474 /* Don't fill constant attributes. The value is independent of
1475 any particular insn. */
1476 if (attr->is_const)
1477 return;
1478
41299f41
TW
1479 for (id = defs; id; id = id->next)
1480 {
1481 /* If no value is specified for this insn for this attribute, use the
1482 default. */
1483 value = NULL;
1484 if (XVEC (id->def, id->vec_idx))
1485 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
75669493
ZD
1486 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1487 attr->name))
41299f41
TW
1488 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1489
1490 if (value == NULL)
1491 av = attr->default_val;
1492 else
1493 av = get_attr_value (value, attr, id->insn_code);
1494
703ad42b 1495 ie = oballoc (sizeof (struct insn_ent));
1e9c8405 1496 ie->def = id;
41299f41
TW
1497 insert_insn_ent (av, ie);
1498 }
1499}
16610927 1500
ae90e6a3
RS
1501/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1502 test that checks relative positions of insns (uses MATCH_DUP or PC).
1503 If so, replace it with what is obtained by passing the expression to
1504 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1505 recursively on each value (including the default value). Otherwise,
1506 return the value returned by NO_ADDRESS_FN applied to EXP. */
41299f41
TW
1507
1508static rtx
16610927
AJ
1509substitute_address (rtx exp, rtx (*no_address_fn) (rtx),
1510 rtx (*address_fn) (rtx))
41299f41
TW
1511{
1512 int i;
1513 rtx newexp;
1514
ae90e6a3
RS
1515 if (GET_CODE (exp) == COND)
1516 {
1517 /* See if any tests use addresses. */
1518 address_used = 0;
1519 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1520 walk_attr_value (XVECEXP (exp, 0, i));
41299f41 1521
ae90e6a3
RS
1522 if (address_used)
1523 return (*address_fn) (exp);
41299f41 1524
ae90e6a3
RS
1525 /* Make a new copy of this COND, replacing each element. */
1526 newexp = rtx_alloc (COND);
1527 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1528 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1529 {
1530 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1531 XVECEXP (newexp, 0, i + 1)
1532 = substitute_address (XVECEXP (exp, 0, i + 1),
1533 no_address_fn, address_fn);
1534 }
41299f41 1535
ae90e6a3
RS
1536 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1537 no_address_fn, address_fn);
1538
1539 return newexp;
41299f41
TW
1540 }
1541
ae90e6a3
RS
1542 else if (GET_CODE (exp) == IF_THEN_ELSE)
1543 {
1544 address_used = 0;
1545 walk_attr_value (XEXP (exp, 0));
1546 if (address_used)
1547 return (*address_fn) (exp);
41299f41 1548
3e7b5313
TW
1549 return attr_rtx (IF_THEN_ELSE,
1550 substitute_address (XEXP (exp, 0),
1551 no_address_fn, address_fn),
1552 substitute_address (XEXP (exp, 1),
1553 no_address_fn, address_fn),
1554 substitute_address (XEXP (exp, 2),
1555 no_address_fn, address_fn));
ae90e6a3
RS
1556 }
1557
1558 return (*no_address_fn) (exp);
41299f41 1559}
16610927 1560
41299f41
TW
1561/* Make new attributes from the `length' attribute. The following are made,
1562 each corresponding to a function called from `shorten_branches' or
1563 `get_attr_length':
1564
1565 *insn_default_length This is the length of the insn to be returned
1566 by `get_attr_length' before `shorten_branches'
1567 has been called. In each case where the length
1568 depends on relative addresses, the largest
1569 possible is used. This routine is also used
1570 to compute the initial size of the insn.
1571
1572 *insn_variable_length_p This returns 1 if the insn's length depends
1573 on relative addresses, zero otherwise.
1574
1575 *insn_current_length This is only called when it is known that the
1576 insn has a variable length and returns the
1577 current length, based on relative addresses.
1578 */
1579
1580static void
16610927 1581make_length_attrs (void)
41299f41 1582{
75669493
ZD
1583 static const char *new_names[] =
1584 {
1585 "*insn_default_length",
1586 "*insn_variable_length_p",
1587 "*insn_current_length"
1588 };
16610927
AJ
1589 static rtx (*const no_address_fn[]) (rtx) = {identity_fn, zero_fn, zero_fn};
1590 static rtx (*const address_fn[]) (rtx) = {max_fn, one_fn, identity_fn};
d6f4ec51 1591 size_t i;
41299f41
TW
1592 struct attr_desc *length_attr, *new_attr;
1593 struct attr_value *av, *new_av;
1594 struct insn_ent *ie, *new_ie;
1595
1596 /* See if length attribute is defined. If so, it must be numeric. Make
1597 it special so we don't output anything for it. */
75669493 1598 length_attr = find_attr (&length_str, 0);
41299f41
TW
1599 if (length_attr == 0)
1600 return;
1601
1602 if (! length_attr->is_numeric)
357351e5 1603 fatal ("length attribute must be numeric");
41299f41 1604
3e7b5313 1605 length_attr->is_const = 0;
41299f41
TW
1606 length_attr->is_special = 1;
1607
1608 /* Make each new attribute, in turn. */
b6a1cbae 1609 for (i = 0; i < ARRAY_SIZE (new_names); i++)
41299f41
TW
1610 {
1611 make_internal_attr (new_names[i],
1612 substitute_address (length_attr->default_val->value,
1613 no_address_fn[i], address_fn[i]),
11597bc9 1614 ATTR_NONE);
75669493 1615 new_attr = find_attr (&new_names[i], 0);
41299f41
TW
1616 for (av = length_attr->first_value; av; av = av->next)
1617 for (ie = av->first_insn; ie; ie = ie->next)
1618 {
1619 new_av = get_attr_value (substitute_address (av->value,
1620 no_address_fn[i],
1621 address_fn[i]),
1e9c8405 1622 new_attr, ie->def->insn_code);
703ad42b 1623 new_ie = oballoc (sizeof (struct insn_ent));
1e9c8405 1624 new_ie->def = ie->def;
41299f41
TW
1625 insert_insn_ent (new_av, new_ie);
1626 }
1627 }
1628}
1629
1630/* Utility functions called from above routine. */
1631
1632static rtx
16610927 1633identity_fn (rtx exp)
41299f41
TW
1634{
1635 return exp;
1636}
1637
1638static rtx
16610927 1639zero_fn (rtx exp ATTRIBUTE_UNUSED)
41299f41
TW
1640{
1641 return make_numeric_value (0);
1642}
1643
1644static rtx
16610927 1645one_fn (rtx exp ATTRIBUTE_UNUSED)
41299f41
TW
1646{
1647 return make_numeric_value (1);
1648}
1649
1650static rtx
16610927 1651max_fn (rtx exp)
41299f41 1652{
7ee37ba4
RH
1653 int unknown;
1654 return make_numeric_value (max_attr_value (exp, &unknown));
41299f41 1655}
fc470718
R
1656
1657static void
16610927 1658write_length_unit_log (void)
fc470718 1659{
75669493 1660 struct attr_desc *length_attr = find_attr (&length_str, 0);
fc470718
R
1661 struct attr_value *av;
1662 struct insn_ent *ie;
1663 unsigned int length_unit_log, length_or;
7ee37ba4 1664 int unknown = 0;
fc470718
R
1665
1666 if (length_attr == 0)
1667 return;
7ee37ba4
RH
1668 length_or = or_attr_value (length_attr->default_val->value, &unknown);
1669 for (av = length_attr->first_value; av; av = av->next)
1670 for (ie = av->first_insn; ie; ie = ie->next)
1671 length_or |= or_attr_value (av->value, &unknown);
1672
1673 if (unknown)
1674 length_unit_log = 0;
1675 else
1676 {
1677 length_or = ~length_or;
1678 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
c9541287 1679 length_unit_log++;
7ee37ba4 1680 }
fc470718
R
1681 printf ("int length_unit_log = %u;\n", length_unit_log);
1682}
16610927 1683
41299f41
TW
1684/* Take a COND expression and see if any of the conditions in it can be
1685 simplified. If any are known true or known false for the particular insn
1686 code, the COND can be further simplified.
1687
1688 Also call ourselves on any COND operations that are values of this COND.
1689
7339c88d 1690 We do not modify EXP; rather, we make and return a new rtx. */
41299f41
TW
1691
1692static rtx
16610927 1693simplify_cond (rtx exp, int insn_code, int insn_index)
41299f41
TW
1694{
1695 int i, j;
7339c88d
RS
1696 /* We store the desired contents here,
1697 then build a new expression if they don't match EXP. */
1698 rtx defval = XEXP (exp, 1);
eaed7119 1699 rtx new_defval = XEXP (exp, 1);
7339c88d 1700 int len = XVECLEN (exp, 0);
703ad42b 1701 rtx *tests = xmalloc (len * sizeof (rtx));
7339c88d 1702 int allsame = 1;
b548dffb 1703 rtx ret;
41299f41 1704
7339c88d 1705 /* This lets us free all storage allocated below, if appropriate. */
4977bab6 1706 obstack_finish (rtl_obstack);
41299f41 1707
4e135bdd 1708 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
41299f41 1709
7339c88d
RS
1710 /* See if default value needs simplification. */
1711 if (GET_CODE (defval) == COND)
eaed7119 1712 new_defval = simplify_cond (defval, insn_code, insn_index);
41299f41 1713
81fd4c6e 1714 /* Simplify the subexpressions, and see what tests we can get rid of. */
41299f41 1715
81fd4c6e 1716 for (i = 0; i < len; i += 2)
7339c88d
RS
1717 {
1718 rtx newtest, newval;
41299f41 1719
7339c88d 1720 /* Simplify this test. */
2d515d60 1721 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
910eabe5 1722 tests[i] = newtest;
41299f41 1723
910eabe5 1724 newval = tests[i + 1];
7339c88d
RS
1725 /* See if this value may need simplification. */
1726 if (GET_CODE (newval) == COND)
1727 newval = simplify_cond (newval, insn_code, insn_index);
1728
1729 /* Look for ways to delete or combine this test. */
1730 if (newtest == true_rtx)
1731 {
1732 /* If test is true, make this value the default
1733 and discard this + any following tests. */
1734 len = i;
910eabe5 1735 defval = tests[i + 1];
eaed7119 1736 new_defval = newval;
41299f41
TW
1737 }
1738
7339c88d 1739 else if (newtest == false_rtx)
41299f41 1740 {
7339c88d
RS
1741 /* If test is false, discard it and its value. */
1742 for (j = i; j < len - 2; j++)
910eabe5 1743 tests[j] = tests[j + 2];
8653a1ed 1744 i -= 2;
81fd4c6e
RS
1745 len -= 2;
1746 }
41299f41 1747
910eabe5 1748 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
81fd4c6e
RS
1749 {
1750 /* If this value and the value for the prev test are the same,
1751 merge the tests. */
1752
910eabe5
JL
1753 tests[i - 2]
1754 = insert_right_side (IOR, tests[i - 2], newtest,
81fd4c6e
RS
1755 insn_code, insn_index);
1756
1757 /* Delete this test/value. */
1758 for (j = i; j < len - 2; j++)
910eabe5 1759 tests[j] = tests[j + 2];
7339c88d 1760 len -= 2;
8653a1ed 1761 i -= 2;
41299f41
TW
1762 }
1763
81fd4c6e 1764 else
910eabe5 1765 tests[i + 1] = newval;
7339c88d 1766 }
41299f41 1767
81fd4c6e
RS
1768 /* If the last test in a COND has the same value
1769 as the default value, that test isn't needed. */
1770
910eabe5 1771 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
81fd4c6e
RS
1772 len -= 2;
1773
1774 /* See if we changed anything. */
1775 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
1776 allsame = 0;
1777 else
1778 for (i = 0; i < len; i++)
910eabe5 1779 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
81fd4c6e
RS
1780 {
1781 allsame = 0;
1782 break;
1783 }
41299f41 1784
7339c88d
RS
1785 if (len == 0)
1786 {
7339c88d 1787 if (GET_CODE (defval) == COND)
b548dffb
ZW
1788 ret = simplify_cond (defval, insn_code, insn_index);
1789 else
1790 ret = defval;
7339c88d 1791 }
81fd4c6e 1792 else if (allsame)
b548dffb 1793 ret = exp;
7339c88d
RS
1794 else
1795 {
81fd4c6e 1796 rtx newexp = rtx_alloc (COND);
7339c88d
RS
1797
1798 XVEC (newexp, 0) = rtvec_alloc (len);
4e135bdd 1799 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
81fd4c6e 1800 XEXP (newexp, 1) = new_defval;
b548dffb 1801 ret = newexp;
41299f41 1802 }
b548dffb
ZW
1803 free (tests);
1804 return ret;
41299f41 1805}
16610927 1806
41299f41
TW
1807/* Remove an insn entry from an attribute value. */
1808
1809static void
16610927 1810remove_insn_ent (struct attr_value *av, struct insn_ent *ie)
41299f41
TW
1811{
1812 struct insn_ent *previe;
1813
1814 if (av->first_insn == ie)
1815 av->first_insn = ie->next;
1816 else
1817 {
1818 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1819 ;
1820 previe->next = ie->next;
1821 }
1822
1823 av->num_insns--;
1e9c8405 1824 if (ie->def->insn_code == -1)
41299f41 1825 av->has_asm_insn = 0;
1c69865d
ILT
1826
1827 num_insn_ents--;
41299f41
TW
1828}
1829
1830/* Insert an insn entry in an attribute value list. */
1831
1832static void
16610927 1833insert_insn_ent (struct attr_value *av, struct insn_ent *ie)
41299f41
TW
1834{
1835 ie->next = av->first_insn;
1836 av->first_insn = ie;
1837 av->num_insns++;
1e9c8405 1838 if (ie->def->insn_code == -1)
41299f41 1839 av->has_asm_insn = 1;
1c69865d
ILT
1840
1841 num_insn_ents++;
41299f41 1842}
16610927 1843
41299f41
TW
1844/* This is a utility routine to take an expression that is a tree of either
1845 AND or IOR expressions and insert a new term. The new term will be
1846 inserted at the right side of the first node whose code does not match
1847 the root. A new node will be created with the root's code. Its left
1848 side will be the old right side and its right side will be the new
1849 term.
1850
1851 If the `term' is itself a tree, all its leaves will be inserted. */
1852
1853static rtx
16610927 1854insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index)
41299f41
TW
1855{
1856 rtx newexp;
1857
7339c88d
RS
1858 /* Avoid consing in some special cases. */
1859 if (code == AND && term == true_rtx)
1860 return exp;
1861 if (code == AND && term == false_rtx)
1862 return false_rtx;
1863 if (code == AND && exp == true_rtx)
1864 return term;
1865 if (code == AND && exp == false_rtx)
1866 return false_rtx;
1867 if (code == IOR && term == true_rtx)
1868 return true_rtx;
1869 if (code == IOR && term == false_rtx)
1870 return exp;
1871 if (code == IOR && exp == true_rtx)
1872 return true_rtx;
1873 if (code == IOR && exp == false_rtx)
1874 return term;
81fd4c6e 1875 if (attr_equal_p (exp, term))
7339c88d
RS
1876 return exp;
1877
41299f41
TW
1878 if (GET_CODE (term) == code)
1879 {
1880 exp = insert_right_side (code, exp, XEXP (term, 0),
1881 insn_code, insn_index);
1882 exp = insert_right_side (code, exp, XEXP (term, 1),
1883 insn_code, insn_index);
1884
1885 return exp;
1886 }
1887
1888 if (GET_CODE (exp) == code)
1889 {
7339c88d
RS
1890 rtx new = insert_right_side (code, XEXP (exp, 1),
1891 term, insn_code, insn_index);
1892 if (new != XEXP (exp, 1))
1893 /* Make a copy of this expression and call recursively. */
1894 newexp = attr_rtx (code, XEXP (exp, 0), new);
1895 else
1896 newexp = exp;
41299f41
TW
1897 }
1898 else
1899 {
1900 /* Insert the new term. */
3e7b5313 1901 newexp = attr_rtx (code, exp, term);
7339c88d 1902 }
41299f41 1903
2d515d60 1904 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41 1905}
16610927 1906
41299f41
TW
1907/* If we have an expression which AND's a bunch of
1908 (not (eq_attrq "alternative" "n"))
1909 terms, we may have covered all or all but one of the possible alternatives.
1910 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1911
1912 This routine is passed an expression and either AND or IOR. It returns a
f75d38a7 1913 bitmask indicating which alternatives are mentioned within EXP. */
41299f41
TW
1914
1915static int
16610927 1916compute_alternative_mask (rtx exp, enum rtx_code code)
41299f41 1917{
3cce094d 1918 const char *string;
41299f41
TW
1919 if (GET_CODE (exp) == code)
1920 return compute_alternative_mask (XEXP (exp, 0), code)
1921 | compute_alternative_mask (XEXP (exp, 1), code);
1922
1923 else if (code == AND && GET_CODE (exp) == NOT
1924 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1925 && XSTR (XEXP (exp, 0), 0) == alternative_name)
b31a5831 1926 string = XSTR (XEXP (exp, 0), 1);
41299f41
TW
1927
1928 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1929 && XSTR (exp, 0) == alternative_name)
b31a5831 1930 string = XSTR (exp, 1);
41299f41 1931
8653a1ed
ZD
1932 else if (GET_CODE (exp) == EQ_ATTR_ALT)
1933 {
1934 if (code == AND && XINT (exp, 1))
1935 return XINT (exp, 0);
1936
1937 if (code == IOR && !XINT (exp, 1))
1938 return XINT (exp, 0);
1939
1940 return 0;
1941 }
41299f41
TW
1942 else
1943 return 0;
b31a5831
RS
1944
1945 if (string[1] == 0)
1946 return 1 << (string[0] - '0');
1947 return 1 << atoi (string);
41299f41
TW
1948}
1949
1950/* Given I, a single-bit mask, return RTX to compare the `alternative'
1951 attribute with the value represented by that bit. */
1952
1953static rtx
16610927 1954make_alternative_compare (int mask)
41299f41 1955{
8653a1ed 1956 return mk_attr_alt (mask);
41299f41 1957}
16610927 1958
41299f41
TW
1959/* If we are processing an (eq_attr "attr" "value") test, we find the value
1960 of "attr" for this insn code. From that value, we can compute a test
1961 showing when the EQ_ATTR will be true. This routine performs that
1962 computation. If a test condition involves an address, we leave the EQ_ATTR
c9541287 1963 intact because addresses are only valid for the `length' attribute.
41299f41 1964
f75d38a7
RK
1965 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1966 for the insn corresponding to INSN_CODE and INSN_INDEX. */
7339c88d 1967
41299f41 1968static rtx
16610927 1969evaluate_eq_attr (rtx exp, rtx value, int insn_code, int insn_index)
41299f41
TW
1970{
1971 rtx orexp, andexp;
1972 rtx right;
1973 rtx newexp;
1974 int i;
1975
b2d59f6f 1976 switch (GET_CODE (value))
41299f41 1977 {
b2d59f6f 1978 case CONST_STRING:
75669493 1979 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1)))
41299f41
TW
1980 newexp = true_rtx;
1981 else
1982 newexp = false_rtx;
b2d59f6f
NS
1983 break;
1984
1985 case SYMBOL_REF:
1986 {
1987 char *p;
1988 char string[256];
1989
1990 gcc_assert (GET_CODE (exp) == EQ_ATTR);
1991 gcc_assert (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2
1992 <= 256);
1993
1994 strcpy (string, XSTR (exp, 0));
1995 strcat (string, "_");
1996 strcat (string, XSTR (exp, 1));
1997 for (p = string; *p; p++)
1998 *p = TOUPPER (*p);
1999
2000 newexp = attr_rtx (EQ, value,
2001 attr_rtx (SYMBOL_REF,
2002 DEF_ATTR_STRING (string)));
2003 break;
2004 }
41299f41 2005
b2d59f6f
NS
2006 case COND:
2007 /* We construct an IOR of all the cases for which the
2008 requested attribute value is present. Since we start with
2009 FALSE, if it is not present, FALSE will be returned.
2010
41299f41 2011 Each case is the AND of the NOT's of the previous conditions with the
c9541287 2012 current condition; in the default case the current condition is TRUE.
b2d59f6f 2013
41299f41 2014 For each possible COND value, call ourselves recursively.
b2d59f6f 2015
41299f41 2016 The extra TRUE and FALSE expressions will be eliminated by another
0f41302f 2017 call to the simplification routine. */
41299f41
TW
2018
2019 orexp = false_rtx;
2020 andexp = true_rtx;
2021
2022 for (i = 0; i < XVECLEN (value, 0); i += 2)
2023 {
2d515d60
JH
2024 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2025 insn_code, insn_index);
7339c88d
RS
2026
2027 right = insert_right_side (AND, andexp, this,
41299f41
TW
2028 insn_code, insn_index);
2029 right = insert_right_side (AND, right,
f75d38a7
RK
2030 evaluate_eq_attr (exp,
2031 XVECEXP (value, 0,
2032 i + 1),
2033 insn_code, insn_index),
41299f41
TW
2034 insn_code, insn_index);
2035 orexp = insert_right_side (IOR, orexp, right,
2036 insn_code, insn_index);
2037
2038 /* Add this condition into the AND expression. */
7339c88d 2039 newexp = attr_rtx (NOT, this);
41299f41
TW
2040 andexp = insert_right_side (AND, andexp, newexp,
2041 insn_code, insn_index);
2042 }
2043
2044 /* Handle the default case. */
2045 right = insert_right_side (AND, andexp,
2046 evaluate_eq_attr (exp, XEXP (value, 1),
f75d38a7 2047 insn_code, insn_index),
41299f41
TW
2048 insn_code, insn_index);
2049 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
b2d59f6f
NS
2050 break;
2051
2052 default:
2053 gcc_unreachable ();
41299f41 2054 }
41299f41 2055
052aaaef 2056 /* If uses an address, must return original expression. But set the
2adc7f12 2057 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
41299f41
TW
2058
2059 address_used = 0;
2060 walk_attr_value (newexp);
2061
2062 if (address_used)
052aaaef 2063 {
2adc7f12 2064 if (! ATTR_IND_SIMPLIFIED_P (exp))
7339c88d 2065 return copy_rtx_unchanging (exp);
052aaaef
RK
2066 return exp;
2067 }
41299f41
TW
2068 else
2069 return newexp;
2070}
16610927 2071
41299f41
TW
2072/* This routine is called when an AND of a term with a tree of AND's is
2073 encountered. If the term or its complement is present in the tree, it
2074 can be replaced with TRUE or FALSE, respectively.
2075
2076 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
c9541287 2077 be true and hence are complementary.
41299f41
TW
2078
2079 There is one special case: If we see
2080 (and (not (eq_attr "att" "v1"))
2081 (eq_attr "att" "v2"))
2082 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2083 replace the term, not anything in the AND tree. So we pass a pointer to
2084 the term. */
2085
2086static rtx
16610927 2087simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
41299f41
TW
2088{
2089 rtx left, right;
2090 rtx newexp;
2091 rtx temp;
2092 int left_eliminates_term, right_eliminates_term;
2093
2094 if (GET_CODE (exp) == AND)
2095 {
c9541287 2096 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
41299f41
TW
2097 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2098 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2099 {
8653a1ed 2100 newexp = attr_rtx (AND, left, right);
41299f41 2101
2d515d60 2102 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
2103 }
2104 }
2105
2106 else if (GET_CODE (exp) == IOR)
2107 {
2108 /* For the IOR case, we do the same as above, except that we can
2109 only eliminate `term' if both sides of the IOR would do so. */
2110 temp = *pterm;
c9541287 2111 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
41299f41
TW
2112 left_eliminates_term = (temp == true_rtx);
2113
2114 temp = *pterm;
2115 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2116 right_eliminates_term = (temp == true_rtx);
2117
2118 if (left_eliminates_term && right_eliminates_term)
2119 *pterm = true_rtx;
2120
2121 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2122 {
8653a1ed 2123 newexp = attr_rtx (IOR, left, right);
41299f41 2124
2d515d60 2125 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
2126 }
2127 }
2128
2129 /* Check for simplifications. Do some extra checking here since this
2130 routine is called so many times. */
2131
2132 if (exp == *pterm)
2133 return true_rtx;
2134
2135 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2136 return false_rtx;
2137
2138 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2139 return false_rtx;
2140
8653a1ed
ZD
2141 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT)
2142 {
2143 if (attr_alt_subset_p (*pterm, exp))
2144 return true_rtx;
2145
2146 if (attr_alt_subset_of_compl_p (*pterm, exp))
2147 return false_rtx;
2148
2149 if (attr_alt_subset_p (exp, *pterm))
2150 *pterm = true_rtx;
2151
2152 return exp;
2153 }
2154
41299f41
TW
2155 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2156 {
2157 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2158 return exp;
2159
75669493 2160 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1)))
41299f41
TW
2161 return true_rtx;
2162 else
2163 return false_rtx;
2164 }
2165
2166 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2167 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2168 {
2169 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2170 return exp;
2171
75669493 2172 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
41299f41
TW
2173 return false_rtx;
2174 else
2175 return true_rtx;
2176 }
2177
2178 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2179 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2180 {
2181 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2182 return exp;
2183
75669493 2184 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
41299f41
TW
2185 return false_rtx;
2186 else
2187 *pterm = true_rtx;
2188 }
2189
2190 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2191 {
81fd4c6e 2192 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
41299f41
TW
2193 return true_rtx;
2194 }
2195
2196 else if (GET_CODE (exp) == NOT)
2197 {
81fd4c6e 2198 if (attr_equal_p (XEXP (exp, 0), *pterm))
41299f41
TW
2199 return false_rtx;
2200 }
2201
2202 else if (GET_CODE (*pterm) == NOT)
2203 {
81fd4c6e 2204 if (attr_equal_p (XEXP (*pterm, 0), exp))
41299f41
TW
2205 return false_rtx;
2206 }
2207
81fd4c6e 2208 else if (attr_equal_p (exp, *pterm))
41299f41
TW
2209 return true_rtx;
2210
2211 return exp;
2212}
16610927 2213
6dc42e49 2214/* Similar to `simplify_and_tree', but for IOR trees. */
41299f41
TW
2215
2216static rtx
16610927 2217simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index)
41299f41
TW
2218{
2219 rtx left, right;
2220 rtx newexp;
2221 rtx temp;
2222 int left_eliminates_term, right_eliminates_term;
2223
2224 if (GET_CODE (exp) == IOR)
2225 {
c9541287 2226 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
41299f41
TW
2227 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2228 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2229 {
3e7b5313 2230 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41 2231
2d515d60 2232 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
2233 }
2234 }
2235
2236 else if (GET_CODE (exp) == AND)
2237 {
2238 /* For the AND case, we do the same as above, except that we can
2239 only eliminate `term' if both sides of the AND would do so. */
2240 temp = *pterm;
c9541287 2241 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
41299f41
TW
2242 left_eliminates_term = (temp == false_rtx);
2243
2244 temp = *pterm;
2245 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2246 right_eliminates_term = (temp == false_rtx);
2247
2248 if (left_eliminates_term && right_eliminates_term)
2249 *pterm = false_rtx;
2250
2251 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2252 {
3e7b5313 2253 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41 2254
2d515d60 2255 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
2256 }
2257 }
2258
81fd4c6e 2259 if (attr_equal_p (exp, *pterm))
41299f41
TW
2260 return false_rtx;
2261
81fd4c6e 2262 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
41299f41
TW
2263 return true_rtx;
2264
81fd4c6e 2265 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
41299f41
TW
2266 return true_rtx;
2267
2268 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2269 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2270 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2271 *pterm = false_rtx;
2272
2273 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2274 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2275 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2276 return false_rtx;
2277
2278 return exp;
2279}
16610927 2280
2bed3391 2281/* Compute approximate cost of the expression. Used to decide whether
eaec9b3d 2282 expression is cheap enough for inline. */
2bed3391 2283static int
16610927 2284attr_rtx_cost (rtx x)
2bed3391
JH
2285{
2286 int cost = 0;
2287 enum rtx_code code;
2288 if (!x)
2289 return 0;
2290 code = GET_CODE (x);
2291 switch (code)
2292 {
2293 case MATCH_OPERAND:
2294 if (XSTR (x, 1)[0])
2295 return 10;
2296 else
2297 return 0;
75669493 2298
8653a1ed
ZD
2299 case EQ_ATTR_ALT:
2300 return 0;
2301
2bed3391
JH
2302 case EQ_ATTR:
2303 /* Alternatives don't result into function call. */
75669493 2304 if (!strcmp_check (XSTR (x, 0), alternative_name))
2bed3391
JH
2305 return 0;
2306 else
2307 return 5;
2308 default:
2309 {
2310 int i, j;
2311 const char *fmt = GET_RTX_FORMAT (code);
2312 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2313 {
2314 switch (fmt[i])
2315 {
2316 case 'V':
2317 case 'E':
2318 for (j = 0; j < XVECLEN (x, i); j++)
2319 cost += attr_rtx_cost (XVECEXP (x, i, j));
2320 break;
2321 case 'e':
2322 cost += attr_rtx_cost (XEXP (x, i));
2323 break;
2324 }
2325 }
2326 }
2327 break;
2328 }
2329 return cost;
2330}
2d515d60
JH
2331
2332/* Simplify test expression and use temporary obstack in order to avoid
fbe5a4a6
KH
2333 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2334 and avoid unnecessary copying if possible. */
2d515d60
JH
2335
2336static rtx
16610927 2337simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index)
2d515d60
JH
2338{
2339 rtx x;
2340 struct obstack *old;
2adc7f12 2341 if (ATTR_IND_SIMPLIFIED_P (exp))
2d515d60
JH
2342 return exp;
2343 old = rtl_obstack;
2344 rtl_obstack = temp_obstack;
2345 x = simplify_test_exp (exp, insn_code, insn_index);
2346 rtl_obstack = old;
2347 if (x == exp || rtl_obstack == temp_obstack)
2348 return x;
2349 return attr_copy_rtx (x);
2350}
2351
8653a1ed
ZD
2352/* Returns true if S1 is a subset of S2. */
2353
2354static bool
2355attr_alt_subset_p (rtx s1, rtx s2)
2356{
2357 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2358 {
2359 case (0 << 1) | 0:
2360 return !(XINT (s1, 0) &~ XINT (s2, 0));
2361
2362 case (0 << 1) | 1:
2363 return !(XINT (s1, 0) & XINT (s2, 0));
2364
2365 case (1 << 1) | 0:
2366 return false;
2367
2368 case (1 << 1) | 1:
2369 return !(XINT (s2, 0) &~ XINT (s1, 0));
2370
2371 default:
b2d59f6f 2372 gcc_unreachable ();
8653a1ed
ZD
2373 }
2374}
2375
2376/* Returns true if S1 is a subset of complement of S2. */
2377
b2d59f6f
NS
2378static bool
2379attr_alt_subset_of_compl_p (rtx s1, rtx s2)
8653a1ed
ZD
2380{
2381 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2382 {
2383 case (0 << 1) | 0:
2384 return !(XINT (s1, 0) & XINT (s2, 0));
2385
2386 case (0 << 1) | 1:
2387 return !(XINT (s1, 0) & ~XINT (s2, 0));
2388
2389 case (1 << 1) | 0:
2390 return !(XINT (s2, 0) &~ XINT (s1, 0));
2391
2392 case (1 << 1) | 1:
2393 return false;
2394
2395 default:
b2d59f6f 2396 gcc_unreachable ();
8653a1ed
ZD
2397 }
2398}
2399
2400/* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2401
2402static rtx
2403attr_alt_intersection (rtx s1, rtx s2)
2404{
2405 rtx result = rtx_alloc (EQ_ATTR_ALT);
2406
2407 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2408 {
2409 case (0 << 1) | 0:
2410 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2411 break;
2412 case (0 << 1) | 1:
2413 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2414 break;
2415 case (1 << 1) | 0:
2416 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2417 break;
2418 case (1 << 1) | 1:
2419 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2420 break;
2421 default:
b2d59f6f 2422 gcc_unreachable ();
8653a1ed
ZD
2423 }
2424 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1);
2425
2426 return result;
2427}
2428
2429/* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2430
2431static rtx
2432attr_alt_union (rtx s1, rtx s2)
2433{
2434 rtx result = rtx_alloc (EQ_ATTR_ALT);
2435
2436 switch ((XINT (s1, 1) << 1) | XINT (s2, 1))
2437 {
2438 case (0 << 1) | 0:
2439 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0);
2440 break;
2441 case (0 << 1) | 1:
2442 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0);
2443 break;
2444 case (1 << 1) | 0:
2445 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0);
2446 break;
2447 case (1 << 1) | 1:
2448 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0);
2449 break;
2450 default:
b2d59f6f 2451 gcc_unreachable ();
8653a1ed
ZD
2452 }
2453
2454 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1);
2455 return result;
2456}
2457
2458/* Return EQ_ATTR_ALT expression representing complement of S. */
2459
2460static rtx
2461attr_alt_complement (rtx s)
2462{
2463 rtx result = rtx_alloc (EQ_ATTR_ALT);
2464
2465 XINT (result, 0) = XINT (s, 0);
2466 XINT (result, 1) = 1 - XINT (s, 1);
2467
2468 return result;
2469}
2470
8653a1ed
ZD
2471/* Return EQ_ATTR_ALT expression representing set containing elements set
2472 in E. */
2473
2474static rtx
2475mk_attr_alt (int e)
2476{
2477 rtx result = rtx_alloc (EQ_ATTR_ALT);
2478
2479 XINT (result, 0) = e;
2480 XINT (result, 1) = 0;
2481
2482 return result;
2483}
2484
41299f41
TW
2485/* Given an expression, see if it can be simplified for a particular insn
2486 code based on the values of other attributes being tested. This can
2487 eliminate nested get_attr_... calls.
2488
c9541287 2489 Note that if an endless recursion is specified in the patterns, the
41299f41
TW
2490 optimization will loop. However, it will do so in precisely the cases where
2491 an infinite recursion loop could occur during compilation. It's better that
2492 it occurs here! */
2493
2494static rtx
16610927 2495simplify_test_exp (rtx exp, int insn_code, int insn_index)
41299f41
TW
2496{
2497 rtx left, right;
2498 struct attr_desc *attr;
2499 struct attr_value *av;
2500 struct insn_ent *ie;
2501 int i;
2502 rtx newexp = exp;
8653a1ed 2503 bool left_alt, right_alt;
7339c88d 2504
7339c88d 2505 /* Don't re-simplify something we already simplified. */
2adc7f12 2506 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
7339c88d 2507 return exp;
41299f41
TW
2508
2509 switch (GET_CODE (exp))
2510 {
2511 case AND:
61abc2ca 2512 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3715a518 2513 if (left == false_rtx)
1f8f4a0b 2514 return false_rtx;
61abc2ca 2515 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
b01896cc 2516 if (right == false_rtx)
1f8f4a0b 2517 return false_rtx;
61abc2ca 2518
8653a1ed
ZD
2519 if (GET_CODE (left) == EQ_ATTR_ALT
2520 && GET_CODE (right) == EQ_ATTR_ALT)
2521 {
2522 exp = attr_alt_intersection (left, right);
2523 return simplify_test_exp (exp, insn_code, insn_index);
2524 }
2525
61abc2ca
RS
2526 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2527 present on both sides, apply the distributive law since this will
2528 yield simplifications. */
2529 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2530 && compute_alternative_mask (left, IOR)
2531 && compute_alternative_mask (right, IOR))
41299f41 2532 {
61abc2ca 2533 if (GET_CODE (left) == IOR)
41299f41 2534 {
61abc2ca
RS
2535 rtx tem = left;
2536 left = right;
2537 right = tem;
2538 }
2539
2540 newexp = attr_rtx (IOR,
2541 attr_rtx (AND, left, XEXP (right, 0)),
2542 attr_rtx (AND, left, XEXP (right, 1)));
2543
2544 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2545 }
2546
2547 /* Try with the term on both sides. */
2548 right = simplify_and_tree (right, &left, insn_code, insn_index);
2549 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2550 left = simplify_and_tree (left, &right, insn_code, insn_index);
2551
2552 if (left == false_rtx || right == false_rtx)
1f8f4a0b 2553 return false_rtx;
61abc2ca
RS
2554 else if (left == true_rtx)
2555 {
85093b9c 2556 return right;
61abc2ca
RS
2557 }
2558 else if (right == true_rtx)
2559 {
85093b9c 2560 return left;
61abc2ca 2561 }
61abc2ca
RS
2562 /* See if all or all but one of the insn's alternatives are specified
2563 in this tree. Optimize if so. */
2564
8653a1ed
ZD
2565 if (GET_CODE (left) == NOT)
2566 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR
2567 && XSTR (XEXP (left, 0), 0) == alternative_name);
2568 else
2569 left_alt = (GET_CODE (left) == EQ_ATTR_ALT
2570 && XINT (left, 1));
2571
2572 if (GET_CODE (right) == NOT)
2573 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR
2574 && XSTR (XEXP (right, 0), 0) == alternative_name);
2575 else
2576 right_alt = (GET_CODE (right) == EQ_ATTR_ALT
2577 && XINT (right, 1));
2578
2579 if (insn_code >= 0
2580 && (GET_CODE (left) == AND
2581 || left_alt
2582 || GET_CODE (right) == AND
2583 || right_alt))
61abc2ca
RS
2584 {
2585 i = compute_alternative_mask (exp, AND);
2586 if (i & ~insn_alternatives[insn_code])
1f978f5f 2587 fatal ("invalid alternative specified for pattern number %d",
61abc2ca
RS
2588 insn_index);
2589
0f41302f 2590 /* If all alternatives are excluded, this is false. */
61abc2ca
RS
2591 i ^= insn_alternatives[insn_code];
2592 if (i == 0)
2593 return false_rtx;
2594 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2595 {
2596 /* If just one excluded, AND a comparison with that one to the
2597 front of the tree. The others will be eliminated by
2598 optimization. We do not want to do this if the insn has one
2599 alternative and we have tested none of them! */
2600 left = make_alternative_compare (i);
2601 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2602 newexp = attr_rtx (AND, left, right);
41299f41
TW
2603
2604 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2605 }
2606 }
61abc2ca
RS
2607
2608 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2609 {
2610 newexp = attr_rtx (AND, left, right);
2611 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2612 }
2613 break;
41299f41
TW
2614
2615 case IOR:
61abc2ca 2616 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3715a518 2617 if (left == true_rtx)
1f8f4a0b 2618 return true_rtx;
61abc2ca 2619 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3715a518 2620 if (right == true_rtx)
1f8f4a0b 2621 return true_rtx;
61abc2ca 2622
8653a1ed
ZD
2623 if (GET_CODE (left) == EQ_ATTR_ALT
2624 && GET_CODE (right) == EQ_ATTR_ALT)
2625 {
2626 exp = attr_alt_union (left, right);
2627 return simplify_test_exp (exp, insn_code, insn_index);
2628 }
2629
61abc2ca
RS
2630 right = simplify_or_tree (right, &left, insn_code, insn_index);
2631 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2632 left = simplify_or_tree (left, &right, insn_code, insn_index);
2633
2634 if (right == true_rtx || left == true_rtx)
1f8f4a0b 2635 return true_rtx;
61abc2ca
RS
2636 else if (left == false_rtx)
2637 {
85093b9c 2638 return right;
61abc2ca
RS
2639 }
2640 else if (right == false_rtx)
2641 {
85093b9c 2642 return left;
61abc2ca
RS
2643 }
2644
2645 /* Test for simple cases where the distributive law is useful. I.e.,
2646 convert (ior (and (x) (y))
2647 (and (x) (z)))
2648 to (and (x)
2649 (ior (y) (z)))
2650 */
2651
2652 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
c9541287 2653 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
61abc2ca
RS
2654 {
2655 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2656
2657 left = XEXP (left, 0);
2658 right = newexp;
2659 newexp = attr_rtx (AND, left, right);
2660 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2661 }
2662
2663 /* See if all or all but one of the insn's alternatives are specified
2664 in this tree. Optimize if so. */
2665
2666 else if (insn_code >= 0
c9541287 2667 && (GET_CODE (left) == IOR
8653a1ed
ZD
2668 || (GET_CODE (left) == EQ_ATTR_ALT
2669 && !XINT (left, 1))
c9541287
KH
2670 || (GET_CODE (left) == EQ_ATTR
2671 && XSTR (left, 0) == alternative_name)
2672 || GET_CODE (right) == IOR
8653a1ed
ZD
2673 || (GET_CODE (right) == EQ_ATTR_ALT
2674 && !XINT (right, 1))
c9541287
KH
2675 || (GET_CODE (right) == EQ_ATTR
2676 && XSTR (right, 0) == alternative_name)))
61abc2ca
RS
2677 {
2678 i = compute_alternative_mask (exp, IOR);
2679 if (i & ~insn_alternatives[insn_code])
1f978f5f 2680 fatal ("invalid alternative specified for pattern number %d",
61abc2ca
RS
2681 insn_index);
2682
0f41302f 2683 /* If all alternatives are included, this is true. */
61abc2ca
RS
2684 i ^= insn_alternatives[insn_code];
2685 if (i == 0)
2686 return true_rtx;
2687 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2688 {
2689 /* If just one excluded, IOR a comparison with that one to the
2690 front of the tree. The others will be eliminated by
2691 optimization. We do not want to do this if the insn has one
2692 alternative and we have tested none of them! */
2693 left = make_alternative_compare (i);
2694 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2695 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2696
2697 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2698 }
2699 }
2700
2701 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2702 {
2703 newexp = attr_rtx (IOR, left, right);
2704 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2705 }
2706 break;
41299f41
TW
2707
2708 case NOT:
7339c88d 2709 if (GET_CODE (XEXP (exp, 0)) == NOT)
3715a518
RS
2710 {
2711 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
2712 insn_code, insn_index);
3715a518
RS
2713 return left;
2714 }
2715
41299f41
TW
2716 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2717 if (GET_CODE (left) == NOT)
2718 return XEXP (left, 0);
2719
2720 if (left == false_rtx)
1f8f4a0b 2721 return true_rtx;
8653a1ed 2722 if (left == true_rtx)
1f8f4a0b 2723 return false_rtx;
41299f41 2724
8653a1ed
ZD
2725 if (GET_CODE (left) == EQ_ATTR_ALT)
2726 {
2727 exp = attr_alt_complement (left);
2728 return simplify_test_exp (exp, insn_code, insn_index);
2729 }
2730
41299f41 2731 /* Try to apply De`Morgan's laws. */
8653a1ed 2732 if (GET_CODE (left) == IOR)
41299f41 2733 {
3e7b5313
TW
2734 newexp = attr_rtx (AND,
2735 attr_rtx (NOT, XEXP (left, 0)),
2736 attr_rtx (NOT, XEXP (left, 1)));
41299f41
TW
2737
2738 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2739 }
2740 else if (GET_CODE (left) == AND)
2741 {
3e7b5313
TW
2742 newexp = attr_rtx (IOR,
2743 attr_rtx (NOT, XEXP (left, 0)),
2744 attr_rtx (NOT, XEXP (left, 1)));
41299f41
TW
2745
2746 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2747 }
2748 else if (left != XEXP (exp, 0))
2749 {
3e7b5313 2750 newexp = attr_rtx (NOT, left);
41299f41
TW
2751 }
2752 break;
2753
8653a1ed 2754 case EQ_ATTR_ALT:
8653a1ed
ZD
2755 if (!XINT (exp, 0))
2756 return XINT (exp, 1) ? true_rtx : false_rtx;
2757 break;
2758
41299f41 2759 case EQ_ATTR:
8653a1ed
ZD
2760 if (XSTR (exp, 0) == alternative_name)
2761 {
2762 newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1)));
2763 break;
2764 }
2765
41299f41
TW
2766 /* Look at the value for this insn code in the specified attribute.
2767 We normally can replace this comparison with the condition that
6d2f8887 2768 would give this insn the values being tested for. */
b01896cc 2769 if (insn_code >= 0
75669493 2770 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL)
41299f41
TW
2771 for (av = attr->first_value; av; av = av->next)
2772 for (ie = av->first_insn; ie; ie = ie->next)
1e9c8405 2773 if (ie->def->insn_code == insn_code)
2bed3391
JH
2774 {
2775 rtx x;
2bed3391
JH
2776 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2777 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2bed3391 2778 if (attr_rtx_cost(x) < 20)
2d515d60 2779 return x;
2bed3391 2780 }
e9a25f70 2781 break;
c9541287 2782
e9a25f70
JL
2783 default:
2784 break;
41299f41
TW
2785 }
2786
2787 /* We have already simplified this expression. Simplifying it again
2788 won't buy anything unless we weren't given a valid insn code
2789 to process (i.e., we are canonicalizing something.). */
b01896cc 2790 if (insn_code != -2
2adc7f12 2791 && ! ATTR_IND_SIMPLIFIED_P (newexp))
3715a518 2792 return copy_rtx_unchanging (newexp);
41299f41
TW
2793
2794 return newexp;
2795}
16610927 2796
41299f41
TW
2797/* Optimize the attribute lists by seeing if we can determine conditional
2798 values from the known values of other attributes. This will save subroutine
2799 calls during the compilation. */
2800
2801static void
16610927 2802optimize_attrs (void)
41299f41
TW
2803{
2804 struct attr_desc *attr;
2805 struct attr_value *av;
b5b6ad46 2806 struct insn_ent *ie;
41299f41 2807 rtx newexp;
85093b9c 2808 int i;
c9541287
KH
2809 struct attr_value_list
2810 {
2811 struct attr_value *av;
2812 struct insn_ent *ie;
2813 struct attr_desc *attr;
2814 struct attr_value_list *next;
2815 };
85093b9c 2816 struct attr_value_list **insn_code_values;
1c69865d 2817 struct attr_value_list *ivbuf;
85093b9c
RS
2818 struct attr_value_list *iv;
2819
fa0aee89
PB
2820 /* For each insn code, make a list of all the insn_ent's for it,
2821 for all values for all attributes. */
72f1215c 2822
fa0aee89
PB
2823 if (num_insn_ents == 0)
2824 return;
72f1215c 2825
fa0aee89
PB
2826 /* Make 2 extra elements, for "code" values -2 and -1. */
2827 insn_code_values = xcalloc ((insn_code_number + 2),
2828 sizeof (struct attr_value_list *));
72f1215c 2829
fa0aee89
PB
2830 /* Offset the table address so we can index by -2 or -1. */
2831 insn_code_values += 2;
72f1215c 2832
fa0aee89 2833 iv = ivbuf = xmalloc (num_insn_ents * sizeof (struct attr_value_list));
72f1215c 2834
fa0aee89
PB
2835 for (i = 0; i < MAX_ATTRS_INDEX; i++)
2836 for (attr = attrs[i]; attr; attr = attr->next)
2837 for (av = attr->first_value; av; av = av->next)
2838 for (ie = av->first_insn; ie; ie = ie->next)
2839 {
2840 iv->attr = attr;
2841 iv->av = av;
2842 iv->ie = ie;
1e9c8405
RS
2843 iv->next = insn_code_values[ie->def->insn_code];
2844 insn_code_values[ie->def->insn_code] = iv;
fa0aee89
PB
2845 iv++;
2846 }
72f1215c 2847
fa0aee89 2848 /* Sanity check on num_insn_ents. */
b2d59f6f 2849 gcc_assert (iv == ivbuf + num_insn_ents);
72f1215c 2850
fa0aee89
PB
2851 /* Process one insn code at a time. */
2852 for (i = -2; i < insn_code_number; i++)
2853 {
2854 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2855 We use it to mean "already simplified for this insn". */
2856 for (iv = insn_code_values[i]; iv; iv = iv->next)
2857 clear_struct_flag (iv->av->value);
72f1215c 2858
fa0aee89 2859 for (iv = insn_code_values[i]; iv; iv = iv->next)
72f1215c 2860 {
fa0aee89
PB
2861 struct obstack *old = rtl_obstack;
2862
2863 attr = iv->attr;
2864 av = iv->av;
2865 ie = iv->ie;
2866 if (GET_CODE (av->value) != COND)
72f1215c 2867 continue;
e9a25f70 2868
fa0aee89
PB
2869 rtl_obstack = temp_obstack;
2870 newexp = av->value;
2871 while (GET_CODE (newexp) == COND)
2872 {
1e9c8405
RS
2873 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code,
2874 ie->def->insn_index);
fa0aee89
PB
2875 if (newexp2 == newexp)
2876 break;
2877 newexp = newexp2;
2878 }
2879
2880 rtl_obstack = old;
2881 if (newexp != av->value)
2882 {
2883 newexp = attr_copy_rtx (newexp);
2884 remove_insn_ent (av, ie);
1e9c8405 2885 av = get_attr_value (newexp, attr, ie->def->insn_code);
fa0aee89
PB
2886 iv->av = av;
2887 insert_insn_ent (av, ie);
2888 }
2889 }
72f1215c 2890 }
fa0aee89
PB
2891
2892 free (ivbuf);
2893 free (insn_code_values - 2);
72f1215c 2894}
16610927 2895
2adc7f12 2896/* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
85093b9c 2897
9a63e81d 2898static void
16610927 2899clear_struct_flag (rtx x)
85093b9c 2900{
b3694847
SS
2901 int i;
2902 int j;
2903 enum rtx_code code;
2904 const char *fmt;
85093b9c 2905
2adc7f12
JJ
2906 ATTR_CURR_SIMPLIFIED_P (x) = 0;
2907 if (ATTR_IND_SIMPLIFIED_P (x))
85093b9c
RS
2908 return;
2909
2910 code = GET_CODE (x);
2911
2912 switch (code)
2913 {
2914 case REG:
85093b9c
RS
2915 case CONST_INT:
2916 case CONST_DOUBLE:
69ef87e2 2917 case CONST_VECTOR:
85093b9c
RS
2918 case SYMBOL_REF:
2919 case CODE_LABEL:
2920 case PC:
2921 case CC0:
2922 case EQ_ATTR:
0b0316dc 2923 case ATTR_FLAG:
85093b9c 2924 return;
c9541287 2925
e9a25f70
JL
2926 default:
2927 break;
85093b9c
RS
2928 }
2929
2930 /* Compare the elements. If any pair of corresponding elements
2931 fail to match, return 0 for the whole things. */
2932
2933 fmt = GET_RTX_FORMAT (code);
2934 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2935 {
2936 switch (fmt[i])
2937 {
2938 case 'V':
2939 case 'E':
85093b9c
RS
2940 for (j = 0; j < XVECLEN (x, i); j++)
2941 clear_struct_flag (XVECEXP (x, i, j));
2942 break;
2943
2944 case 'e':
2945 clear_struct_flag (XEXP (x, i));
2946 break;
2947 }
41299f41
TW
2948 }
2949}
3715a518 2950
41299f41
TW
2951/* Create table entries for DEFINE_ATTR. */
2952
2953static void
16610927 2954gen_attr (rtx exp, int lineno)
41299f41
TW
2955{
2956 struct attr_desc *attr;
2957 struct attr_value *av;
3cce094d 2958 const char *name_ptr;
41299f41
TW
2959 char *p;
2960
2961 /* Make a new attribute structure. Check for duplicate by looking at
2962 attr->default_val, since it is initialized by this routine. */
75669493 2963 attr = find_attr (&XSTR (exp, 0), 1);
41299f41 2964 if (attr->default_val)
a4cad544
RH
2965 {
2966 message_with_line (lineno, "duplicate definition for attribute %s",
2967 attr->name);
2968 message_with_line (attr->lineno, "previous definition");
2969 have_error = 1;
2970 return;
2971 }
2972 attr->lineno = lineno;
41299f41
TW
2973
2974 if (*XSTR (exp, 1) == '\0')
7ee37ba4 2975 attr->is_numeric = 1;
41299f41
TW
2976 else
2977 {
2978 name_ptr = XSTR (exp, 1);
2979 while ((p = next_comma_elt (&name_ptr)) != NULL)
2980 {
703ad42b 2981 av = oballoc (sizeof (struct attr_value));
3e7b5313 2982 av->value = attr_rtx (CONST_STRING, p);
41299f41
TW
2983 av->next = attr->first_value;
2984 attr->first_value = av;
2985 av->first_insn = NULL;
2986 av->num_insns = 0;
2987 av->has_asm_insn = 0;
2988 }
2989 }
2990
3e7b5313
TW
2991 if (GET_CODE (XEXP (exp, 2)) == CONST)
2992 {
2993 attr->is_const = 1;
2994 if (attr->is_numeric)
a4cad544
RH
2995 {
2996 message_with_line (lineno,
2997 "constant attributes may not take numeric values");
2998 have_error = 1;
2999 }
3000
3e7b5313
TW
3001 /* Get rid of the CONST node. It is allowed only at top-level. */
3002 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
3003 }
3004
75669493 3005 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric)
a4cad544 3006 {
c9541287
KH
3007 message_with_line (lineno,
3008 "`length' attribute must take numeric values");
a4cad544
RH
3009 have_error = 1;
3010 }
41299f41 3011
0f41302f 3012 /* Set up the default value. */
81fd4c6e 3013 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
41299f41
TW
3014 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
3015}
16610927 3016
41299f41
TW
3017/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3018 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3019 number of alternatives as this should be checked elsewhere. */
3020
3021static int
16610927 3022count_alternatives (rtx exp)
41299f41
TW
3023{
3024 int i, j, n;
6f7d635c 3025 const char *fmt;
c9541287 3026
41299f41
TW
3027 if (GET_CODE (exp) == MATCH_OPERAND)
3028 return n_comma_elts (XSTR (exp, 2));
3029
3030 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3031 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3032 switch (*fmt++)
3033 {
3034 case 'e':
3035 case 'u':
3036 n = count_alternatives (XEXP (exp, i));
3037 if (n)
3038 return n;
3039 break;
3040
3041 case 'E':
3042 case 'V':
3043 if (XVEC (exp, i) != NULL)
3044 for (j = 0; j < XVECLEN (exp, i); j++)
3045 {
3046 n = count_alternatives (XVECEXP (exp, i, j));
3047 if (n)
3048 return n;
3049 }
3050 }
3051
3052 return 0;
3053}
16610927 3054
cc2902df 3055/* Returns nonzero if the given expression contains an EQ_ATTR with the
41299f41
TW
3056 `alternative' attribute. */
3057
3058static int
16610927 3059compares_alternatives_p (rtx exp)
41299f41
TW
3060{
3061 int i, j;
6f7d635c 3062 const char *fmt;
41299f41
TW
3063
3064 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
3065 return 1;
3066
3067 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3068 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3069 switch (*fmt++)
3070 {
3071 case 'e':
3072 case 'u':
3073 if (compares_alternatives_p (XEXP (exp, i)))
3074 return 1;
3075 break;
3076
3077 case 'E':
3078 for (j = 0; j < XVECLEN (exp, i); j++)
3079 if (compares_alternatives_p (XVECEXP (exp, i, j)))
3080 return 1;
3081 break;
3082 }
3083
3084 return 0;
3085}
16610927 3086
cc2902df 3087/* Returns nonzero is INNER is contained in EXP. */
41299f41
TW
3088
3089static int
16610927 3090contained_in_p (rtx inner, rtx exp)
41299f41
TW
3091{
3092 int i, j;
6f7d635c 3093 const char *fmt;
41299f41
TW
3094
3095 if (rtx_equal_p (inner, exp))
3096 return 1;
3097
3098 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
3099 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
3100 switch (*fmt++)
3101 {
3102 case 'e':
3103 case 'u':
3104 if (contained_in_p (inner, XEXP (exp, i)))
3105 return 1;
3106 break;
3107
3108 case 'E':
3109 for (j = 0; j < XVECLEN (exp, i); j++)
3110 if (contained_in_p (inner, XVECEXP (exp, i, j)))
3111 return 1;
3112 break;
3113 }
3114
3115 return 0;
3116}
16610927 3117
41299f41
TW
3118/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3119
3120static void
16610927 3121gen_insn (rtx exp, int lineno)
41299f41
TW
3122{
3123 struct insn_def *id;
3124
703ad42b 3125 id = oballoc (sizeof (struct insn_def));
41299f41
TW
3126 id->next = defs;
3127 defs = id;
3128 id->def = exp;
a4cad544 3129 id->lineno = lineno;
41299f41
TW
3130
3131 switch (GET_CODE (exp))
3132 {
3133 case DEFINE_INSN:
c88c0d42
CP
3134 id->insn_code = insn_code_number;
3135 id->insn_index = insn_index_number;
41299f41
TW
3136 id->num_alternatives = count_alternatives (exp);
3137 if (id->num_alternatives == 0)
3138 id->num_alternatives = 1;
3139 id->vec_idx = 4;
3140 break;
3141
3142 case DEFINE_PEEPHOLE:
c88c0d42
CP
3143 id->insn_code = insn_code_number;
3144 id->insn_index = insn_index_number;
41299f41
TW
3145 id->num_alternatives = count_alternatives (exp);
3146 if (id->num_alternatives == 0)
3147 id->num_alternatives = 1;
3148 id->vec_idx = 3;
3149 break;
3150
3151 case DEFINE_ASM_ATTRIBUTES:
3152 id->insn_code = -1;
3153 id->insn_index = -1;
3154 id->num_alternatives = 1;
3155 id->vec_idx = 0;
3156 got_define_asm_attributes = 1;
3157 break;
c9541287 3158
e9a25f70 3159 default:
b2d59f6f 3160 gcc_unreachable ();
41299f41
TW
3161 }
3162}
16610927 3163
41299f41
TW
3164/* Process a DEFINE_DELAY. Validate the vector length, check if annul
3165 true or annul false is specified, and make a `struct delay_desc'. */
3166
3167static void
16610927 3168gen_delay (rtx def, int lineno)
41299f41
TW
3169{
3170 struct delay_desc *delay;
3171 int i;
3172
3173 if (XVECLEN (def, 1) % 3 != 0)
a4cad544
RH
3174 {
3175 message_with_line (lineno,
c9541287 3176 "number of elements in DEFINE_DELAY must be multiple of three");
a4cad544
RH
3177 have_error = 1;
3178 return;
3179 }
41299f41
TW
3180
3181 for (i = 0; i < XVECLEN (def, 1); i += 3)
3182 {
3183 if (XVECEXP (def, 1, i + 1))
3184 have_annul_true = 1;
3185 if (XVECEXP (def, 1, i + 2))
3186 have_annul_false = 1;
3187 }
c9541287 3188
703ad42b 3189 delay = oballoc (sizeof (struct delay_desc));
41299f41
TW
3190 delay->def = def;
3191 delay->num = ++num_delays;
3192 delay->next = delays;
a4cad544 3193 delay->lineno = lineno;
41299f41
TW
3194 delays = delay;
3195}
16610927 3196
9ec36da5 3197/* Given a piece of RTX, print a C expression to test its truth value.
c9541287 3198 We use AND and IOR both for logical and bit-wise operations, so
41299f41 3199 interpret them as logical unless they are inside a comparison expression.
cc2902df 3200 The first bit of FLAGS will be nonzero in that case.
71d9b493
RH
3201
3202 Set the second bit of FLAGS to make references to attribute values use
3203 a cached local variable instead of calling a function. */
41299f41
TW
3204
3205static void
16610927 3206write_test_expr (rtx exp, int flags)
41299f41
TW
3207{
3208 int comparison_operator = 0;
3209 RTX_CODE code;
3210 struct attr_desc *attr;
3211
3212 /* In order not to worry about operator precedence, surround our part of
3213 the expression with parentheses. */
3214
3215 printf ("(");
3216 code = GET_CODE (exp);
3217 switch (code)
3218 {
3219 /* Binary operators. */
b2e0a450
KK
3220 case GEU: case GTU:
3221 case LEU: case LTU:
3222 printf ("(unsigned) ");
3223 /* Fall through. */
3224
41299f41 3225 case EQ: case NE:
b2e0a450
KK
3226 case GE: case GT:
3227 case LE: case LT:
41299f41
TW
3228 comparison_operator = 1;
3229
3230 case PLUS: case MINUS: case MULT: case DIV: case MOD:
3231 case AND: case IOR: case XOR:
45620ed4 3232 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
71d9b493 3233 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
41299f41 3234 switch (code)
c9541287 3235 {
41299f41
TW
3236 case EQ:
3237 printf (" == ");
3238 break;
3239 case NE:
3240 printf (" != ");
3241 break;
3242 case GE:
3243 printf (" >= ");
3244 break;
3245 case GT:
3246 printf (" > ");
3247 break;
3248 case GEU:
3249 printf (" >= (unsigned) ");
3250 break;
3251 case GTU:
3252 printf (" > (unsigned) ");
3253 break;
3254 case LE:
3255 printf (" <= ");
3256 break;
3257 case LT:
3258 printf (" < ");
3259 break;
3260 case LEU:
3261 printf (" <= (unsigned) ");
3262 break;
3263 case LTU:
3264 printf (" < (unsigned) ");
3265 break;
3266 case PLUS:
3267 printf (" + ");
3268 break;
3269 case MINUS:
3270 printf (" - ");
3271 break;
3272 case MULT:
3273 printf (" * ");
3274 break;
3275 case DIV:
3276 printf (" / ");
3277 break;
3278 case MOD:
412dc348 3279 printf (" %% ");
41299f41
TW
3280 break;
3281 case AND:
71d9b493 3282 if (flags & 1)
41299f41
TW
3283 printf (" & ");
3284 else
3285 printf (" && ");
3286 break;
3287 case IOR:
71d9b493 3288 if (flags & 1)
41299f41
TW
3289 printf (" | ");
3290 else
3291 printf (" || ");
3292 break;
3293 case XOR:
3294 printf (" ^ ");
3295 break;
41299f41
TW
3296 case ASHIFT:
3297 printf (" << ");
3298 break;
3299 case LSHIFTRT:
3300 case ASHIFTRT:
3301 printf (" >> ");
3302 break;
e9a25f70 3303 default:
b2d59f6f 3304 gcc_unreachable ();
c9541287 3305 }
41299f41 3306
71d9b493 3307 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
41299f41
TW
3308 break;
3309
3310 case NOT:
3311 /* Special-case (not (eq_attrq "alternative" "x")) */
71d9b493 3312 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
41299f41
TW
3313 && XSTR (XEXP (exp, 0), 0) == alternative_name)
3314 {
3315 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
3316 break;
3317 }
3318
3319 /* Otherwise, fall through to normal unary operator. */
3320
c9541287 3321 /* Unary operators. */
41299f41
TW
3322 case ABS: case NEG:
3323 switch (code)
3324 {
3325 case NOT:
71d9b493 3326 if (flags & 1)
41299f41
TW
3327 printf ("~ ");
3328 else
3329 printf ("! ");
3330 break;
3331 case ABS:
3332 printf ("abs ");
3333 break;
3334 case NEG:
3335 printf ("-");
3336 break;
e9a25f70 3337 default:
b2d59f6f 3338 gcc_unreachable ();
41299f41
TW
3339 }
3340
71d9b493 3341 write_test_expr (XEXP (exp, 0), flags);
41299f41
TW
3342 break;
3343
8653a1ed
ZD
3344 case EQ_ATTR_ALT:
3345 {
3346 int set = XINT (exp, 0), bit = 0;
3347
3348 if (flags & 1)
3349 fatal ("EQ_ATTR_ALT not valid inside comparison");
3350
3351 if (!set)
3352 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3353
3354 if (!(set & (set - 1)))
3355 {
3356 if (!(set & 0xffff))
3357 {
3358 bit += 16;
3359 set >>= 16;
3360 }
3361 if (!(set & 0xff))
3362 {
3363 bit += 8;
3364 set >>= 8;
3365 }
3366 if (!(set & 0xf))
3367 {
3368 bit += 4;
3369 set >>= 4;
3370 }
3371 if (!(set & 0x3))
3372 {
3373 bit += 2;
3374 set >>= 2;
3375 }
3376 if (!(set & 1))
3377 bit++;
3378
3379 printf ("which_alternative %s= %d",
3380 XINT (exp, 1) ? "!" : "=", bit);
3381 }
3382 else
3383 {
3384 printf ("%s((1 << which_alternative) & 0x%x)",
3385 XINT (exp, 1) ? "!" : "", set);
3386 }
3387 }
3388 break;
3389
41299f41
TW
3390 /* Comparison test of an attribute with a value. Most of these will
3391 have been removed by optimization. Handle "alternative"
3392 specially and give error if EQ_ATTR present inside a comparison. */
3393 case EQ_ATTR:
71d9b493 3394 if (flags & 1)
41299f41
TW
3395 fatal ("EQ_ATTR not valid inside comparison");
3396
3397 if (XSTR (exp, 0) == alternative_name)
3398 {
3399 printf ("which_alternative == %s", XSTR (exp, 1));
3400 break;
3401 }
3402
75669493 3403 attr = find_attr (&XSTR (exp, 0), 0);
b2d59f6f 3404 gcc_assert (attr);
b31a5831
RS
3405
3406 /* Now is the time to expand the value of a constant attribute. */
3407 if (attr->is_const)
3408 {
3409 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
dedb78d4 3410 -2, -2),
71d9b493 3411 flags);
b31a5831
RS
3412 }
3413 else
3414 {
71d9b493
RH
3415 if (flags & 2)
3416 printf ("attr_%s", attr->name);
3417 else
3418 printf ("get_attr_%s (insn)", attr->name);
3419 printf (" == ");
3420 write_attr_valueq (attr, XSTR (exp, 1));
b31a5831 3421 }
41299f41
TW
3422 break;
3423
0b0316dc
JL
3424 /* Comparison test of flags for define_delays. */
3425 case ATTR_FLAG:
71d9b493 3426 if (flags & 1)
0b0316dc
JL
3427 fatal ("ATTR_FLAG not valid inside comparison");
3428 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
3429 break;
3430
41299f41
TW
3431 /* See if an operand matches a predicate. */
3432 case MATCH_OPERAND:
3433 /* If only a mode is given, just ensure the mode matches the operand.
3434 If neither a mode nor predicate is given, error. */
c9541287 3435 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
41299f41
TW
3436 {
3437 if (GET_MODE (exp) == VOIDmode)
1f978f5f 3438 fatal ("null MATCH_OPERAND specified as test");
41299f41
TW
3439 else
3440 printf ("GET_MODE (operands[%d]) == %smode",
3441 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3442 }
3443 else
3444 printf ("%s (operands[%d], %smode)",
3445 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
3446 break;
3447
0f41302f 3448 /* Constant integer. */
41299f41 3449 case CONST_INT:
76d31c63 3450 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
41299f41
TW
3451 break;
3452
0f41302f 3453 /* A random C expression. */
41299f41 3454 case SYMBOL_REF:
7445392c 3455 print_c_condition (XSTR (exp, 0));
41299f41
TW
3456 break;
3457
3458 /* The address of the branch target. */
3459 case MATCH_DUP:
a4cad544 3460 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
5ab7138b 3461 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
41299f41
TW
3462 break;
3463
41299f41 3464 case PC:
fc470718
R
3465 /* The address of the current insn. We implement this actually as the
3466 address of the current insn for backward branches, but the last
3467 address of the next insn for forward branches, and both with
3468 adjustments that account for the worst-case possible stretching of
3469 intervening alignments between this insn and its destination. */
c9541287 3470 printf ("insn_current_reference_address (insn)");
41299f41
TW
3471 break;
3472
71d9b493
RH
3473 case CONST_STRING:
3474 printf ("%s", XSTR (exp, 0));
3475 break;
3476
3477 case IF_THEN_ELSE:
3478 write_test_expr (XEXP (exp, 0), flags & 2);
3479 printf (" ? ");
3480 write_test_expr (XEXP (exp, 1), flags | 1);
3481 printf (" : ");
3482 write_test_expr (XEXP (exp, 2), flags | 1);
3483 break;
3484
41299f41
TW
3485 default:
3486 fatal ("bad RTX code `%s' in attribute calculation\n",
3487 GET_RTX_NAME (code));
3488 }
3489
3490 printf (")");
3491}
16610927 3492
41299f41 3493/* Given an attribute value, return the maximum CONST_STRING argument
7ee37ba4 3494 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
41299f41
TW
3495
3496static int
16610927 3497max_attr_value (rtx exp, int *unknownp)
41299f41 3498{
7ee37ba4
RH
3499 int current_max;
3500 int i, n;
41299f41 3501
7ee37ba4 3502 switch (GET_CODE (exp))
41299f41 3503 {
7ee37ba4
RH
3504 case CONST_STRING:
3505 current_max = atoi (XSTR (exp, 0));
3506 break;
3507
3508 case COND:
3509 current_max = max_attr_value (XEXP (exp, 1), unknownp);
41299f41
TW
3510 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3511 {
7ee37ba4 3512 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
41299f41
TW
3513 if (n > current_max)
3514 current_max = n;
3515 }
7ee37ba4 3516 break;
41299f41 3517
7ee37ba4
RH
3518 case IF_THEN_ELSE:
3519 current_max = max_attr_value (XEXP (exp, 1), unknownp);
3520 n = max_attr_value (XEXP (exp, 2), unknownp);
41299f41
TW
3521 if (n > current_max)
3522 current_max = n;
7ee37ba4 3523 break;
41299f41 3524
7ee37ba4
RH
3525 default:
3526 *unknownp = 1;
3527 current_max = INT_MAX;
3528 break;
bee757e1
TW
3529 }
3530
41299f41
TW
3531 return current_max;
3532}
fc470718
R
3533
3534/* Given an attribute value, return the result of ORing together all
7ee37ba4
RH
3535 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3536 if the numeric value is not known. */
fc470718
R
3537
3538static int
16610927 3539or_attr_value (rtx exp, int *unknownp)
fc470718 3540{
7ee37ba4 3541 int current_or;
fc470718
R
3542 int i;
3543
7ee37ba4 3544 switch (GET_CODE (exp))
fc470718 3545 {
7ee37ba4
RH
3546 case CONST_STRING:
3547 current_or = atoi (XSTR (exp, 0));
3548 break;
3549
3550 case COND:
3551 current_or = or_attr_value (XEXP (exp, 1), unknownp);
fc470718 3552 for (i = 0; i < XVECLEN (exp, 0); i += 2)
7ee37ba4
RH
3553 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
3554 break;
fc470718 3555
7ee37ba4
RH
3556 case IF_THEN_ELSE:
3557 current_or = or_attr_value (XEXP (exp, 1), unknownp);
3558 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
3559 break;
fc470718 3560
7ee37ba4
RH
3561 default:
3562 *unknownp = 1;
3563 current_or = -1;
3564 break;
fc470718
R
3565 }
3566
fc470718
R
3567 return current_or;
3568}
16610927 3569
41299f41
TW
3570/* Scan an attribute value, possibly a conditional, and record what actions
3571 will be required to do any conditional tests in it.
3572
3573 Specifically, set
3574 `must_extract' if we need to extract the insn operands
3575 `must_constrain' if we must compute `which_alternative'
3576 `address_used' if an address expression was used
d7c665bf 3577 `length_used' if an (eq_attr "length" ...) was used
41299f41
TW
3578 */
3579
3580static void
16610927 3581walk_attr_value (rtx exp)
41299f41 3582{
b3694847
SS
3583 int i, j;
3584 const char *fmt;
41299f41
TW
3585 RTX_CODE code;
3586
3587 if (exp == NULL)
3588 return;
3589
3590 code = GET_CODE (exp);
3591 switch (code)
3592 {
3593 case SYMBOL_REF:
2adc7f12 3594 if (! ATTR_IND_SIMPLIFIED_P (exp))
3e7b5313
TW
3595 /* Since this is an arbitrary expression, it can look at anything.
3596 However, constant expressions do not depend on any particular
3597 insn. */
3598 must_extract = must_constrain = 1;
41299f41
TW
3599 return;
3600
3601 case MATCH_OPERAND:
3602 must_extract = 1;
3603 return;
3604
8653a1ed
ZD
3605 case EQ_ATTR_ALT:
3606 must_extract = must_constrain = 1;
3607 break;
3608
41299f41
TW
3609 case EQ_ATTR:
3610 if (XSTR (exp, 0) == alternative_name)
3611 must_extract = must_constrain = 1;
75669493 3612 else if (strcmp_check (XSTR (exp, 0), length_str) == 0)
d7c665bf 3613 length_used = 1;
41299f41
TW
3614 return;
3615
3616 case MATCH_DUP:
426cd2f4
RK
3617 must_extract = 1;
3618 address_used = 1;
3619 return;
3620
41299f41
TW
3621 case PC:
3622 address_used = 1;
3623 return;
0b0316dc
JL
3624
3625 case ATTR_FLAG:
3626 return;
e9a25f70
JL
3627
3628 default:
3629 break;
41299f41
TW
3630 }
3631
3632 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3633 switch (*fmt++)
3634 {
3635 case 'e':
3636 case 'u':
3637 walk_attr_value (XEXP (exp, i));
3638 break;
3639
3640 case 'E':
3641 if (XVEC (exp, i) != NULL)
3642 for (j = 0; j < XVECLEN (exp, i); j++)
3643 walk_attr_value (XVECEXP (exp, i, j));
3644 break;
3645 }
3646}
16610927 3647
41299f41
TW
3648/* Write out a function to obtain the attribute for a given INSN. */
3649
3650static void
16610927 3651write_attr_get (struct attr_desc *attr)
41299f41
TW
3652{
3653 struct attr_value *av, *common_av;
3654
3655 /* Find the most used attribute value. Handle that as the `default' of the
0f41302f 3656 switch we will generate. */
41299f41
TW
3657 common_av = find_most_used (attr);
3658
3659 /* Write out start of function, then all values with explicit `case' lines,
3660 then a `default', then the value with the most uses. */
ec049fdb
KG
3661 if (attr->static_p)
3662 printf ("static ");
bee757e1 3663 if (!attr->is_numeric)
41299f41 3664 printf ("enum attr_%s\n", attr->name);
bee757e1
TW
3665 else
3666 printf ("int\n");
41299f41
TW
3667
3668 /* If the attribute name starts with a star, the remainder is the name of
3669 the subroutine to use, instead of `get_attr_...'. */
3670 if (attr->name[0] == '*')
6906ba40 3671 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr->name[1]);
3e7b5313 3672 else if (attr->is_const == 0)
6906ba40 3673 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr->name);
3e7b5313
TW
3674 else
3675 {
6906ba40 3676 printf ("get_attr_%s (void)\n", attr->name);
3e7b5313
TW
3677 printf ("{\n");
3678
3679 for (av = attr->first_value; av; av = av->next)
3680 if (av->num_insns != 0)
3681 write_attr_set (attr, 2, av->value, "return", ";",
1e9c8405
RS
3682 true_rtx, av->first_insn->def->insn_code,
3683 av->first_insn->def->insn_index);
3e7b5313
TW
3684
3685 printf ("}\n\n");
3686 return;
3687 }
71d9b493 3688
41299f41 3689 printf ("{\n");
fa0aee89
PB
3690 printf (" switch (recog_memoized (insn))\n");
3691 printf (" {\n");
41299f41 3692
fa0aee89
PB
3693 for (av = attr->first_value; av; av = av->next)
3694 if (av != common_av)
3695 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
71d9b493 3696
fa0aee89
PB
3697 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3698 printf (" }\n}\n\n");
41299f41 3699}
16610927 3700
41299f41
TW
3701/* Given an AND tree of known true terms (because we are inside an `if' with
3702 that as the condition or are in an `else' clause) and an expression,
3703 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3704 the bulk of the work. */
3705
3706static rtx
16610927 3707eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index)
41299f41
TW
3708{
3709 rtx term;
3710
61abc2ca
RS
3711 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3712
3713 if (GET_CODE (known_true) == AND)
3714 {
3715 exp = eliminate_known_true (XEXP (known_true, 0), exp,
3716 insn_code, insn_index);
3717 exp = eliminate_known_true (XEXP (known_true, 1), exp,
3718 insn_code, insn_index);
3719 }
3720 else
3721 {
3722 term = known_true;
3723 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3724 }
3725
3726 return exp;
41299f41 3727}
16610927 3728
41299f41
TW
3729/* Write out a series of tests and assignment statements to perform tests and
3730 sets of an attribute value. We are passed an indentation amount and prefix
3731 and suffix strings to write around each attribute value (e.g., "return"
3732 and ";"). */
3733
3734static void
16610927
AJ
3735write_attr_set (struct attr_desc *attr, int indent, rtx value,
3736 const char *prefix, const char *suffix, rtx known_true,
3737 int insn_code, int insn_index)
41299f41 3738{
7ee37ba4 3739 if (GET_CODE (value) == COND)
41299f41
TW
3740 {
3741 /* Assume the default value will be the default of the COND unless we
3742 find an always true expression. */
3743 rtx default_val = XEXP (value, 1);
3744 rtx our_known_true = known_true;
3745 rtx newexp;
3746 int first_if = 1;
3747 int i;
3748
3749 for (i = 0; i < XVECLEN (value, 0); i += 2)
3750 {
3751 rtx testexp;
3752 rtx inner_true;
3753
3754 testexp = eliminate_known_true (our_known_true,
3755 XVECEXP (value, 0, i),
3756 insn_code, insn_index);
3e7b5313 3757 newexp = attr_rtx (NOT, testexp);
c9541287
KH
3758 newexp = insert_right_side (AND, our_known_true, newexp,
3759 insn_code, insn_index);
41299f41
TW
3760
3761 /* If the test expression is always true or if the next `known_true'
3762 expression is always false, this is the last case, so break
3763 out and let this value be the `else' case. */
3764 if (testexp == true_rtx || newexp == false_rtx)
3765 {
3766 default_val = XVECEXP (value, 0, i + 1);
3767 break;
3768 }
3769
3770 /* Compute the expression to pass to our recursive call as being
3771 known true. */
3772 inner_true = insert_right_side (AND, our_known_true,
3773 testexp, insn_code, insn_index);
3774
3775 /* If this is always false, skip it. */
3776 if (inner_true == false_rtx)
3777 continue;
3778
3779 write_indent (indent);
3780 printf ("%sif ", first_if ? "" : "else ");
3781 first_if = 0;
3782 write_test_expr (testexp, 0);
3783 printf ("\n");
3784 write_indent (indent + 2);
3785 printf ("{\n");
3786
c9541287 3787 write_attr_set (attr, indent + 4,
41299f41
TW
3788 XVECEXP (value, 0, i + 1), prefix, suffix,
3789 inner_true, insn_code, insn_index);
3790 write_indent (indent + 2);
3791 printf ("}\n");
3792 our_known_true = newexp;
3793 }
3794
3795 if (! first_if)
3796 {
3797 write_indent (indent);
3798 printf ("else\n");
3799 write_indent (indent + 2);
3800 printf ("{\n");
3801 }
3802
3803 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3804 prefix, suffix, our_known_true, insn_code, insn_index);
3805
3806 if (! first_if)
3807 {
3808 write_indent (indent + 2);
3809 printf ("}\n");
3810 }
3811 }
3812 else
7ee37ba4
RH
3813 {
3814 write_indent (indent);
3815 printf ("%s ", prefix);
3816 write_attr_value (attr, value);
3817 printf ("%s\n", suffix);
3818 }
41299f41 3819}
16610927 3820
c1a404bd
RS
3821/* Write a series of case statements for every instruction in list IE.
3822 INDENT is the amount of indentation to write before each case. */
3823
3824static void
3825write_insn_cases (struct insn_ent *ie, int indent)
3826{
3827 for (; ie != 0; ie = ie->next)
3828 if (ie->def->insn_code != -1)
3829 {
3830 write_indent (indent);
3831 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE)
3832 printf ("case %d: /* define_peephole, line %d */\n",
3833 ie->def->insn_code, ie->def->lineno);
3834 else
3835 printf ("case %d: /* %s */\n",
3836 ie->def->insn_code, XSTR (ie->def->def, 0));
3837 }
3838}
3839
41299f41
TW
3840/* Write out the computation for one attribute value. */
3841
3842static void
16610927
AJ
3843write_attr_case (struct attr_desc *attr, struct attr_value *av,
3844 int write_case_lines, const char *prefix, const char *suffix,
3845 int indent, rtx known_true)
41299f41 3846{
41299f41
TW
3847 if (av->num_insns == 0)
3848 return;
3849
3850 if (av->has_asm_insn)
3851 {
3852 write_indent (indent);
3853 printf ("case -1:\n");
3854 write_indent (indent + 2);
3855 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3856 write_indent (indent + 2);
3857 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3858 write_indent (indent + 2);
3859 printf (" fatal_insn_not_found (insn);\n");
3860 }
3861
3862 if (write_case_lines)
c1a404bd 3863 write_insn_cases (av->first_insn, indent);
41299f41
TW
3864 else
3865 {
3866 write_indent (indent);
3867 printf ("default:\n");
3868 }
3869
d7c665bf 3870 /* See what we have to do to output this value. */
41299f41
TW
3871 must_extract = must_constrain = address_used = 0;
3872 walk_attr_value (av->value);
3873
d90ffc8d 3874 if (must_constrain)
41299f41
TW
3875 {
3876 write_indent (indent + 2);
d90ffc8d 3877 printf ("extract_constrain_insn_cached (insn);\n");
41299f41 3878 }
d90ffc8d 3879 else if (must_extract)
41299f41 3880 {
41299f41 3881 write_indent (indent + 2);
d90ffc8d 3882 printf ("extract_insn_cached (insn);\n");
41299f41
TW
3883 }
3884
3885 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
1e9c8405
RS
3886 known_true, av->first_insn->def->insn_code,
3887 av->first_insn->def->insn_index);
41299f41
TW
3888
3889 if (strncmp (prefix, "return", 6))
3890 {
3891 write_indent (indent + 2);
3892 printf ("break;\n");
3893 }
3894 printf ("\n");
3895}
16610927 3896
71d9b493
RH
3897/* Search for uses of non-const attributes and write code to cache them. */
3898
3899static int
16610927 3900write_expr_attr_cache (rtx p, struct attr_desc *attr)
71d9b493 3901{
6f7d635c 3902 const char *fmt;
71d9b493
RH
3903 int i, ie, j, je;
3904
3905 if (GET_CODE (p) == EQ_ATTR)
3906 {
3907 if (XSTR (p, 0) != attr->name)
3908 return 0;
3909
3910 if (!attr->is_numeric)
b3694847 3911 printf (" enum attr_%s ", attr->name);
71d9b493 3912 else
b3694847 3913 printf (" int ");
71d9b493
RH
3914
3915 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
3916 return 1;
3917 }
3918
3919 fmt = GET_RTX_FORMAT (GET_CODE (p));
3920 ie = GET_RTX_LENGTH (GET_CODE (p));
3921 for (i = 0; i < ie; i++)
3922 {
3923 switch (*fmt++)
3924 {
3925 case 'e':
3926 if (write_expr_attr_cache (XEXP (p, i), attr))
3927 return 1;
3928 break;
3929
3930 case 'E':
3931 je = XVECLEN (p, i);
3932 for (j = 0; j < je; ++j)
3933 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
3934 return 1;
3935 break;
3936 }
3937 }
3938
3939 return 0;
3940}
3941
fa0aee89 3942/* Utilities to write in various forms. */
6f6074ea 3943
41299f41 3944static void
16610927 3945write_attr_valueq (struct attr_desc *attr, const char *s)
41299f41
TW
3946{
3947 if (attr->is_numeric)
bee757e1 3948 {
6f6074ea
MM
3949 int num = atoi (s);
3950
3951 printf ("%d", num);
3952
fa0aee89 3953 if (num > 9 || num < 0)
6f6074ea 3954 printf (" /* 0x%x */", num);
bee757e1 3955 }
41299f41
TW
3956 else
3957 {
3958 write_upcase (attr->name);
3959 printf ("_");
3960 write_upcase (s);
3961 }
3962}
3963
3964static void
16610927 3965write_attr_value (struct attr_desc *attr, rtx value)
41299f41 3966{
7ee37ba4
RH
3967 int op;
3968
3969 switch (GET_CODE (value))
3970 {
3971 case CONST_STRING:
3972 write_attr_valueq (attr, XSTR (value, 0));
3973 break;
3974
6ef67412
JH
3975 case CONST_INT:
3976 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
3977 break;
3978
7ee37ba4 3979 case SYMBOL_REF:
7445392c 3980 print_c_condition (XSTR (value, 0));
7ee37ba4
RH
3981 break;
3982
3983 case ATTR:
3984 {
75669493 3985 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0);
c9541287 3986 printf ("get_attr_%s (%s)", attr2->name,
7ee37ba4
RH
3987 (attr2->is_const ? "" : "insn"));
3988 }
3989 break;
41299f41 3990
7ee37ba4
RH
3991 case PLUS:
3992 op = '+';
3993 goto do_operator;
3994 case MINUS:
3995 op = '-';
3996 goto do_operator;
3997 case MULT:
3998 op = '*';
3999 goto do_operator;
4000 case DIV:
4001 op = '/';
4002 goto do_operator;
4003 case MOD:
4004 op = '%';
4005 goto do_operator;
4006
4007 do_operator:
4008 write_attr_value (attr, XEXP (value, 0));
4009 putchar (' ');
4010 putchar (op);
4011 putchar (' ');
4012 write_attr_value (attr, XEXP (value, 1));
4013 break;
4014
4015 default:
b2d59f6f 4016 gcc_unreachable ();
7ee37ba4 4017 }
41299f41
TW
4018}
4019
4020static void
16610927 4021write_upcase (const char *str)
41299f41
TW
4022{
4023 while (*str)
c9541287
KH
4024 {
4025 /* The argument of TOUPPER should not have side effects. */
4026 putchar (TOUPPER(*str));
4027 str++;
4028 }
41299f41
TW
4029}
4030
4031static void
16610927 4032write_indent (int indent)
41299f41
TW
4033{
4034 for (; indent > 8; indent -= 8)
4035 printf ("\t");
4036
4037 for (; indent; indent--)
4038 printf (" ");
4039}
16610927 4040
41299f41 4041/* Write a subroutine that is given an insn that requires a delay slot, a
cc2902df 4042 delay slot ordinal, and a candidate insn. It returns nonzero if the
41299f41
TW
4043 candidate can be placed in the specified delay slot of the insn.
4044
4045 We can write as many as three subroutines. `eligible_for_delay'
4046 handles normal delay slots, `eligible_for_annul_true' indicates that
4047 the specified insn can be annulled if the branch is true, and likewise
4048 for `eligible_for_annul_false'.
4049
6dc42e49 4050 KIND is a string distinguishing these three cases ("delay", "annul_true",
41299f41
TW
4051 or "annul_false"). */
4052
4053static void
16610927 4054write_eligible_delay (const char *kind)
41299f41
TW
4055{
4056 struct delay_desc *delay;
4057 int max_slots;
4058 char str[50];
75669493 4059 const char *pstr;
41299f41
TW
4060 struct attr_desc *attr;
4061 struct attr_value *av, *common_av;
4062 int i;
4063
4064 /* Compute the maximum number of delay slots required. We use the delay
4065 ordinal times this number plus one, plus the slot number as an index into
4066 the appropriate predicate to test. */
4067
4068 for (delay = delays, max_slots = 0; delay; delay = delay->next)
4069 if (XVECLEN (delay->def, 1) / 3 > max_slots)
4070 max_slots = XVECLEN (delay->def, 1) / 3;
4071
4072 /* Write function prelude. */
4073
4074 printf ("int\n");
6906ba40 4075 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
c9541287 4076 kind);
41299f41
TW
4077 printf ("{\n");
4078 printf (" rtx insn;\n");
4079 printf ("\n");
1a2caa7a 4080 printf (" gcc_assert (slot < %d);\n", max_slots);
41299f41 4081 printf ("\n");
beed8fc0
AO
4082 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4083 converts a compound instruction into a loop. */
4084 printf (" if (!INSN_P (candidate_insn))\n");
4085 printf (" return 0;\n");
4086 printf ("\n");
41299f41
TW
4087
4088 /* If more than one delay type, find out which type the delay insn is. */
4089
4090 if (num_delays > 1)
4091 {
75669493 4092 attr = find_attr (&delay_type_str, 0);
b2d59f6f 4093 gcc_assert (attr);
41299f41
TW
4094 common_av = find_most_used (attr);
4095
4096 printf (" insn = delay_insn;\n");
4097 printf (" switch (recog_memoized (insn))\n");
4098 printf (" {\n");
4099
4100 sprintf (str, " * %d;\n break;", max_slots);
4101 for (av = attr->first_value; av; av = av->next)
4102 if (av != common_av)
4103 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
4104
4105 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
4106 printf (" }\n\n");
4107
4108 /* Ensure matched. Otherwise, shouldn't have been called. */
b2d59f6f 4109 printf (" gcc_assert (slot >= %d);\n\n", max_slots);
41299f41
TW
4110 }
4111
4112 /* If just one type of delay slot, write simple switch. */
4113 if (num_delays == 1 && max_slots == 1)
4114 {
4115 printf (" insn = candidate_insn;\n");
4116 printf (" switch (recog_memoized (insn))\n");
4117 printf (" {\n");
4118
75669493 4119 attr = find_attr (&delay_1_0_str, 0);
b2d59f6f 4120 gcc_assert (attr);
41299f41
TW
4121 common_av = find_most_used (attr);
4122
4123 for (av = attr->first_value; av; av = av->next)
4124 if (av != common_av)
4125 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4126
4127 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4128 printf (" }\n");
4129 }
4130
4131 else
4132 {
4133 /* Write a nested CASE. The first indicates which condition we need to
4134 test, and the inner CASE tests the condition. */
4135 printf (" insn = candidate_insn;\n");
4136 printf (" switch (slot)\n");
4137 printf (" {\n");
4138
4139 for (delay = delays; delay; delay = delay->next)
4140 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
4141 {
4142 printf (" case %d:\n",
4143 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
4144 printf (" switch (recog_memoized (insn))\n");
4145 printf ("\t{\n");
4146
4147 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
75669493
ZD
4148 pstr = str;
4149 attr = find_attr (&pstr, 0);
b2d59f6f 4150 gcc_assert (attr);
41299f41
TW
4151 common_av = find_most_used (attr);
4152
4153 for (av = attr->first_value; av; av = av->next)
4154 if (av != common_av)
4155 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
4156
4157 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
4158 printf (" }\n");
4159 }
4160
4161 printf (" default:\n");
b2d59f6f 4162 printf (" gcc_unreachable ();\n");
41299f41
TW
4163 printf (" }\n");
4164 }
4165
4166 printf ("}\n\n");
4167}
16610927 4168
41299f41
TW
4169/* This page contains miscellaneous utility routines. */
4170
41299f41
TW
4171/* Given a pointer to a (char *), return a malloc'ed string containing the
4172 next comma-separated element. Advance the pointer to after the string
4173 scanned, or the end-of-string. Return NULL if at end of string. */
4174
4175static char *
16610927 4176next_comma_elt (const char **pstr)
41299f41 4177{
9a5834ae 4178 const char *start;
41299f41 4179
9a5834ae 4180 start = scan_comma_elt (pstr);
41299f41 4181
9a5834ae
ZW
4182 if (start == NULL)
4183 return NULL;
41299f41 4184
9a5834ae 4185 return attr_string (start, *pstr - start);
41299f41
TW
4186}
4187
4188/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
75669493
ZD
4189 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4190 replaced by a pointer to a canonical copy of the string. */
41299f41
TW
4191
4192static struct attr_desc *
75669493 4193find_attr (const char **name_p, int create)
41299f41
TW
4194{
4195 struct attr_desc *attr;
3715a518 4196 int index;
75669493 4197 const char *name = *name_p;
41299f41
TW
4198
4199 /* Before we resort to using `strcmp', see if the string address matches
4200 anywhere. In most cases, it should have been canonicalized to do so. */
4201 if (name == alternative_name)
4202 return NULL;
4203
3715a518
RS
4204 index = name[0] & (MAX_ATTRS_INDEX - 1);
4205 for (attr = attrs[index]; attr; attr = attr->next)
41299f41
TW
4206 if (name == attr->name)
4207 return attr;
4208
4209 /* Otherwise, do it the slow way. */
3715a518 4210 for (attr = attrs[index]; attr; attr = attr->next)
81fd4c6e 4211 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
75669493
ZD
4212 {
4213 *name_p = attr->name;
4214 return attr;
4215 }
41299f41
TW
4216
4217 if (! create)
4218 return NULL;
4219
703ad42b 4220 attr = oballoc (sizeof (struct attr_desc));
75669493 4221 attr->name = DEF_ATTR_STRING (name);
41299f41 4222 attr->first_value = attr->default_val = NULL;
db77171d
KH
4223 attr->is_numeric = attr->is_const = attr->is_special = 0;
4224 attr->static_p = 0;
3715a518
RS
4225 attr->next = attrs[index];
4226 attrs[index] = attr;
41299f41 4227
75669493
ZD
4228 *name_p = attr->name;
4229
41299f41
TW
4230 return attr;
4231}
4232
4233/* Create internal attribute with the given default value. */
4234
fae15c93 4235void
16610927 4236make_internal_attr (const char *name, rtx value, int special)
41299f41
TW
4237{
4238 struct attr_desc *attr;
4239
75669493 4240 attr = find_attr (&name, 1);
b2d59f6f 4241 gcc_assert (!attr->default_val);
41299f41
TW
4242
4243 attr->is_numeric = 1;
3e7b5313 4244 attr->is_const = 0;
11597bc9 4245 attr->is_special = (special & ATTR_SPECIAL) != 0;
ec049fdb 4246 attr->static_p = (special & ATTR_STATIC) != 0;
41299f41
TW
4247 attr->default_val = get_attr_value (value, attr, -2);
4248}
4249
4250/* Find the most used value of an attribute. */
4251
4252static struct attr_value *
16610927 4253find_most_used (struct attr_desc *attr)
41299f41
TW
4254{
4255 struct attr_value *av;
4256 struct attr_value *most_used;
4257 int nuses;
4258
4259 most_used = NULL;
4260 nuses = -1;
4261
4262 for (av = attr->first_value; av; av = av->next)
4263 if (av->num_insns > nuses)
4264 nuses = av->num_insns, most_used = av;
4265
4266 return most_used;
4267}
4268
41299f41
TW
4269/* Return (attr_value "n") */
4270
fae15c93 4271rtx
16610927 4272make_numeric_value (int n)
41299f41
TW
4273{
4274 static rtx int_values[20];
4275 rtx exp;
3e7b5313 4276 char *p;
41299f41 4277
b2d59f6f 4278 gcc_assert (n >= 0);
41299f41
TW
4279
4280 if (n < 20 && int_values[n])
4281 return int_values[n];
4282
0e9414fd 4283 p = attr_printf (MAX_DIGITS, "%d", n);
3e7b5313 4284 exp = attr_rtx (CONST_STRING, p);
41299f41
TW
4285
4286 if (n < 20)
4287 int_values[n] = exp;
4288
4289 return exp;
4290}
16610927 4291
7339c88d 4292static rtx
16610927 4293copy_rtx_unchanging (rtx orig)
7339c88d 4294{
2adc7f12 4295 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
81fd4c6e
RS
4296 return orig;
4297
2adc7f12 4298 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
85093b9c 4299 return orig;
7339c88d
RS
4300}
4301
d7c665bf
RK
4302/* Determine if an insn has a constant number of delay slots, i.e., the
4303 number of delay slots is not a function of the length of the insn. */
4304
69277eec 4305static void
16610927 4306write_const_num_delay_slots (void)
a9ab5e00 4307{
75669493 4308 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0);
a9ab5e00 4309 struct attr_value *av;
a9ab5e00
TM
4310
4311 if (attr)
4312 {
6906ba40 4313 printf ("int\nconst_num_delay_slots (rtx insn)\n");
a9ab5e00
TM
4314 printf ("{\n");
4315 printf (" switch (recog_memoized (insn))\n");
4316 printf (" {\n");
4317
4318 for (av = attr->first_value; av; av = av->next)
d7c665bf
RK
4319 {
4320 length_used = 0;
4321 walk_attr_value (av->value);
4322 if (length_used)
c1a404bd 4323 write_insn_cases (av->first_insn, 4);
d7c665bf
RK
4324 }
4325
a9ab5e00
TM
4326 printf (" default:\n");
4327 printf (" return 1;\n");
fc470718 4328 printf (" }\n}\n\n");
a9ab5e00
TM
4329 }
4330}
c1b59dce 4331
41299f41 4332int
16610927 4333main (int argc, char **argv)
41299f41
TW
4334{
4335 rtx desc;
41299f41 4336 struct attr_desc *attr;
41299f41
TW
4337 struct insn_def *id;
4338 rtx tem;
3715a518 4339 int i;
41299f41 4340
ef178af3
ZW
4341 progname = "genattrtab";
4342
04d8aa70 4343 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
3916d6d8
RH
4344 return (FATAL_EXIT_CODE);
4345
7339c88d 4346 obstack_init (hash_obstack);
81fd4c6e 4347 obstack_init (temp_obstack);
41299f41 4348
41299f41 4349 /* Set up true and false rtx's */
81fd4c6e 4350 true_rtx = rtx_alloc (CONST_INT);
3d678dca 4351 XWINT (true_rtx, 0) = 1;
81fd4c6e 4352 false_rtx = rtx_alloc (CONST_INT);
3d678dca 4353 XWINT (false_rtx, 0) = 0;
2adc7f12
JJ
4354 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
4355 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
81fd4c6e 4356
75669493
ZD
4357 alternative_name = DEF_ATTR_STRING ("alternative");
4358 length_str = DEF_ATTR_STRING ("length");
4359 delay_type_str = DEF_ATTR_STRING ("*delay_type");
4360 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0");
4361 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots");
41299f41
TW
4362
4363 printf ("/* Generated automatically by the program `genattrtab'\n\
4364from the machine description file `md'. */\n\n");
4365
4366 /* Read the machine description. */
4367
fae15c93 4368 initiate_automaton_gen (argc, argv);
41299f41
TW
4369 while (1)
4370 {
a4cad544 4371 int lineno;
41299f41 4372
a4cad544 4373 desc = read_md_rtx (&lineno, &insn_code_number);
c88c0d42
CP
4374 if (desc == NULL)
4375 break;
ede7cd44 4376
c88c0d42 4377 switch (GET_CODE (desc))
41299f41 4378 {
c9541287
KH
4379 case DEFINE_INSN:
4380 case DEFINE_PEEPHOLE:
4381 case DEFINE_ASM_ATTRIBUTES:
4382 gen_insn (desc, lineno);
4383 break;
41299f41 4384
c9541287
KH
4385 case DEFINE_ATTR:
4386 gen_attr (desc, lineno);
4387 break;
41299f41 4388
c9541287
KH
4389 case DEFINE_DELAY:
4390 gen_delay (desc, lineno);
4391 break;
4392
fae15c93
VM
4393 case DEFINE_CPU_UNIT:
4394 gen_cpu_unit (desc);
4395 break;
16610927 4396
fae15c93
VM
4397 case DEFINE_QUERY_CPU_UNIT:
4398 gen_query_cpu_unit (desc);
4399 break;
16610927 4400
fae15c93
VM
4401 case DEFINE_BYPASS:
4402 gen_bypass (desc);
4403 break;
16610927 4404
fae15c93
VM
4405 case EXCLUSION_SET:
4406 gen_excl_set (desc);
4407 break;
16610927 4408
fae15c93
VM
4409 case PRESENCE_SET:
4410 gen_presence_set (desc);
4411 break;
16610927 4412
30028c85
VM
4413 case FINAL_PRESENCE_SET:
4414 gen_final_presence_set (desc);
4415 break;
16610927 4416
fae15c93
VM
4417 case ABSENCE_SET:
4418 gen_absence_set (desc);
4419 break;
16610927 4420
30028c85
VM
4421 case FINAL_ABSENCE_SET:
4422 gen_final_absence_set (desc);
4423 break;
16610927 4424
fae15c93
VM
4425 case DEFINE_AUTOMATON:
4426 gen_automaton (desc);
4427 break;
16610927 4428
fae15c93
VM
4429 case AUTOMATA_OPTION:
4430 gen_automata_option (desc);
4431 break;
16610927 4432
fae15c93
VM
4433 case DEFINE_RESERVATION:
4434 gen_reserv (desc);
4435 break;
16610927 4436
fae15c93
VM
4437 case DEFINE_INSN_RESERVATION:
4438 gen_insn_reserv (desc);
4439 break;
4440
c9541287
KH
4441 default:
4442 break;
41299f41 4443 }
c88c0d42 4444 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
c9541287 4445 insn_index_number++;
41299f41
TW
4446 }
4447
a4cad544
RH
4448 if (have_error)
4449 return FATAL_EXIT_CODE;
4450
c88c0d42
CP
4451 insn_code_number++;
4452
41299f41
TW
4453 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4454 if (! got_define_asm_attributes)
4455 {
4456 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
4457 XVEC (tem, 0) = rtvec_alloc (0);
a4cad544 4458 gen_insn (tem, 0);
41299f41
TW
4459 }
4460
4461 /* Expand DEFINE_DELAY information into new attribute. */
4462 if (num_delays)
4463 expand_delays ();
4464
fa0aee89
PB
4465 /* Build DFA, output some functions and expand DFA information
4466 to new attributes. */
4467 if (num_dfa_decls)
4468 expand_automata ();
41299f41
TW
4469
4470 printf ("#include \"config.h\"\n");
729da3f5 4471 printf ("#include \"system.h\"\n");
4977bab6
ZW
4472 printf ("#include \"coretypes.h\"\n");
4473 printf ("#include \"tm.h\"\n");
41299f41 4474 printf ("#include \"rtl.h\"\n");
6baf1cc8 4475 printf ("#include \"tm_p.h\"\n");
41299f41
TW
4476 printf ("#include \"insn-config.h\"\n");
4477 printf ("#include \"recog.h\"\n");
4478 printf ("#include \"regs.h\"\n");
4479 printf ("#include \"real.h\"\n");
4480 printf ("#include \"output.h\"\n");
4481 printf ("#include \"insn-attr.h\"\n");
114791ea 4482 printf ("#include \"toplev.h\"\n");
2840aebf 4483 printf ("#include \"flags.h\"\n");
2f937369 4484 printf ("#include \"function.h\"\n");
c9541287 4485 printf ("\n");
1ccbefce 4486 printf ("#define operands recog_data.operand\n\n");
41299f41
TW
4487
4488 /* Make `insn_alternatives'. */
703ad42b 4489 insn_alternatives = oballoc (insn_code_number * sizeof (int));
41299f41
TW
4490 for (id = defs; id; id = id->next)
4491 if (id->insn_code >= 0)
4492 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
4493
3715a518 4494 /* Make `insn_n_alternatives'. */
703ad42b 4495 insn_n_alternatives = oballoc (insn_code_number * sizeof (int));
3715a518
RS
4496 for (id = defs; id; id = id->next)
4497 if (id->insn_code >= 0)
4498 insn_n_alternatives[id->insn_code] = id->num_alternatives;
4499
41299f41
TW
4500 /* Prepare to write out attribute subroutines by checking everything stored
4501 away and building the attribute cases. */
4502
4503 check_defs ();
a4cad544 4504
3715a518
RS
4505 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4506 for (attr = attrs[i]; attr; attr = attr->next)
a4cad544
RH
4507 attr->default_val->value
4508 = check_attr_value (attr->default_val->value, attr);
4509
4510 if (have_error)
4511 return FATAL_EXIT_CODE;
4512
4513 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4514 for (attr = attrs[i]; attr; attr = attr->next)
4515 fill_attr (attr);
41299f41
TW
4516
4517 /* Construct extra attributes for `length'. */
4518 make_length_attrs ();
4519
0f41302f 4520 /* Perform any possible optimizations to speed up compilation. */
41299f41
TW
4521 optimize_attrs ();
4522
4523 /* Now write out all the `gen_attr_...' routines. Do these before the
fa0aee89 4524 special routines so that they get defined before they are used. */
41299f41 4525
3715a518
RS
4526 for (i = 0; i < MAX_ATTRS_INDEX; i++)
4527 for (attr = attrs[i]; attr; attr = attr->next)
4528 {
71d9b493 4529 if (! attr->is_special && ! attr->is_const)
d530b07f
VM
4530 {
4531 int insn_alts_p;
4532
4533 insn_alts_p
4534 = (attr->name [0] == '*'
75669493 4535 && strcmp (&attr->name[1], INSN_ALTS_FUNC_NAME) == 0);
d530b07f
VM
4536 if (insn_alts_p)
4537 printf ("\n#if AUTOMATON_ALTS\n");
4538 write_attr_get (attr);
4539 if (insn_alts_p)
4540 printf ("#endif\n\n");
4541 }
3715a518 4542 }
41299f41
TW
4543
4544 /* Write out delay eligibility information, if DEFINE_DELAY present.
4545 (The function to compute the number of delay slots will be written
4546 below.) */
4547 if (num_delays)
4548 {
4549 write_eligible_delay ("delay");
4550 if (have_annul_true)
4551 write_eligible_delay ("annul_true");
4552 if (have_annul_false)
4553 write_eligible_delay ("annul_false");
4554 }
4555
fa0aee89
PB
4556 /* Output code for pipeline hazards recognition based on DFA
4557 (deterministic finite-state automata). */
4558 if (num_dfa_decls)
4559 write_automata ();
41299f41 4560
f9da5064 4561 /* Write out constant delay slot info. */
a9ab5e00
TM
4562 write_const_num_delay_slots ();
4563
fc470718
R
4564 write_length_unit_log ();
4565
41299f41 4566 fflush (stdout);
c1b59dce 4567 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
41299f41 4568}
a995e389
RH
4569
4570/* Define this so we can link with print-rtl.o to get debug_rtx function. */
4571const char *
16610927 4572get_insn_name (int code ATTRIBUTE_UNUSED)
a995e389
RH
4573{
4574 return NULL;
4575}