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