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