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