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