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