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