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