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