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