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