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