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