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