]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genattrtab.c
Test gcov output for functions that use longjmp.
[thirdparty/gcc.git] / gcc / genattrtab.c
CommitLineData
41299f41 1/* Generate code from machine description to compute values of attributes.
d050d723
JL
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 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
41299f41
TW
24 DEFINE_FUNCTION_UNIT definitions.
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
TW
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
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
73 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
74 definitions is to create arbitrarily complex expressions and have the
75 optimization simplify them.
76
77 Once optimization is complete, any required routines and definitions
3e7b5313
TW
78 will be written.
79
80 An optimization that is not yet implemented is to hoist the constant
81 expressions entirely out of the routines and definitions that are written.
82 A way to do this is to iterate over all possible combinations of values
83 for constant attributes and generate a set of functions for that given
84 combination. An initialization function would be written that evaluates
85 the attributes and installs the corresponding set of routines and
3715a518
RS
86 definitions (each would be accessed through a pointer).
87
88 We use the flags in an RTX as follows:
89 `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified
90 independent of the insn code.
91 `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
92 for the insn code currently being processed (see optimize_attrs).
93 `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
72f1215c
TW
94 (see attr_rtx).
95 `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
96 EQ_ATTR rtx is true if !volatil and false if volatil. */
3715a518 97
0d64891c 98#include "hconfig.h"
0b93b64e 99#include "system.h"
41299f41 100#include "rtl.h"
a3770a81 101#include "ggc.h"
c88c0d42 102#include "gensupport.h"
41299f41 103
956d6950
JL
104#ifdef HAVE_SYS_RESOURCE_H
105# include <sys/resource.h>
f0cdf2b2
RK
106#endif
107
31f0534c
RS
108/* We must include obstack.h after <sys/time.h>, to avoid lossage with
109 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
110#include "obstack.h"
f8b6598e 111#include "errors.h"
31f0534c 112
3916d6d8 113static struct obstack obstack1, obstack2;
7339c88d 114struct obstack *hash_obstack = &obstack1;
81fd4c6e 115struct obstack *temp_obstack = &obstack2;
41299f41
TW
116
117#define obstack_chunk_alloc xmalloc
118#define obstack_chunk_free free
119
0e9414fd
MM
120/* enough space to reserve for printing out ints */
121#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
122
41299f41
TW
123/* Define structures used to record attributes and values. */
124
125/* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
126 encountered, we store all the relevant information into a
127 `struct insn_def'. This is done to allow attribute definitions to occur
128 anywhere in the file. */
129
130struct insn_def
131{
0f41302f
MS
132 struct insn_def *next; /* Next insn in chain. */
133 rtx def; /* The DEFINE_... */
a4cad544
RH
134 int insn_code; /* Instruction number. */
135 int insn_index; /* Expression numer in file, for errors. */
136 int lineno; /* Line number. */
41299f41 137 int num_alternatives; /* Number of alternatives. */
0f41302f 138 int vec_idx; /* Index of attribute vector in `def'. */
41299f41
TW
139};
140
141/* Once everything has been read in, we store in each attribute value a list
142 of insn codes that have that value. Here is the structure used for the
143 list. */
144
145struct insn_ent
146{
a4cad544 147 struct insn_ent *next; /* Next in chain. */
41299f41
TW
148 int insn_code; /* Instruction number. */
149 int insn_index; /* Index of definition in file */
a4cad544 150 int lineno; /* Line number. */
41299f41
TW
151};
152
153/* Each value of an attribute (either constant or computed) is assigned a
154 structure which is used as the listhead of the insns that have that
155 value. */
156
157struct attr_value
158{
159 rtx value; /* Value of attribute. */
160 struct attr_value *next; /* Next attribute value in chain. */
161 struct insn_ent *first_insn; /* First insn with this value. */
162 int num_insns; /* Number of insns with this value. */
163 int has_asm_insn; /* True if this value used for `asm' insns */
164};
165
166/* Structure for each attribute. */
167
168struct attr_desc
169{
0f41302f
MS
170 char *name; /* Name of attribute. */
171 struct attr_desc *next; /* Next attribute. */
6f6074ea
MM
172 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
173 unsigned negative_ok : 1; /* Allow negative numeric values. */
174 unsigned unsigned_p : 1; /* Make the output function unsigned int. */
175 unsigned is_const : 1; /* Attribute value constant for each run. */
176 unsigned is_special : 1; /* Don't call `write_attr_set'. */
177 unsigned func_units_p : 1; /* this is the function_units attribute */
178 unsigned blockage_p : 1; /* this is the blockage range function */
0f41302f
MS
179 struct attr_value *first_value; /* First value of this attribute. */
180 struct attr_value *default_val; /* Default value for this attribute. */
a4cad544 181 int lineno; /* Line number. */
41299f41
TW
182};
183
3d678dca
RS
184#define NULL_ATTR (struct attr_desc *) NULL
185
bee757e1
TW
186/* A range of values. */
187
188struct range
189{
190 int min;
191 int max;
192};
193
41299f41
TW
194/* Structure for each DEFINE_DELAY. */
195
196struct delay_desc
197{
198 rtx def; /* DEFINE_DELAY expression. */
0f41302f 199 struct delay_desc *next; /* Next DEFINE_DELAY. */
41299f41 200 int num; /* Number of DEFINE_DELAY, starting at 1. */
a4cad544 201 int lineno; /* Line number. */
41299f41
TW
202};
203
204/* Record information about each DEFINE_FUNCTION_UNIT. */
205
206struct function_unit_op
207{
208 rtx condexp; /* Expression TRUE for applicable insn. */
209 struct function_unit_op *next; /* Next operation for this function unit. */
210 int num; /* Ordinal for this operation type in unit. */
211 int ready; /* Cost until data is ready. */
bee757e1
TW
212 int issue_delay; /* Cost until unit can accept another insn. */
213 rtx conflict_exp; /* Expression TRUE for insns incurring issue delay. */
214 rtx issue_exp; /* Expression computing issue delay. */
a4cad544 215 int lineno; /* Line number. */
41299f41
TW
216};
217
218/* Record information about each function unit mentioned in a
219 DEFINE_FUNCTION_UNIT. */
220
221struct function_unit
222{
3cce094d 223 const char *name; /* Function unit name. */
41299f41
TW
224 struct function_unit *next; /* Next function unit. */
225 int num; /* Ordinal of this unit type. */
226 int multiplicity; /* Number of units of this type. */
227 int simultaneity; /* Maximum number of simultaneous insns
228 on this function unit or 0 if unlimited. */
0f41302f 229 rtx condexp; /* Expression TRUE for insn needing unit. */
41299f41
TW
230 int num_opclasses; /* Number of different operation types. */
231 struct function_unit_op *ops; /* Pointer to first operation type. */
232 int needs_conflict_function; /* Nonzero if a conflict function required. */
bee757e1 233 int needs_blockage_function; /* Nonzero if a blockage function required. */
f75d38a7 234 int needs_range_function; /* Nonzero if blockage range function needed.*/
41299f41 235 rtx default_cost; /* Conflict cost, if constant. */
bee757e1
TW
236 struct range issue_delay; /* Range of issue delay values. */
237 int max_blockage; /* Maximum time an insn blocks the unit. */
a4cad544 238 int first_lineno; /* First seen line number. */
41299f41
TW
239};
240
241/* Listheads of above structures. */
242
3715a518
RS
243/* This one is indexed by the first character of the attribute name. */
244#define MAX_ATTRS_INDEX 256
245static struct attr_desc *attrs[MAX_ATTRS_INDEX];
41299f41
TW
246static struct insn_def *defs;
247static struct delay_desc *delays;
248static struct function_unit *units;
249
f75d38a7
RK
250/* An expression where all the unknown terms are EQ_ATTR tests can be
251 rearranged into a COND provided we can enumerate all possible
252 combinations of the unknown values. The set of combinations become the
253 tests of the COND; the value of the expression given that combination is
254 computed and becomes the corresponding value. To do this, we must be
255 able to enumerate all values for each attribute used in the expression
256 (currently, we give up if we find a numeric attribute).
c9541287 257
f75d38a7
RK
258 If the set of EQ_ATTR tests used in an expression tests the value of N
259 different attributes, the list of all possible combinations can be made
260 by walking the N-dimensional attribute space defined by those
261 attributes. We record each of these as a struct dimension.
262
263 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
264 expression are the same, the will also have the same address. We find
265 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
266 represents the value of an EQ_ATTR node, so once all nodes are marked,
267 they are also given an initial value of FALSE.
268
269 We then separate the set of EQ_ATTR nodes into dimensions for each
270 attribute and put them on the VALUES list. Terms are added as needed by
271 `add_values_to_cover' so that all possible values of the attribute are
272 tested.
273
274 Each dimension also has a current value. This is the node that is
275 currently considered to be TRUE. If this is one of the nodes added by
276 `add_values_to_cover', all the EQ_ATTR tests in the original expression
277 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
278
279 NUM_VALUES is simply the length of the VALUES list and is there for
280 convenience.
281
282 Once the dimensions are created, the algorithm enumerates all possible
283 values and computes the current value of the given expression. */
284
c9541287 285struct dimension
f75d38a7
RK
286{
287 struct attr_desc *attr; /* Attribute for this dimension. */
288 rtx values; /* List of attribute values used. */
289 rtx current_value; /* Position in the list for the TRUE value. */
290 int num_values; /* Length of the values list. */
291};
292
0f41302f 293/* Other variables. */
41299f41
TW
294
295static int insn_code_number;
296static int insn_index_number;
297static int got_define_asm_attributes;
298static int must_extract;
299static int must_constrain;
300static int address_used;
d7c665bf 301static int length_used;
41299f41
TW
302static int num_delays;
303static int have_annul_true, have_annul_false;
71d9b493 304static int num_units, num_unit_opclasses;
1c69865d 305static int num_insn_ents;
41299f41
TW
306
307/* Used as operand to `operate_exp': */
308
71d9b493 309enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
41299f41 310
3715a518
RS
311/* Stores, for each insn code, the number of constraint alternatives. */
312
313static int *insn_n_alternatives;
314
41299f41
TW
315/* Stores, for each insn code, a bitmap that has bits on for each possible
316 alternative. */
317
318static int *insn_alternatives;
319
3715a518
RS
320/* If nonzero, assume that the `alternative' attr has this value.
321 This is the hashed, unique string for the numeral
322 whose value is chosen alternative. */
323
3cce094d 324static const char *current_alternative_string;
3715a518 325
41299f41
TW
326/* Used to simplify expressions. */
327
328static rtx true_rtx, false_rtx;
329
330/* Used to reduce calls to `strcmp' */
331
81fd4c6e 332static char *alternative_name;
41299f41 333
21ca87b8
MS
334/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
335 called. */
336
337int reload_completed = 0;
338
9ec36da5
JL
339/* Some machines test `optimize' in macros called from rtlanal.c, so we need
340 to define it here. */
341
c5afbb49
JL
342int optimize = 0;
343
41299f41
TW
344/* Simplify an expression. Only call the routine if there is something to
345 simplify. */
346#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
3715a518 347 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
41299f41 348 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
c9541287 349
3715a518
RS
350/* Simplify (eq_attr ("alternative") ...)
351 when we are working with a particular alternative. */
352#define SIMPLIFY_ALTERNATIVE(EXP) \
353 if (current_alternative_string \
354 && GET_CODE ((EXP)) == EQ_ATTR \
355 && XSTR ((EXP), 0) == alternative_name) \
356 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
357 ? true_rtx : false_rtx);
358
41299f41
TW
359/* These are referenced by rtlanal.c and hence need to be defined somewhere.
360 They won't actually be used. */
361
5da077de 362rtx global_rtl[GR_MAX];
e5e809f4 363rtx pic_offset_table_rtx;
41299f41 364
a94ae8f5
KG
365static void attr_hash_add_rtx PARAMS ((int, rtx));
366static void attr_hash_add_string PARAMS ((int, char *));
367static rtx attr_rtx PARAMS ((enum rtx_code, ...));
b8ec5764
VM
368static char *attr_printf PARAMS ((int, const char *, ...))
369 ATTRIBUTE_PRINTF_2;
a94ae8f5 370static char *attr_string PARAMS ((const char *, int));
b8ec5764 371static rtx check_attr_test PARAMS ((rtx, int, int));
a94ae8f5 372static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
a4cad544
RH
373static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
374static rtx convert_set_attr PARAMS ((rtx, struct insn_def *));
a94ae8f5 375static void check_defs PARAMS ((void));
71d9b493 376#if 0
a94ae8f5 377static rtx convert_const_symbol_ref PARAMS ((rtx, struct attr_desc *));
71d9b493 378#endif
a94ae8f5
KG
379static rtx make_canonical PARAMS ((struct attr_desc *, rtx));
380static struct attr_value *get_attr_value PARAMS ((rtx, struct attr_desc *, int));
381static rtx copy_rtx_unchanging PARAMS ((rtx));
382static rtx copy_boolean PARAMS ((rtx));
383static void expand_delays PARAMS ((void));
384static rtx operate_exp PARAMS ((enum operator, rtx, rtx));
385static void expand_units PARAMS ((void));
386static rtx simplify_knowing PARAMS ((rtx, rtx));
387static rtx encode_units_mask PARAMS ((rtx));
388static void fill_attr PARAMS ((struct attr_desc *));
5836dc64 389/* dpx2 compiler chokes if we specify the arg types of the args. */
a94ae8f5
KG
390static rtx substitute_address PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
391static void make_length_attrs PARAMS ((void));
392static rtx identity_fn PARAMS ((rtx));
393static rtx zero_fn PARAMS ((rtx));
394static rtx one_fn PARAMS ((rtx));
395static rtx max_fn PARAMS ((rtx));
396static void write_length_unit_log PARAMS ((void));
397static rtx simplify_cond PARAMS ((rtx, int, int));
e9a25f70 398#if 0
a94ae8f5 399static rtx simplify_by_alternatives PARAMS ((rtx, int, int));
e9a25f70 400#endif
a94ae8f5
KG
401static rtx simplify_by_exploding PARAMS ((rtx));
402static int find_and_mark_used_attributes PARAMS ((rtx, rtx *, int *));
403static void unmark_used_attributes PARAMS ((rtx, struct dimension *, int));
404static int add_values_to_cover PARAMS ((struct dimension *));
405static int increment_current_value PARAMS ((struct dimension *, int));
406static rtx test_for_current_value PARAMS ((struct dimension *, int));
407static rtx simplify_with_current_value PARAMS ((rtx, struct dimension *, int));
408static rtx simplify_with_current_value_aux PARAMS ((rtx));
409static void clear_struct_flag PARAMS ((rtx));
410static int count_sub_rtxs PARAMS ((rtx, int));
411static void remove_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
412static void insert_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
413static rtx insert_right_side PARAMS ((enum rtx_code, rtx, rtx, int, int));
414static rtx make_alternative_compare PARAMS ((int));
415static int compute_alternative_mask PARAMS ((rtx, enum rtx_code));
416static rtx evaluate_eq_attr PARAMS ((rtx, rtx, int, int));
417static rtx simplify_and_tree PARAMS ((rtx, rtx *, int, int));
418static rtx simplify_or_tree PARAMS ((rtx, rtx *, int, int));
419static rtx simplify_test_exp PARAMS ((rtx, int, int));
2d515d60 420static rtx simplify_test_exp_in_temp PARAMS ((rtx, int, int));
a94ae8f5 421static void optimize_attrs PARAMS ((void));
a4cad544 422static void gen_attr PARAMS ((rtx, int));
a94ae8f5
KG
423static int count_alternatives PARAMS ((rtx));
424static int compares_alternatives_p PARAMS ((rtx));
425static int contained_in_p PARAMS ((rtx, rtx));
a4cad544
RH
426static void gen_insn PARAMS ((rtx, int));
427static void gen_delay PARAMS ((rtx, int));
428static void gen_unit PARAMS ((rtx, int));
a94ae8f5
KG
429static void write_test_expr PARAMS ((rtx, int));
430static int max_attr_value PARAMS ((rtx, int*));
431static int or_attr_value PARAMS ((rtx, int*));
432static void walk_attr_value PARAMS ((rtx));
433static void write_attr_get PARAMS ((struct attr_desc *));
434static rtx eliminate_known_true PARAMS ((rtx, rtx, int, int));
435static void write_attr_set PARAMS ((struct attr_desc *, int, rtx,
85fda1eb
KG
436 const char *, const char *, rtx,
437 int, int));
a94ae8f5 438static void write_attr_case PARAMS ((struct attr_desc *, struct attr_value *,
85fda1eb 439 int, const char *, const char *, int, rtx));
a94ae8f5 440static void write_unit_name PARAMS ((const char *, int, const char *));
3cce094d 441static void write_attr_valueq PARAMS ((struct attr_desc *, const char *));
a94ae8f5
KG
442static void write_attr_value PARAMS ((struct attr_desc *, rtx));
443static void write_upcase PARAMS ((const char *));
444static void write_indent PARAMS ((int));
445static void write_eligible_delay PARAMS ((const char *));
446static void write_function_unit_info PARAMS ((void));
447static void write_complex_function PARAMS ((struct function_unit *, const char *,
85fda1eb 448 const char *));
a94ae8f5
KG
449static int write_expr_attr_cache PARAMS ((rtx, struct attr_desc *));
450static void write_toplevel_expr PARAMS ((rtx));
451static void write_const_num_delay_slots PARAMS ((void));
3cce094d
KG
452static int n_comma_elts PARAMS ((const char *));
453static char *next_comma_elt PARAMS ((const char **));
a94ae8f5 454static struct attr_desc *find_attr PARAMS ((const char *, int));
b8ec5764 455static void make_internal_attr PARAMS ((const char *, rtx, int));
a94ae8f5
KG
456static struct attr_value *find_most_used PARAMS ((struct attr_desc *));
457static rtx find_single_value PARAMS ((struct attr_desc *));
b8ec5764 458static rtx make_numeric_value PARAMS ((int));
a94ae8f5 459static void extend_range PARAMS ((struct range *, int, int));
3cce094d
KG
460static rtx attr_eq PARAMS ((const char *, const char *));
461static const char *attr_numeral PARAMS ((int));
a94ae8f5
KG
462static int attr_equal_p PARAMS ((rtx, rtx));
463static rtx attr_copy_rtx PARAMS ((rtx));
2bed3391 464static int attr_rtx_cost PARAMS ((rtx));
0e9414fd
MM
465
466#define oballoc(size) obstack_alloc (hash_obstack, size)
41299f41 467\f
3e7b5313
TW
468/* Hash table for sharing RTL and strings. */
469
470/* Each hash table slot is a bucket containing a chain of these structures.
471 Strings are given negative hash codes; RTL expressions are given positive
472 hash codes. */
473
474struct attr_hash
475{
476 struct attr_hash *next; /* Next structure in the bucket. */
477 int hashcode; /* Hash code of this rtx or string. */
478 union
479 {
480 char *str; /* The string (negative hash codes) */
481 rtx rtl; /* or the RTL recorded here. */
482 } u;
483};
484
485/* Now here is the hash table. When recording an RTL, it is added to
486 the slot whose index is the hash code mod the table size. Note
487 that the hash table is used for several kinds of RTL (see attr_rtx)
488 and for strings. While all these live in the same table, they are
489 completely independent, and the hash code is computed differently
490 for each. */
491
492#define RTL_HASH_SIZE 4093
493struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
494
495/* Here is how primitive or already-shared RTL's hash
496 codes are made. */
2e0dd623 497#define RTL_HASH(RTL) ((long) (RTL) & 0777777)
3e7b5313
TW
498
499/* Add an entry to the hash table for RTL with hash code HASHCODE. */
500
501static void
502attr_hash_add_rtx (hashcode, rtl)
503 int hashcode;
504 rtx rtl;
505{
506 register struct attr_hash *h;
507
7339c88d
RS
508 h = (struct attr_hash *) obstack_alloc (hash_obstack,
509 sizeof (struct attr_hash));
3e7b5313
TW
510 h->hashcode = hashcode;
511 h->u.rtl = rtl;
512 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
513 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
514}
515
516/* Add an entry to the hash table for STRING with hash code HASHCODE. */
517
518static void
519attr_hash_add_string (hashcode, str)
520 int hashcode;
521 char *str;
522{
523 register struct attr_hash *h;
524
7339c88d
RS
525 h = (struct attr_hash *) obstack_alloc (hash_obstack,
526 sizeof (struct attr_hash));
3e7b5313
TW
527 h->hashcode = -hashcode;
528 h->u.str = str;
529 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
530 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
531}
532
81fd4c6e
RS
533/* Generate an RTL expression, but avoid duplicates.
534 Set the RTX_INTEGRATED_P flag for these permanent objects.
535
536 In some cases we cannot uniquify; then we return an ordinary
537 impermanent rtx with RTX_INTEGRATED_P clear.
538
539 Args are like gen_rtx, but without the mode:
3e7b5313
TW
540
541 rtx attr_rtx (code, [element1, ..., elementn]) */
542
3e7b5313 543static rtx
a94ae8f5 544attr_rtx VPARAMS ((enum rtx_code code, ...))
3e7b5313 545{
5148a72b 546#ifndef ANSI_PROTOTYPES
3e7b5313 547 enum rtx_code code;
9e1b6503
RK
548#endif
549 va_list p;
3e7b5313 550 register int i; /* Array indices... */
a544cfd2
KG
551 register const char *fmt; /* Current rtx's format... */
552 register rtx rt_val = NULL_RTX;/* RTX to return to caller... */
3e7b5313
TW
553 int hashcode;
554 register struct attr_hash *h;
7339c88d 555 struct obstack *old_obstack = rtl_obstack;
3e7b5313 556
9e1b6503
RK
557 VA_START (p, code);
558
5148a72b 559#ifndef ANSI_PROTOTYPES
3e7b5313 560 code = va_arg (p, enum rtx_code);
9e1b6503 561#endif
3e7b5313
TW
562
563 /* For each of several cases, search the hash table for an existing entry.
564 Use that entry if one is found; otherwise create a new RTL and add it
565 to the table. */
566
567 if (GET_RTX_CLASS (code) == '1')
568 {
569 rtx arg0 = va_arg (p, rtx);
570
81fd4c6e
RS
571 /* A permanent object cannot point to impermanent ones. */
572 if (! RTX_INTEGRATED_P (arg0))
573 {
574 rt_val = rtx_alloc (code);
575 XEXP (rt_val, 0) = arg0;
576 va_end (p);
577 return rt_val;
578 }
579
d98c1e33 580 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
3e7b5313
TW
581 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
582 if (h->hashcode == hashcode
583 && GET_CODE (h->u.rtl) == code
584 && XEXP (h->u.rtl, 0) == arg0)
585 goto found;
586
587 if (h == 0)
588 {
7339c88d 589 rtl_obstack = hash_obstack;
3e7b5313
TW
590 rt_val = rtx_alloc (code);
591 XEXP (rt_val, 0) = arg0;
592 }
593 }
594 else if (GET_RTX_CLASS (code) == 'c'
595 || GET_RTX_CLASS (code) == '2'
596 || GET_RTX_CLASS (code) == '<')
597 {
598 rtx arg0 = va_arg (p, rtx);
599 rtx arg1 = va_arg (p, rtx);
600
81fd4c6e
RS
601 /* A permanent object cannot point to impermanent ones. */
602 if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
603 {
604 rt_val = rtx_alloc (code);
605 XEXP (rt_val, 0) = arg0;
606 XEXP (rt_val, 1) = arg1;
607 va_end (p);
608 return rt_val;
609 }
610
d98c1e33 611 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
3e7b5313
TW
612 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
613 if (h->hashcode == hashcode
614 && GET_CODE (h->u.rtl) == code
615 && XEXP (h->u.rtl, 0) == arg0
616 && XEXP (h->u.rtl, 1) == arg1)
617 goto found;
618
619 if (h == 0)
620 {
7339c88d 621 rtl_obstack = hash_obstack;
3e7b5313
TW
622 rt_val = rtx_alloc (code);
623 XEXP (rt_val, 0) = arg0;
624 XEXP (rt_val, 1) = arg1;
625 }
626 }
627 else if (GET_RTX_LENGTH (code) == 1
628 && GET_RTX_FORMAT (code)[0] == 's')
629 {
770ae6cc 630 char *arg0 = va_arg (p, char *);
3e7b5313 631
81fd4c6e
RS
632 if (code == SYMBOL_REF)
633 arg0 = attr_string (arg0, strlen (arg0));
634
d98c1e33 635 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
3e7b5313
TW
636 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
637 if (h->hashcode == hashcode
638 && GET_CODE (h->u.rtl) == code
639 && XSTR (h->u.rtl, 0) == arg0)
640 goto found;
641
642 if (h == 0)
643 {
7339c88d 644 rtl_obstack = hash_obstack;
3e7b5313
TW
645 rt_val = rtx_alloc (code);
646 XSTR (rt_val, 0) = arg0;
647 }
648 }
649 else if (GET_RTX_LENGTH (code) == 2
650 && GET_RTX_FORMAT (code)[0] == 's'
651 && GET_RTX_FORMAT (code)[1] == 's')
652 {
81fd4c6e
RS
653 char *arg0 = va_arg (p, char *);
654 char *arg1 = va_arg (p, char *);
3e7b5313 655
d98c1e33 656 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
3e7b5313
TW
657 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
658 if (h->hashcode == hashcode
659 && GET_CODE (h->u.rtl) == code
660 && XSTR (h->u.rtl, 0) == arg0
661 && XSTR (h->u.rtl, 1) == arg1)
662 goto found;
663
664 if (h == 0)
665 {
7339c88d 666 rtl_obstack = hash_obstack;
3e7b5313
TW
667 rt_val = rtx_alloc (code);
668 XSTR (rt_val, 0) = arg0;
669 XSTR (rt_val, 1) = arg1;
670 }
671 }
81fd4c6e
RS
672 else if (code == CONST_INT)
673 {
3d678dca 674 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
81fd4c6e 675 if (arg0 == 0)
f0305a2b
KG
676 {
677 va_end (p);
678 return false_rtx;
679 }
81fd4c6e 680 if (arg0 == 1)
f0305a2b
KG
681 {
682 va_end (p);
683 return true_rtx;
684 }
81fd4c6e
RS
685 goto nohash;
686 }
3e7b5313
TW
687 else
688 {
81fd4c6e 689 nohash:
3e7b5313 690 rt_val = rtx_alloc (code); /* Allocate the storage space. */
c9541287 691
3e7b5313
TW
692 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
693 for (i = 0; i < GET_RTX_LENGTH (code); i++)
694 {
695 switch (*fmt++)
696 {
697 case '0': /* Unused field. */
698 break;
699
700 case 'i': /* An integer? */
701 XINT (rt_val, i) = va_arg (p, int);
702 break;
703
3d678dca
RS
704 case 'w': /* A wide integer? */
705 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
706 break;
707
3e7b5313
TW
708 case 's': /* A string? */
709 XSTR (rt_val, i) = va_arg (p, char *);
710 break;
711
712 case 'e': /* An expression? */
713 case 'u': /* An insn? Same except when printing. */
714 XEXP (rt_val, i) = va_arg (p, rtx);
715 break;
716
717 case 'E': /* An RTX vector? */
718 XVEC (rt_val, i) = va_arg (p, rtvec);
719 break;
720
721 default:
c9541287 722 abort ();
3e7b5313
TW
723 }
724 }
725 va_end (p);
726 return rt_val;
727 }
728
7339c88d 729 rtl_obstack = old_obstack;
3e7b5313
TW
730 va_end (p);
731 attr_hash_add_rtx (hashcode, rt_val);
81fd4c6e 732 RTX_INTEGRATED_P (rt_val) = 1;
3e7b5313
TW
733 return rt_val;
734
735 found:
736 va_end (p);
737 return h->u.rtl;
738}
739
740/* Create a new string printed with the printf line arguments into a space
741 of at most LEN bytes:
742
743 rtx attr_printf (len, format, [arg1, ..., argn]) */
744
b8ec5764 745static char *
a94ae8f5 746attr_printf VPARAMS ((register int len, const char *fmt, ...))
3e7b5313 747{
b548dffb 748 char str[256];
3e7b5313 749
ec83eb53
KG
750 VA_OPEN (p, fmt);
751 VA_FIXEDARG (p, int, len);
752 VA_FIXEDARG (p, const char *, fmt);
753
754 if (len > (sizeof(str) - 1)) /* leave room for \0 */
b548dffb
ZW
755 abort ();
756
3e7b5313 757 vsprintf (str, fmt, p);
ec83eb53 758 VA_CLOSE (p);
3e7b5313
TW
759
760 return attr_string (str, strlen (str));
761}
762
69277eec 763static rtx
81fd4c6e 764attr_eq (name, value)
3cce094d 765 const char *name, *value;
81fd4c6e
RS
766{
767 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
768 attr_string (value, strlen (value)));
769}
770
3cce094d 771static const char *
81fd4c6e
RS
772attr_numeral (n)
773 int n;
774{
775 return XSTR (make_numeric_value (n), 0);
776}
777
3e7b5313
TW
778/* Return a permanent (possibly shared) copy of a string STR (not assumed
779 to be null terminated) with LEN bytes. */
780
781static char *
782attr_string (str, len)
85fda1eb 783 const char *str;
3e7b5313
TW
784 int len;
785{
786 register struct attr_hash *h;
787 int hashcode;
788 int i;
789 register char *new_str;
790
791 /* Compute the hash code. */
c9541287 792 hashcode = (len + 1) * 613 + (unsigned) str[0];
3e7b5313 793 for (i = 1; i <= len; i += 2)
c9541287 794 hashcode = ((hashcode * 613) + (unsigned) str[i]);
3e7b5313
TW
795 if (hashcode < 0)
796 hashcode = -hashcode;
797
798 /* Search the table for the string. */
799 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
81fd4c6e 800 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
d45cf215 801 && !strncmp (h->u.str, str, len))
3e7b5313
TW
802 return h->u.str; /* <-- return if found. */
803
804 /* Not found; create a permanent copy and add it to the hash table. */
b31a5831 805 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
4e135bdd 806 memcpy (new_str, str, len);
3e7b5313
TW
807 new_str[len] = '\0';
808 attr_hash_add_string (hashcode, new_str);
809
810 return new_str; /* Return the new string. */
811}
81fd4c6e
RS
812
813/* Check two rtx's for equality of contents,
814 taking advantage of the fact that if both are hashed
815 then they can't be equal unless they are the same object. */
816
69277eec 817static int
81fd4c6e
RS
818attr_equal_p (x, y)
819 rtx x, y;
820{
821 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
822 && rtx_equal_p (x, y)));
823}
824\f
825/* Copy an attribute value expression,
826 descending to all depths, but not copying any
827 permanent hashed subexpressions. */
828
69277eec 829static rtx
81fd4c6e
RS
830attr_copy_rtx (orig)
831 register rtx orig;
832{
833 register rtx copy;
834 register int i, j;
835 register RTX_CODE code;
6f7d635c 836 register const char *format_ptr;
81fd4c6e
RS
837
838 /* No need to copy a permanent object. */
839 if (RTX_INTEGRATED_P (orig))
840 return orig;
841
842 code = GET_CODE (orig);
843
844 switch (code)
845 {
846 case REG:
847 case QUEUED:
848 case CONST_INT:
849 case CONST_DOUBLE:
850 case SYMBOL_REF:
851 case CODE_LABEL:
852 case PC:
853 case CC0:
854 return orig;
e9a25f70
JL
855
856 default:
857 break;
81fd4c6e
RS
858 }
859
860 copy = rtx_alloc (code);
861 PUT_MODE (copy, GET_MODE (orig));
862 copy->in_struct = orig->in_struct;
863 copy->volatil = orig->volatil;
864 copy->unchanging = orig->unchanging;
865 copy->integrated = orig->integrated;
c9541287 866
81fd4c6e
RS
867 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
868
869 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
870 {
871 switch (*format_ptr++)
872 {
873 case 'e':
874 XEXP (copy, i) = XEXP (orig, i);
875 if (XEXP (orig, i) != NULL)
876 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
877 break;
878
879 case 'E':
880 case 'V':
881 XVEC (copy, i) = XVEC (orig, i);
882 if (XVEC (orig, i) != NULL)
883 {
884 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
885 for (j = 0; j < XVECLEN (copy, i); j++)
886 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
887 }
888 break;
889
3d678dca
RS
890 case 'n':
891 case 'i':
81fd4c6e
RS
892 XINT (copy, i) = XINT (orig, i);
893 break;
3d678dca
RS
894
895 case 'w':
896 XWINT (copy, i) = XWINT (orig, i);
897 break;
898
899 case 's':
900 case 'S':
901 XSTR (copy, i) = XSTR (orig, i);
902 break;
903
904 default:
905 abort ();
81fd4c6e
RS
906 }
907 }
908 return copy;
909}
3e7b5313 910\f
41299f41 911/* Given a test expression for an attribute, ensure it is validly formed.
3e7b5313
TW
912 IS_CONST indicates whether the expression is constant for each compiler
913 run (a constant expression may not test any particular insn).
914
41299f41
TW
915 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
916 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
917 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
918
919 Update the string address in EQ_ATTR expression to be the same used
920 in the attribute (or `alternative_name') to speed up subsequent
921 `find_attr' calls and eliminate most `strcmp' calls.
922
923 Return the new expression, if any. */
924
b8ec5764 925static rtx
a4cad544 926check_attr_test (exp, is_const, lineno)
41299f41 927 rtx exp;
3e7b5313 928 int is_const;
a4cad544 929 int lineno;
41299f41
TW
930{
931 struct attr_desc *attr;
932 struct attr_value *av;
3cce094d 933 const char *name_ptr, *p;
41299f41
TW
934 rtx orexp, newexp;
935
936 switch (GET_CODE (exp))
937 {
938 case EQ_ATTR:
939 /* Handle negation test. */
940 if (XSTR (exp, 1)[0] == '!')
3e7b5313 941 return check_attr_test (attr_rtx (NOT,
81fd4c6e
RS
942 attr_eq (XSTR (exp, 0),
943 &XSTR (exp, 1)[1])),
a4cad544 944 is_const, lineno);
41299f41
TW
945
946 else if (n_comma_elts (XSTR (exp, 1)) == 1)
947 {
c114787a 948 attr = find_attr (XSTR (exp, 0), 0);
41299f41
TW
949 if (attr == NULL)
950 {
951 if (! strcmp (XSTR (exp, 0), "alternative"))
952 {
953 XSTR (exp, 0) = alternative_name;
954 /* This can't be simplified any further. */
955 RTX_UNCHANGING_P (exp) = 1;
956 return exp;
957 }
7339c88d 958 else
487a6e06 959 fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
41299f41
TW
960 }
961
3e7b5313
TW
962 if (is_const && ! attr->is_const)
963 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
487a6e06 964 XSTR (exp, 0));
3e7b5313 965
81fd4c6e
RS
966 /* Copy this just to make it permanent,
967 so expressions using it can be permanent too. */
968 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
41299f41 969
f72aed24 970 /* It shouldn't be possible to simplify the value given to a
b31a5831 971 constant attribute, so don't expand this until it's time to
c9541287 972 write the test expression. */
b31a5831
RS
973 if (attr->is_const)
974 RTX_UNCHANGING_P (exp) = 1;
975
41299f41
TW
976 if (attr->is_numeric)
977 {
978 for (p = XSTR (exp, 1); *p; p++)
979 if (*p < '0' || *p > '9')
c9541287
KH
980 fatal ("Attribute `%s' takes only numeric values",
981 XSTR (exp, 0));
41299f41
TW
982 }
983 else
984 {
985 for (av = attr->first_value; av; av = av->next)
986 if (GET_CODE (av->value) == CONST_STRING
987 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
988 break;
989
990 if (av == NULL)
991 fatal ("Unknown value `%s' for `%s' attribute",
487a6e06 992 XSTR (exp, 1), XSTR (exp, 0));
41299f41
TW
993 }
994 }
995 else
996 {
997 /* Make an IOR tree of the possible values. */
998 orexp = false_rtx;
999 name_ptr = XSTR (exp, 1);
1000 while ((p = next_comma_elt (&name_ptr)) != NULL)
1001 {
81fd4c6e 1002 newexp = attr_eq (XSTR (exp, 0), p);
f75d38a7 1003 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
41299f41
TW
1004 }
1005
a4cad544 1006 return check_attr_test (orexp, is_const, lineno);
41299f41
TW
1007 }
1008 break;
1009
0b0316dc
JL
1010 case ATTR_FLAG:
1011 break;
1012
41299f41
TW
1013 case CONST_INT:
1014 /* Either TRUE or FALSE. */
3d678dca 1015 if (XWINT (exp, 0))
41299f41
TW
1016 return true_rtx;
1017 else
1018 return false_rtx;
1019
1020 case IOR:
1021 case AND:
a4cad544
RH
1022 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1023 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
41299f41
TW
1024 break;
1025
1026 case NOT:
a4cad544 1027 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
41299f41
TW
1028 break;
1029
8450a694 1030 case MATCH_INSN:
41299f41 1031 case MATCH_OPERAND:
3e7b5313
TW
1032 if (is_const)
1033 fatal ("RTL operator \"%s\" not valid in constant attribute test",
8450a694 1034 GET_RTX_NAME (GET_CODE (exp)));
81fd4c6e
RS
1035 /* These cases can't be simplified. */
1036 RTX_UNCHANGING_P (exp) = 1;
1037 break;
c9541287 1038
41299f41
TW
1039 case LE: case LT: case GT: case GE:
1040 case LEU: case LTU: case GTU: case GEU:
1041 case NE: case EQ:
81fd4c6e
RS
1042 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1043 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1044 exp = attr_rtx (GET_CODE (exp),
1045 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1046 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
41299f41
TW
1047 /* These cases can't be simplified. */
1048 RTX_UNCHANGING_P (exp) = 1;
1049 break;
1050
3e7b5313
TW
1051 case SYMBOL_REF:
1052 if (is_const)
1053 {
1054 /* These cases are valid for constant attributes, but can't be
1055 simplified. */
81fd4c6e 1056 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
3e7b5313
TW
1057 RTX_UNCHANGING_P (exp) = 1;
1058 break;
1059 }
41299f41
TW
1060 default:
1061 fatal ("RTL operator \"%s\" not valid in attribute test",
1062 GET_RTX_NAME (GET_CODE (exp)));
1063 }
1064
1065 return exp;
1066}
1067\f
1068/* Given an expression, ensure that it is validly formed and that all named
1069 attribute values are valid for the given attribute. Issue a fatal error
81fd4c6e 1070 if not. If no attribute is specified, assume a numeric attribute.
41299f41 1071
81fd4c6e
RS
1072 Return a perhaps modified replacement expression for the value. */
1073
1074static rtx
41299f41
TW
1075check_attr_value (exp, attr)
1076 rtx exp;
1077 struct attr_desc *attr;
1078{
1079 struct attr_value *av;
3cce094d 1080 const char *p;
41299f41
TW
1081 int i;
1082
1083 switch (GET_CODE (exp))
1084 {
1085 case CONST_INT:
1086 if (attr && ! attr->is_numeric)
a4cad544
RH
1087 {
1088 message_with_line (attr->lineno,
1089 "CONST_INT not valid for non-numeric attribute %s",
1090 attr->name);
1091 have_error = 1;
1092 break;
1093 }
41299f41 1094
7ee37ba4 1095 if (INTVAL (exp) < 0 && ! attr->negative_ok)
a4cad544
RH
1096 {
1097 message_with_line (attr->lineno,
c9541287
KH
1098 "negative numeric value specified for attribute %s",
1099 attr->name);
a4cad544
RH
1100 have_error = 1;
1101 break;
1102 }
41299f41
TW
1103 break;
1104
1105 case CONST_STRING:
1106 if (! strcmp (XSTR (exp, 0), "*"))
1107 break;
1108
1109 if (attr == 0 || attr->is_numeric)
1110 {
72f1215c
TW
1111 p = XSTR (exp, 0);
1112 if (attr && attr->negative_ok && *p == '-')
1113 p++;
1114 for (; *p; p++)
41299f41 1115 if (*p > '9' || *p < '0')
a4cad544
RH
1116 {
1117 message_with_line (attr ? attr->lineno : 0,
1118 "non-numeric value for numeric attribute %s",
1119 attr ? attr->name : "internal");
1120 have_error = 1;
1121 break;
1122 }
41299f41
TW
1123 break;
1124 }
1125
1126 for (av = attr->first_value; av; av = av->next)
1127 if (GET_CODE (av->value) == CONST_STRING
1128 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1129 break;
1130
1131 if (av == NULL)
a4cad544
RH
1132 {
1133 message_with_line (attr->lineno,
1134 "unknown value `%s' for `%s' attribute",
1135 XSTR (exp, 0), attr ? attr->name : "internal");
1136 have_error = 1;
1137 }
81fd4c6e 1138 break;
41299f41
TW
1139
1140 case IF_THEN_ELSE:
3e7b5313 1141 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
a4cad544
RH
1142 attr ? attr->is_const : 0,
1143 attr ? attr->lineno : 0);
81fd4c6e
RS
1144 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1145 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1146 break;
41299f41 1147
7ee37ba4
RH
1148 case PLUS:
1149 case MINUS:
1150 case MULT:
1151 case DIV:
1152 case MOD:
1153 if (attr && !attr->is_numeric)
a4cad544
RH
1154 {
1155 message_with_line (attr->lineno,
c9541287
KH
1156 "invalid operation `%s' for non-numeric attribute value",
1157 GET_RTX_NAME (GET_CODE (exp)));
a4cad544
RH
1158 have_error = 1;
1159 break;
1160 }
7ee37ba4
RH
1161 /* FALLTHRU */
1162
71d9b493
RH
1163 case IOR:
1164 case AND:
1165 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1166 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1167 break;
1168
1169 case FFS:
1170 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1171 break;
1172
41299f41
TW
1173 case COND:
1174 if (XVECLEN (exp, 0) % 2 != 0)
a4cad544
RH
1175 {
1176 message_with_line (attr->lineno,
1177 "first operand of COND must have even length");
1178 have_error = 1;
1179 break;
1180 }
41299f41
TW
1181
1182 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1183 {
3e7b5313 1184 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
a4cad544
RH
1185 attr ? attr->is_const : 0,
1186 attr ? attr->lineno : 0);
81fd4c6e
RS
1187 XVECEXP (exp, 0, i + 1)
1188 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
41299f41
TW
1189 }
1190
81fd4c6e
RS
1191 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1192 break;
41299f41 1193
7ee37ba4
RH
1194 case ATTR:
1195 {
1196 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
1197 if (attr2 == NULL)
a4cad544
RH
1198 {
1199 message_with_line (attr ? attr->lineno : 0,
1200 "unknown attribute `%s' in ATTR",
1201 XSTR (exp, 0));
1202 have_error = 1;
1203 }
1204 else if (attr && attr->is_const && ! attr2->is_const)
1205 {
1206 message_with_line (attr->lineno,
1207 "non-constant attribute `%s' referenced from `%s'",
1208 XSTR (exp, 0), attr->name);
1209 have_error = 1;
1210 }
c9541287 1211 else if (attr
7ee37ba4
RH
1212 && (attr->is_numeric != attr2->is_numeric
1213 || (! attr->negative_ok && attr2->negative_ok)))
a4cad544
RH
1214 {
1215 message_with_line (attr->lineno,
1216 "numeric attribute mismatch calling `%s' from `%s'",
1217 XSTR (exp, 0), attr->name);
1218 have_error = 1;
1219 }
7ee37ba4
RH
1220 }
1221 break;
1222
3e7b5313 1223 case SYMBOL_REF:
7ee37ba4
RH
1224 /* A constant SYMBOL_REF is valid as a constant attribute test and
1225 is expanded later by make_canonical into a COND. In a non-constant
1226 attribute test, it is left be. */
1227 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
3e7b5313 1228
41299f41 1229 default:
a4cad544
RH
1230 message_with_line (attr ? attr->lineno : 0,
1231 "invalid operation `%s' for attribute value",
1232 GET_RTX_NAME (GET_CODE (exp)));
1233 have_error = 1;
1234 break;
41299f41 1235 }
81fd4c6e
RS
1236
1237 return exp;
41299f41
TW
1238}
1239\f
1240/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1241 It becomes a COND with each test being (eq_attr "alternative "n") */
1242
1243static rtx
a4cad544 1244convert_set_attr_alternative (exp, id)
41299f41 1245 rtx exp;
a4cad544 1246 struct insn_def *id;
41299f41 1247{
a4cad544 1248 int num_alt = id->num_alternatives;
41299f41
TW
1249 rtx condexp;
1250 int i;
1251
1252 if (XVECLEN (exp, 1) != num_alt)
a4cad544
RH
1253 {
1254 message_with_line (id->lineno,
c9541287 1255 "bad number of entries in SET_ATTR_ALTERNATIVE");
a4cad544
RH
1256 have_error = 1;
1257 return NULL_RTX;
1258 }
41299f41
TW
1259
1260 /* Make a COND with all tests but the last. Select the last value via the
1261 default. */
1262 condexp = rtx_alloc (COND);
1263 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1264
1265 for (i = 0; i < num_alt - 1; i++)
1266 {
3cce094d 1267 const char *p;
81fd4c6e 1268 p = attr_numeral (i);
3e7b5313 1269
81fd4c6e 1270 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
41299f41
TW
1271 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1272 }
1273
1274 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1275
3e7b5313 1276 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
41299f41
TW
1277}
1278\f
1279/* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1280 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1281
1282static rtx
a4cad544 1283convert_set_attr (exp, id)
41299f41 1284 rtx exp;
a4cad544 1285 struct insn_def *id;
41299f41
TW
1286{
1287 rtx newexp;
3cce094d 1288 const char *name_ptr;
41299f41
TW
1289 char *p;
1290 int n;
1291
1292 /* See how many alternative specified. */
1293 n = n_comma_elts (XSTR (exp, 1));
1294 if (n == 1)
3e7b5313
TW
1295 return attr_rtx (SET,
1296 attr_rtx (ATTR, XSTR (exp, 0)),
1297 attr_rtx (CONST_STRING, XSTR (exp, 1)));
41299f41
TW
1298
1299 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1300 XSTR (newexp, 0) = XSTR (exp, 0);
1301 XVEC (newexp, 1) = rtvec_alloc (n);
1302
1303 /* Process each comma-separated name. */
1304 name_ptr = XSTR (exp, 1);
1305 n = 0;
1306 while ((p = next_comma_elt (&name_ptr)) != NULL)
3e7b5313 1307 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
41299f41 1308
a4cad544 1309 return convert_set_attr_alternative (newexp, id);
41299f41
TW
1310}
1311\f
1312/* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1313 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
0f41302f 1314 expressions. */
41299f41
TW
1315
1316static void
1317check_defs ()
1318{
1319 struct insn_def *id;
1320 struct attr_desc *attr;
1321 int i;
1322 rtx value;
1323
1324 for (id = defs; id; id = id->next)
1325 {
1326 if (XVEC (id->def, id->vec_idx) == NULL)
1327 continue;
1328
1329 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1330 {
1331 value = XVECEXP (id->def, id->vec_idx, i);
1332 switch (GET_CODE (value))
1333 {
1334 case SET:
1335 if (GET_CODE (XEXP (value, 0)) != ATTR)
a4cad544
RH
1336 {
1337 message_with_line (id->lineno, "bad attribute set");
1338 have_error = 1;
1339 value = NULL_RTX;
1340 }
41299f41
TW
1341 break;
1342
1343 case SET_ATTR_ALTERNATIVE:
a4cad544 1344 value = convert_set_attr_alternative (value, id);
41299f41
TW
1345 break;
1346
1347 case SET_ATTR:
a4cad544 1348 value = convert_set_attr (value, id);
41299f41
TW
1349 break;
1350
1351 default:
a4cad544
RH
1352 message_with_line (id->lineno, "invalid attribute code %s",
1353 GET_RTX_NAME (GET_CODE (value)));
1354 have_error = 1;
1355 value = NULL_RTX;
41299f41 1356 }
a4cad544
RH
1357 if (value == NULL_RTX)
1358 continue;
41299f41
TW
1359
1360 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
a4cad544
RH
1361 {
1362 message_with_line (id->lineno, "unknown attribute %s",
1363 XSTR (XEXP (value, 0), 0));
1364 have_error = 1;
1365 continue;
1366 }
41299f41
TW
1367
1368 XVECEXP (id->def, id->vec_idx, i) = value;
81fd4c6e 1369 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
41299f41
TW
1370 }
1371 }
1372}
1373\f
71d9b493 1374#if 0
3e7b5313
TW
1375/* Given a constant SYMBOL_REF expression, convert to a COND that
1376 explicitly tests each enumerated value. */
1377
1378static rtx
1379convert_const_symbol_ref (exp, attr)
1380 rtx exp;
1381 struct attr_desc *attr;
1382{
1383 rtx condexp;
1384 struct attr_value *av;
1385 int i;
1386 int num_alt = 0;
1387
1388 for (av = attr->first_value; av; av = av->next)
1389 num_alt++;
1390
1391 /* Make a COND with all tests but the last, and in the original order.
1392 Select the last value via the default. Note that the attr values
1393 are constructed in reverse order. */
1394
1395 condexp = rtx_alloc (COND);
1396 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1397 av = attr->first_value;
1398 XEXP (condexp, 1) = av->value;
1399
1400 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1401 {
81fd4c6e 1402 char *p, *string;
3e7b5313
TW
1403 rtx value;
1404
0e9414fd 1405 string = p = (char *) oballoc (2
81fd4c6e
RS
1406 + strlen (attr->name)
1407 + strlen (XSTR (av->value, 0)));
3e7b5313
TW
1408 strcpy (p, attr->name);
1409 strcat (p, "_");
1410 strcat (p, XSTR (av->value, 0));
1411 for (; *p != '\0'; p++)
92a438d1 1412 *p = TOUPPER (*p);
3e7b5313 1413
81fd4c6e
RS
1414 value = attr_rtx (SYMBOL_REF, string);
1415 RTX_UNCHANGING_P (value) = 1;
c9541287 1416
3715a518 1417 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
81fd4c6e 1418
3e7b5313
TW
1419 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1420 }
1421
1422 return condexp;
1423}
71d9b493 1424#endif
3e7b5313 1425\f
41299f41
TW
1426/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1427 expressions by converting them into a COND. This removes cases from this
1428 program. Also, replace an attribute value of "*" with the default attribute
1429 value. */
1430
1431static rtx
1432make_canonical (attr, exp)
1433 struct attr_desc *attr;
1434 rtx exp;
1435{
1436 int i;
1437 rtx newexp;
1438
1439 switch (GET_CODE (exp))
1440 {
1441 case CONST_INT:
1442 exp = make_numeric_value (INTVAL (exp));
1443 break;
1444
1445 case CONST_STRING:
1446 if (! strcmp (XSTR (exp, 0), "*"))
1447 {
1448 if (attr == 0 || attr->default_val == 0)
1449 fatal ("(attr_value \"*\") used in invalid context.");
1450 exp = attr->default_val->value;
1451 }
1452
1453 break;
1454
3e7b5313
TW
1455 case SYMBOL_REF:
1456 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1457 break;
3715a518
RS
1458 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1459 This makes the COND something that won't be considered an arbitrary
1460 expression by walk_attr_value. */
1461 RTX_UNCHANGING_P (exp) = 1;
71d9b493
RH
1462#if 0
1463 /* ??? Why do we do this? With attribute values { A B C D E }, this
1464 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
c9541287 1465 than (x==E). */
3e7b5313 1466 exp = convert_const_symbol_ref (exp, attr);
052aaaef 1467 RTX_UNCHANGING_P (exp) = 1;
81fd4c6e 1468 exp = check_attr_value (exp, attr);
3e7b5313 1469 /* Goto COND case since this is now a COND. Note that while the
956d6950 1470 new expression is rescanned, all symbol_ref notes are marked as
3e7b5313
TW
1471 unchanging. */
1472 goto cond;
71d9b493
RH
1473#else
1474 exp = check_attr_value (exp, attr);
1475 break;
1476#endif
3e7b5313 1477
41299f41
TW
1478 case IF_THEN_ELSE:
1479 newexp = rtx_alloc (COND);
1480 XVEC (newexp, 0) = rtvec_alloc (2);
1481 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1482 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1483
1484 XEXP (newexp, 1) = XEXP (exp, 2);
1485
1486 exp = newexp;
1487 /* Fall through to COND case since this is now a COND. */
1488
1489 case COND:
7339c88d
RS
1490 {
1491 int allsame = 1;
1492 rtx defval;
41299f41 1493
0f41302f 1494 /* First, check for degenerate COND. */
7339c88d
RS
1495 if (XVECLEN (exp, 0) == 0)
1496 return make_canonical (attr, XEXP (exp, 1));
1497 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
41299f41 1498
7339c88d
RS
1499 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1500 {
81fd4c6e 1501 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
7339c88d
RS
1502 XVECEXP (exp, 0, i + 1)
1503 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1504 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1505 allsame = 0;
1506 }
1507 if (allsame)
1508 return defval;
7339c88d 1509 }
e9a25f70
JL
1510 break;
1511
1512 default:
1513 break;
41299f41
TW
1514 }
1515
1516 return exp;
1517}
81fd4c6e
RS
1518
1519static rtx
1520copy_boolean (exp)
1521 rtx exp;
1522{
1523 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1524 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1525 copy_boolean (XEXP (exp, 1)));
1526 return exp;
1527}
41299f41
TW
1528\f
1529/* Given a value and an attribute description, return a `struct attr_value *'
1530 that represents that value. This is either an existing structure, if the
1531 value has been previously encountered, or a newly-created structure.
1532
1533 `insn_code' is the code of an insn whose attribute has the specified
1534 value (-2 if not processing an insn). We ensure that all insns for
1535 a given value have the same number of alternatives if the value checks
1536 alternatives. */
1537
1538static struct attr_value *
1539get_attr_value (value, attr, insn_code)
1540 rtx value;
1541 struct attr_desc *attr;
1542 int insn_code;
1543{
1544 struct attr_value *av;
1545 int num_alt = 0;
1546
1547 value = make_canonical (attr, value);
1548 if (compares_alternatives_p (value))
1549 {
1550 if (insn_code < 0 || insn_alternatives == NULL)
1551 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1552 else
1553 num_alt = insn_alternatives[insn_code];
1554 }
1555
1556 for (av = attr->first_value; av; av = av->next)
1557 if (rtx_equal_p (value, av->value)
1558 && (num_alt == 0 || av->first_insn == NULL
1559 || insn_alternatives[av->first_insn->insn_code]))
1560 return av;
1561
0e9414fd 1562 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
41299f41
TW
1563 av->value = value;
1564 av->next = attr->first_value;
1565 attr->first_value = av;
1566 av->first_insn = NULL;
1567 av->num_insns = 0;
1568 av->has_asm_insn = 0;
1569
1570 return av;
1571}
1572\f
1573/* After all DEFINE_DELAYs have been read in, create internal attributes
1574 to generate the required routines.
1575
1576 First, we compute the number of delay slots for each insn (as a COND of
1577 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1578 delay type is specified, we compute a similar function giving the
1579 DEFINE_DELAY ordinal for each insn.
1580
1581 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1582 tells whether a given insn can be in that delay slot.
1583
6dc42e49 1584 Normal attribute filling and optimization expands these to contain the
41299f41
TW
1585 information needed to handle delay slots. */
1586
1587static void
1588expand_delays ()
1589{
1590 struct delay_desc *delay;
1591 rtx condexp;
1592 rtx newexp;
1593 int i;
1594 char *p;
1595
1596 /* First, generate data for `num_delay_slots' function. */
1597
1598 condexp = rtx_alloc (COND);
1599 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1600 XEXP (condexp, 1) = make_numeric_value (0);
1601
1602 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1603 {
1604 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1605 XVECEXP (condexp, 0, i + 1)
1606 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1607 }
1608
1609 make_internal_attr ("*num_delay_slots", condexp, 0);
1610
1611 /* If more than one delay type, do the same for computing the delay type. */
1612 if (num_delays > 1)
1613 {
1614 condexp = rtx_alloc (COND);
1615 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1616 XEXP (condexp, 1) = make_numeric_value (0);
1617
1618 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1619 {
1620 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1621 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1622 }
1623
1624 make_internal_attr ("*delay_type", condexp, 1);
1625 }
1626
6dc42e49
RS
1627 /* For each delay possibility and delay slot, compute an eligibility
1628 attribute for non-annulled insns and for each type of annulled (annul
41299f41 1629 if true and annul if false). */
c9541287
KH
1630 for (delay = delays; delay; delay = delay->next)
1631 {
1632 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1633 {
1634 condexp = XVECEXP (delay->def, 1, i);
1635 if (condexp == 0)
1636 condexp = false_rtx;
1637 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1638 make_numeric_value (1), make_numeric_value (0));
1639
1640 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS * 2,
1641 "*delay_%d_%d",
1642 delay->num, i / 3);
1643 make_internal_attr (p, newexp, 1);
1644
1645 if (have_annul_true)
1646 {
1647 condexp = XVECEXP (delay->def, 1, i + 1);
1648 if (condexp == 0) condexp = false_rtx;
1649 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1650 make_numeric_value (1),
1651 make_numeric_value (0));
1652 p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS * 2,
1653 "*annul_true_%d_%d", delay->num, i / 3);
1654 make_internal_attr (p, newexp, 1);
1655 }
1656
1657 if (have_annul_false)
1658 {
1659 condexp = XVECEXP (delay->def, 1, i + 2);
1660 if (condexp == 0) condexp = false_rtx;
1661 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1662 make_numeric_value (1),
1663 make_numeric_value (0));
1664 p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS * 2,
1665 "*annul_false_%d_%d", delay->num, i / 3);
1666 make_internal_attr (p, newexp, 1);
1667 }
1668 }
1669 }
41299f41
TW
1670}
1671\f
1672/* This function is given a left and right side expression and an operator.
1673 Each side is a conditional expression, each alternative of which has a
1674 numerical value. The function returns another conditional expression
1675 which, for every possible set of condition values, returns a value that is
1676 the operator applied to the values of the two sides.
1677
1678 Since this is called early, it must also support IF_THEN_ELSE. */
1679
1680static rtx
1681operate_exp (op, left, right)
1682 enum operator op;
1683 rtx left, right;
1684{
1685 int left_value, right_value;
1686 rtx newexp;
1687 int i;
1688
1689 /* If left is a string, apply operator to it and the right side. */
1690 if (GET_CODE (left) == CONST_STRING)
1691 {
1692 /* If right is also a string, just perform the operation. */
1693 if (GET_CODE (right) == CONST_STRING)
1694 {
1695 left_value = atoi (XSTR (left, 0));
1696 right_value = atoi (XSTR (right, 0));
1697 switch (op)
1698 {
1699 case PLUS_OP:
1700 i = left_value + right_value;
1701 break;
1702
1703 case MINUS_OP:
1704 i = left_value - right_value;
1705 break;
1706
bee757e1
TW
1707 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1708 if (left_value > right_value)
1709 i = left_value - right_value;
1710 else
1711 i = 0;
1712 break;
1713
41299f41 1714 case OR_OP:
71d9b493 1715 case ORX_OP:
41299f41
TW
1716 i = left_value | right_value;
1717 break;
1718
bee757e1
TW
1719 case EQ_OP:
1720 i = left_value == right_value;
1721 break;
1722
1723 case RANGE_OP:
1724 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1725 break;
1726
41299f41
TW
1727 case MAX_OP:
1728 if (left_value > right_value)
1729 i = left_value;
1730 else
1731 i = right_value;
1732 break;
1733
bee757e1
TW
1734 case MIN_OP:
1735 if (left_value < right_value)
1736 i = left_value;
1737 else
1738 i = right_value;
1739 break;
1740
41299f41
TW
1741 default:
1742 abort ();
1743 }
1744
71d9b493
RH
1745 if (i == left_value)
1746 return left;
1747 if (i == right_value)
1748 return right;
41299f41
TW
1749 return make_numeric_value (i);
1750 }
1751 else if (GET_CODE (right) == IF_THEN_ELSE)
1752 {
1753 /* Apply recursively to all values within. */
7339c88d
RS
1754 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1755 rtx newright = operate_exp (op, left, XEXP (right, 2));
1756 if (rtx_equal_p (newleft, newright))
1757 return newleft;
1758 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
41299f41
TW
1759 }
1760 else if (GET_CODE (right) == COND)
1761 {
7339c88d
RS
1762 int allsame = 1;
1763 rtx defval;
1764
41299f41
TW
1765 newexp = rtx_alloc (COND);
1766 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
7339c88d
RS
1767 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1768
41299f41
TW
1769 for (i = 0; i < XVECLEN (right, 0); i += 2)
1770 {
1771 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1772 XVECEXP (newexp, 0, i + 1)
1773 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
7339c88d 1774 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
c9541287 1775 defval))
7339c88d 1776 allsame = 0;
41299f41
TW
1777 }
1778
7339c88d
RS
1779 /* If the resulting cond is trivial (all alternatives
1780 give the same value), optimize it away. */
1781 if (allsame)
1f8f4a0b 1782 return operate_exp (op, left, XEXP (right, 1));
41299f41
TW
1783
1784 return newexp;
1785 }
1786 else
1787 fatal ("Badly formed attribute value");
1788 }
1789
71d9b493
RH
1790 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1791 not associate through IF_THEN_ELSE. */
1792 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1793 {
1794 return attr_rtx (IOR, left, right);
1795 }
1796
41299f41
TW
1797 /* Otherwise, do recursion the other way. */
1798 else if (GET_CODE (left) == IF_THEN_ELSE)
1799 {
7339c88d
RS
1800 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1801 rtx newright = operate_exp (op, XEXP (left, 2), right);
1802 if (rtx_equal_p (newleft, newright))
1803 return newleft;
1804 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
41299f41 1805 }
41299f41
TW
1806 else if (GET_CODE (left) == COND)
1807 {
7339c88d
RS
1808 int allsame = 1;
1809 rtx defval;
1810
41299f41
TW
1811 newexp = rtx_alloc (COND);
1812 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
7339c88d
RS
1813 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1814
41299f41
TW
1815 for (i = 0; i < XVECLEN (left, 0); i += 2)
1816 {
1817 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1818 XVECEXP (newexp, 0, i + 1)
1819 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
7339c88d 1820 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
c9541287 1821 defval))
7339c88d 1822 allsame = 0;
41299f41
TW
1823 }
1824
7339c88d
RS
1825 /* If the cond is trivial (all alternatives give the same value),
1826 optimize it away. */
1827 if (allsame)
1f8f4a0b 1828 return operate_exp (op, XEXP (left, 1), right);
7339c88d
RS
1829
1830 /* If the result is the same as the LEFT operand,
1831 just use that. */
1832 if (rtx_equal_p (newexp, left))
1f8f4a0b 1833 return left;
41299f41
TW
1834
1835 return newexp;
1836 }
1837
1838 else
1839 fatal ("Badly formed attribute value.");
1840 /* NOTREACHED */
1841 return NULL;
1842}
1843\f
1844/* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1845 construct a number of attributes.
1846
1847 The first produces a function `function_units_used' which is given an
72f1215c
TW
1848 insn and produces an encoding showing which function units are required
1849 for the execution of that insn. If the value is non-negative, the insn
1850 uses that unit; otherwise, the value is a one's compliment mask of units
1851 used.
41299f41
TW
1852
1853 The second produces a function `result_ready_cost' which is used to
1854 determine the time that the result of an insn will be ready and hence
1855 a worst-case schedule.
1856
1857 Both of these produce quite complex expressions which are then set as the
1858 default value of internal attributes. Normal attribute simplification
1859 should produce reasonable expressions.
1860
1861 For each unit, a `<name>_unit_ready_cost' function will take an
1862 insn and give the delay until that unit will be ready with the result
72f1215c 1863 and a `<name>_unit_conflict_cost' function is given an insn already
41299f41
TW
1864 executing on the unit and a candidate to execute and will give the
1865 cost from the time the executing insn started until the candidate
bee757e1
TW
1866 can start (ignore limitations on the number of simultaneous insns).
1867
1868 For each unit, a `<name>_unit_blockage' function is given an insn
1869 already executing on the unit and a candidate to execute and will
1870 give the delay incurred due to function unit conflicts. The range of
1871 blockage cost values for a given executing insn is given by the
1872 `<name>_unit_blockage_range' function. These values are encoded in
1873 an int where the upper half gives the minimum value and the lower
1874 half gives the maximum value. */
41299f41
TW
1875
1876static void
1877expand_units ()
1878{
72f1215c
TW
1879 struct function_unit *unit, **unit_num;
1880 struct function_unit_op *op, **op_array, ***unit_ops;
41299f41
TW
1881 rtx unitsmask;
1882 rtx readycost;
1883 rtx newexp;
85fda1eb 1884 const char *str;
72f1215c 1885 int i, j, u, num, nvalues;
41299f41 1886
bee757e1
TW
1887 /* Rebuild the condition for the unit to share the RTL expressions.
1888 Sharing is required by simplify_by_exploding. Build the issue delay
1889 expressions. Validate the expressions we were given for the conditions
1890 and conflict vector. Then make attributes for use in the conflict
1891 function. */
1892
72f1215c 1893 for (unit = units; unit; unit = unit->next)
bee757e1 1894 {
a4cad544 1895 unit->condexp = check_attr_test (unit->condexp, 0, unit->first_lineno);
bee757e1
TW
1896
1897 for (op = unit->ops; op; op = op->next)
1898 {
1899 rtx issue_delay = make_numeric_value (op->issue_delay);
1900 rtx issue_exp = issue_delay;
1901
1902 /* Build, validate, and simplify the issue delay expression. */
1903 if (op->conflict_exp != true_rtx)
1904 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1905 issue_exp, make_numeric_value (0));
1906 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1907 issue_exp),
72f1215c 1908 NULL_ATTR);
bee757e1
TW
1909 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1910 op->issue_exp = issue_exp;
1911
1912 /* Make an attribute for use in the conflict function if needed. */
1913 unit->needs_conflict_function = (unit->issue_delay.min
1914 != unit->issue_delay.max);
1915 if (unit->needs_conflict_function)
1916 {
0e9414fd
MM
1917 str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1918 "*%s_cost_%d", unit->name, op->num);
bee757e1
TW
1919 make_internal_attr (str, issue_exp, 1);
1920 }
1921
1922 /* Validate the condition. */
a4cad544 1923 op->condexp = check_attr_test (op->condexp, 0, op->lineno);
bee757e1
TW
1924 }
1925 }
41299f41 1926
72f1215c
TW
1927 /* Compute the mask of function units used. Initially, the unitsmask is
1928 zero. Set up a conditional to compute each unit's contribution. */
1929 unitsmask = make_numeric_value (0);
41299f41
TW
1930 newexp = rtx_alloc (IF_THEN_ELSE);
1931 XEXP (newexp, 2) = make_numeric_value (0);
1932
71d9b493
RH
1933 /* If we have just a few units, we may be all right expanding the whole
1934 thing. But the expansion is 2**N in space on the number of opclasses,
1935 so we can't do this for very long -- Alpha and MIPS in particular have
1936 problems with this. So in that situation, we fall back on an alternate
1937 implementation method. */
1938#define NUM_UNITOP_CUTOFF 20
1939
1940 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
72f1215c 1941 {
71d9b493
RH
1942 /* Merge each function unit into the unit mask attributes. */
1943 for (unit = units; unit; unit = unit->next)
c9541287
KH
1944 {
1945 XEXP (newexp, 0) = unit->condexp;
1946 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1947 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1948 }
71d9b493
RH
1949 }
1950 else
1951 {
1952 /* Merge each function unit into the unit mask attributes. */
1953 for (unit = units; unit; unit = unit->next)
c9541287
KH
1954 {
1955 XEXP (newexp, 0) = unit->condexp;
1956 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1957 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1958 }
72f1215c
TW
1959 }
1960
1961 /* Simplify the unit mask expression, encode it, and make an attribute
1962 for the function_units_used function. */
1963 unitsmask = simplify_by_exploding (unitsmask);
71d9b493
RH
1964
1965 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1966 unitsmask = encode_units_mask (unitsmask);
1967 else
1968 {
1969 /* We can no longer encode unitsmask at compile time, so emit code to
1970 calculate it at runtime. Rather, put a marker for where we'd do
1971 the code, and actually output it in write_attr_get(). */
1972 unitsmask = attr_rtx (FFS, unitsmask);
1973 }
1974
6f6074ea 1975 make_internal_attr ("*function_units_used", unitsmask, 10);
72f1215c
TW
1976
1977 /* Create an array of ops for each unit. Add an extra unit for the
1978 result_ready_cost function that has the ops of all other units. */
1979 unit_ops = (struct function_unit_op ***)
b548dffb 1980 xmalloc ((num_units + 1) * sizeof (struct function_unit_op **));
72f1215c 1981 unit_num = (struct function_unit **)
b548dffb 1982 xmalloc ((num_units + 1) * sizeof (struct function_unit *));
72f1215c
TW
1983
1984 unit_num[num_units] = unit = (struct function_unit *)
b548dffb 1985 xmalloc (sizeof (struct function_unit));
72f1215c
TW
1986 unit->num = num_units;
1987 unit->num_opclasses = 0;
1988
1989 for (unit = units; unit; unit = unit->next)
1990 {
1991 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1992 unit_num[unit->num] = unit;
1993 unit_ops[unit->num] = op_array = (struct function_unit_op **)
b548dffb 1994 xmalloc (unit->num_opclasses * sizeof (struct function_unit_op *));
72f1215c
TW
1995
1996 for (op = unit->ops; op; op = op->next)
1997 op_array[op->num] = op;
1998 }
1999
2000 /* Compose the array of ops for the extra unit. */
2001 unit_ops[num_units] = op_array = (struct function_unit_op **)
b548dffb 2002 xmalloc (unit_num[num_units]->num_opclasses
72f1215c
TW
2003 * sizeof (struct function_unit_op *));
2004
2005 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
d38a30c9
KG
2006 memcpy (&op_array[i], unit_ops[unit->num],
2007 unit->num_opclasses * sizeof (struct function_unit_op *));
72f1215c
TW
2008
2009 /* Compute the ready cost function for each unit by computing the
2010 condition for each non-default value. */
2011 for (u = 0; u <= num_units; u++)
2012 {
2013 rtx orexp;
2014 int value;
2015
2016 unit = unit_num[u];
2017 op_array = unit_ops[unit->num];
2018 num = unit->num_opclasses;
2019
2020 /* Sort the array of ops into increasing ready cost order. */
2021 for (i = 0; i < num; i++)
2022 for (j = num - 1; j > i; j--)
c9541287 2023 if (op_array[j - 1]->ready < op_array[j]->ready)
72f1215c
TW
2024 {
2025 op = op_array[j];
c9541287
KH
2026 op_array[j] = op_array[j - 1];
2027 op_array[j - 1] = op;
72f1215c
TW
2028 }
2029
2030 /* Determine how many distinct non-default ready cost values there
2031 are. We use a default ready cost value of 1. */
2032 nvalues = 0; value = 1;
2033 for (i = num - 1; i >= 0; i--)
2034 if (op_array[i]->ready > value)
2035 {
2036 value = op_array[i]->ready;
2037 nvalues++;
2038 }
2039
2040 if (nvalues == 0)
2041 readycost = make_numeric_value (1);
2042 else
2043 {
2044 /* Construct the ready cost expression as a COND of each value from
2045 the largest to the smallest. */
2046 readycost = rtx_alloc (COND);
2047 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2048 XEXP (readycost, 1) = make_numeric_value (1);
2049
c9541287
KH
2050 nvalues = 0;
2051 orexp = false_rtx;
2052 value = op_array[0]->ready;
72f1215c
TW
2053 for (i = 0; i < num; i++)
2054 {
2055 op = op_array[i];
2056 if (op->ready <= 1)
2057 break;
2058 else if (op->ready == value)
f75d38a7 2059 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
72f1215c
TW
2060 else
2061 {
2062 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2063 XVECEXP (readycost, 0, nvalues * 2 + 1)
2064 = make_numeric_value (value);
2065 nvalues++;
2066 value = op->ready;
2067 orexp = op->condexp;
2068 }
2069 }
2070 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2071 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2072 }
2073
72f1215c 2074 if (u < num_units)
bee757e1
TW
2075 {
2076 rtx max_blockage = 0, min_blockage = 0;
2077
2078 /* Simplify the readycost expression by only considering insns
2079 that use the unit. */
2080 readycost = simplify_knowing (readycost, unit->condexp);
2081
2082 /* Determine the blockage cost the executing insn (E) given
2083 the candidate insn (C). This is the maximum of the issue
2084 delay, the pipeline delay, and the simultaneity constraint.
2085 Each function_unit_op represents the characteristics of the
2086 candidate insn, so in the expressions below, C is a known
2087 term and E is an unknown term.
2088
cb1520bc
JW
2089 We compute the blockage cost for each E for every possible C.
2090 Thus OP represents E, and READYCOST is a list of values for
2091 every possible C.
2092
bee757e1
TW
2093 The issue delay function for C is op->issue_exp and is used to
2094 write the `<name>_unit_conflict_cost' function. Symbolicly
2095 this is "ISSUE-DELAY (E,C)".
2096
2097 The pipeline delay results form the FIFO constraint on the
2098 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2099
2100 The simultaneity constraint is based on how long it takes to
2101 fill the unit given the minimum issue delay. FILL-TIME is the
2102 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2103 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2104 if SIMULTANEITY is non-zero and zero otherwise.
2105
2106 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2107
2108 MAX (ISSUE-DELAY (E,C),
2109 READY-COST (E) - (READY-COST (C) - 1))
2110
2111 and otherwise
2112
2113 MAX (ISSUE-DELAY (E,C),
2114 READY-COST (E) - (READY-COST (C) - 1),
2115 READY-COST (E) - FILL-TIME)
2116
2117 The `<name>_unit_blockage' function is computed by determining
2118 this value for each candidate insn. As these values are
2119 computed, we also compute the upper and lower bounds for
2120 BLOCKAGE (E,*). These are combined to form the function
2121 `<name>_unit_blockage_range'. Finally, the maximum blockage
2122 cost, MAX (BLOCKAGE (*,*)), is computed. */
2123
2124 for (op = unit->ops; op; op = op->next)
2125 {
8c660648 2126 rtx blockage = op->issue_exp;
bee757e1
TW
2127 blockage = simplify_knowing (blockage, unit->condexp);
2128
2129 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2130 MIN (BLOCKAGE (E,*)). */
2131 if (max_blockage == 0)
2132 max_blockage = min_blockage = blockage;
2133 else
2134 {
2135 max_blockage
2136 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2137 blockage),
2138 unit->condexp);
2139 min_blockage
2140 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2141 blockage),
2142 unit->condexp);
2143 }
2144
2145 /* Make an attribute for use in the blockage function. */
0e9414fd
MM
2146 str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2147 "*%s_block_%d", unit->name, op->num);
bee757e1
TW
2148 make_internal_attr (str, blockage, 1);
2149 }
2150
2151 /* Record MAX (BLOCKAGE (*,*)). */
7ee37ba4
RH
2152 {
2153 int unknown;
2154 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2155 }
bee757e1
TW
2156
2157 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2158 same. If so, the blockage function carries no additional
2159 information and is not written. */
2160 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2161 newexp = simplify_knowing (newexp, unit->condexp);
2162 unit->needs_blockage_function
2163 = (GET_CODE (newexp) != CONST_STRING
2164 || atoi (XSTR (newexp, 0)) != 1);
2165
2166 /* If the all values of BLOCKAGE (E,C) have the same value,
c9541287 2167 neither blockage function is written. */
bee757e1
TW
2168 unit->needs_range_function
2169 = (unit->needs_blockage_function
2170 || GET_CODE (max_blockage) != CONST_STRING);
2171
2172 if (unit->needs_range_function)
2173 {
2174 /* Compute the blockage range function and make an attribute
9ec36da5 2175 for writing its value. */
bee757e1
TW
2176 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2177 newexp = simplify_knowing (newexp, unit->condexp);
2178
0e9414fd 2179 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
bee757e1 2180 "*%s_unit_blockage_range", unit->name);
6f6074ea 2181 make_internal_attr (str, newexp, 20);
bee757e1
TW
2182 }
2183
0e9414fd
MM
2184 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2185 "*%s_unit_ready_cost", unit->name);
bee757e1 2186 }
72f1215c
TW
2187 else
2188 str = "*result_ready_cost";
bee757e1
TW
2189
2190 /* Make an attribute for the ready_cost function. Simplifying
2191 further with simplify_by_exploding doesn't win. */
72f1215c
TW
2192 make_internal_attr (str, readycost, 0);
2193 }
2194
2195 /* For each unit that requires a conflict cost function, make an attribute
2196 that maps insns to the operation number. */
41299f41
TW
2197 for (unit = units; unit; unit = unit->next)
2198 {
72f1215c 2199 rtx caseexp;
41299f41 2200
bee757e1
TW
2201 if (! unit->needs_conflict_function
2202 && ! unit->needs_blockage_function)
72f1215c
TW
2203 continue;
2204
2205 caseexp = rtx_alloc (COND);
41299f41
TW
2206 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2207
2208 for (op = unit->ops; op; op = op->next)
2209 {
72f1215c
TW
2210 /* Make our adjustment to the COND being computed. If we are the
2211 last operation class, place our values into the default of the
2212 COND. */
41299f41
TW
2213 if (op->num == unit->num_opclasses - 1)
2214 {
41299f41
TW
2215 XEXP (caseexp, 1) = make_numeric_value (op->num);
2216 }
2217 else
2218 {
41299f41
TW
2219 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2220 XVECEXP (caseexp, 0, op->num * 2 + 1)
2221 = make_numeric_value (op->num);
2222 }
2223 }
2224
72f1215c 2225 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
0e9414fd
MM
2226 str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2227 "*%s_cases", unit->name);
41299f41 2228 make_internal_attr (str, caseexp, 1);
72f1215c
TW
2229 }
2230}
41299f41 2231
bee757e1
TW
2232/* Simplify EXP given KNOWN_TRUE. */
2233
2234static rtx
2235simplify_knowing (exp, known_true)
2236 rtx exp, known_true;
2237{
2238 if (GET_CODE (exp) != CONST_STRING)
2239 {
6166aa01 2240 int unknown = 0, max;
7ee37ba4
RH
2241 max = max_attr_value (exp, &unknown);
2242 if (! unknown)
2243 {
2244 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
c9541287
KH
2245 make_numeric_value (max));
2246 exp = simplify_by_exploding (exp);
7ee37ba4 2247 }
bee757e1
TW
2248 }
2249 return exp;
2250}
2251
72f1215c
TW
2252/* Translate the CONST_STRING expressions in X to change the encoding of
2253 value. On input, the value is a bitmask with a one bit for each unit
2254 used; on output, the value is the unit number (zero based) if one
2255 and only one unit is used or the one's compliment of the bitmask. */
41299f41 2256
72f1215c
TW
2257static rtx
2258encode_units_mask (x)
2259 rtx x;
2260{
2261 register int i;
2262 register int j;
2263 register enum rtx_code code;
6f7d635c 2264 register const char *fmt;
72f1215c
TW
2265
2266 code = GET_CODE (x);
2267
2268 switch (code)
2269 {
2270 case CONST_STRING:
2271 i = atoi (XSTR (x, 0));
2272 if (i < 0)
c9541287
KH
2273 /* The sign bit encodes a one's compliment mask. */
2274 abort ();
72f1215c
TW
2275 else if (i != 0 && i == (i & -i))
2276 /* Only one bit is set, so yield that unit number. */
2277 for (j = 0; (i >>= 1) != 0; j++)
2278 ;
2279 else
2280 j = ~i;
0e9414fd 2281 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
41299f41 2282
72f1215c
TW
2283 case REG:
2284 case QUEUED:
2285 case CONST_INT:
2286 case CONST_DOUBLE:
2287 case SYMBOL_REF:
2288 case CODE_LABEL:
2289 case PC:
2290 case CC0:
2291 case EQ_ATTR:
2292 return x;
c9541287 2293
e9a25f70
JL
2294 default:
2295 break;
41299f41
TW
2296 }
2297
72f1215c
TW
2298 /* Compare the elements. If any pair of corresponding elements
2299 fail to match, return 0 for the whole things. */
2300
2301 fmt = GET_RTX_FORMAT (code);
2302 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2303 {
2304 switch (fmt[i])
2305 {
2306 case 'V':
2307 case 'E':
2308 for (j = 0; j < XVECLEN (x, i); j++)
2309 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2310 break;
2311
2312 case 'e':
2313 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2314 break;
2315 }
2316 }
2317 return x;
41299f41
TW
2318}
2319\f
2320/* Once all attributes and insns have been read and checked, we construct for
2321 each attribute value a list of all the insns that have that value for
2322 the attribute. */
2323
2324static void
2325fill_attr (attr)
2326 struct attr_desc *attr;
2327{
2328 struct attr_value *av;
2329 struct insn_ent *ie;
2330 struct insn_def *id;
2331 int i;
2332 rtx value;
2333
b31a5831
RS
2334 /* Don't fill constant attributes. The value is independent of
2335 any particular insn. */
2336 if (attr->is_const)
2337 return;
2338
41299f41
TW
2339 for (id = defs; id; id = id->next)
2340 {
2341 /* If no value is specified for this insn for this attribute, use the
2342 default. */
2343 value = NULL;
2344 if (XVEC (id->def, id->vec_idx))
2345 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
c9541287 2346 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
41299f41
TW
2347 attr->name))
2348 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2349
2350 if (value == NULL)
2351 av = attr->default_val;
2352 else
2353 av = get_attr_value (value, attr, id->insn_code);
2354
0e9414fd 2355 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
41299f41
TW
2356 ie->insn_code = id->insn_code;
2357 ie->insn_index = id->insn_code;
2358 insert_insn_ent (av, ie);
2359 }
2360}
2361\f
ae90e6a3
RS
2362/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2363 test that checks relative positions of insns (uses MATCH_DUP or PC).
2364 If so, replace it with what is obtained by passing the expression to
2365 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2366 recursively on each value (including the default value). Otherwise,
2367 return the value returned by NO_ADDRESS_FN applied to EXP. */
41299f41
TW
2368
2369static rtx
2370substitute_address (exp, no_address_fn, address_fn)
2371 rtx exp;
a94ae8f5
KG
2372 rtx (*no_address_fn) PARAMS ((rtx));
2373 rtx (*address_fn) PARAMS ((rtx));
41299f41
TW
2374{
2375 int i;
2376 rtx newexp;
2377
ae90e6a3
RS
2378 if (GET_CODE (exp) == COND)
2379 {
2380 /* See if any tests use addresses. */
2381 address_used = 0;
2382 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2383 walk_attr_value (XVECEXP (exp, 0, i));
41299f41 2384
ae90e6a3
RS
2385 if (address_used)
2386 return (*address_fn) (exp);
41299f41 2387
ae90e6a3
RS
2388 /* Make a new copy of this COND, replacing each element. */
2389 newexp = rtx_alloc (COND);
2390 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2391 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2392 {
2393 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2394 XVECEXP (newexp, 0, i + 1)
2395 = substitute_address (XVECEXP (exp, 0, i + 1),
2396 no_address_fn, address_fn);
2397 }
41299f41 2398
ae90e6a3
RS
2399 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2400 no_address_fn, address_fn);
2401
2402 return newexp;
41299f41
TW
2403 }
2404
ae90e6a3
RS
2405 else if (GET_CODE (exp) == IF_THEN_ELSE)
2406 {
2407 address_used = 0;
2408 walk_attr_value (XEXP (exp, 0));
2409 if (address_used)
2410 return (*address_fn) (exp);
41299f41 2411
3e7b5313
TW
2412 return attr_rtx (IF_THEN_ELSE,
2413 substitute_address (XEXP (exp, 0),
2414 no_address_fn, address_fn),
2415 substitute_address (XEXP (exp, 1),
2416 no_address_fn, address_fn),
2417 substitute_address (XEXP (exp, 2),
2418 no_address_fn, address_fn));
ae90e6a3
RS
2419 }
2420
2421 return (*no_address_fn) (exp);
41299f41
TW
2422}
2423\f
2424/* Make new attributes from the `length' attribute. The following are made,
2425 each corresponding to a function called from `shorten_branches' or
2426 `get_attr_length':
2427
2428 *insn_default_length This is the length of the insn to be returned
2429 by `get_attr_length' before `shorten_branches'
2430 has been called. In each case where the length
2431 depends on relative addresses, the largest
2432 possible is used. This routine is also used
2433 to compute the initial size of the insn.
2434
2435 *insn_variable_length_p This returns 1 if the insn's length depends
2436 on relative addresses, zero otherwise.
2437
2438 *insn_current_length This is only called when it is known that the
2439 insn has a variable length and returns the
2440 current length, based on relative addresses.
2441 */
2442
2443static void
2444make_length_attrs ()
2445{
85fda1eb
KG
2446 static const char *new_names[] = {"*insn_default_length",
2447 "*insn_variable_length_p",
2448 "*insn_current_length"};
a94ae8f5
KG
2449 static rtx (*no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
2450 static rtx (*address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
d6f4ec51 2451 size_t i;
41299f41
TW
2452 struct attr_desc *length_attr, *new_attr;
2453 struct attr_value *av, *new_av;
2454 struct insn_ent *ie, *new_ie;
2455
2456 /* See if length attribute is defined. If so, it must be numeric. Make
2457 it special so we don't output anything for it. */
2458 length_attr = find_attr ("length", 0);
2459 if (length_attr == 0)
2460 return;
2461
2462 if (! length_attr->is_numeric)
2463 fatal ("length attribute must be numeric.");
2464
3e7b5313 2465 length_attr->is_const = 0;
41299f41
TW
2466 length_attr->is_special = 1;
2467
2468 /* Make each new attribute, in turn. */
b6a1cbae 2469 for (i = 0; i < ARRAY_SIZE (new_names); i++)
41299f41
TW
2470 {
2471 make_internal_attr (new_names[i],
2472 substitute_address (length_attr->default_val->value,
2473 no_address_fn[i], address_fn[i]),
2474 0);
2475 new_attr = find_attr (new_names[i], 0);
2476 for (av = length_attr->first_value; av; av = av->next)
2477 for (ie = av->first_insn; ie; ie = ie->next)
2478 {
2479 new_av = get_attr_value (substitute_address (av->value,
2480 no_address_fn[i],
2481 address_fn[i]),
2482 new_attr, ie->insn_code);
0e9414fd 2483 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
41299f41
TW
2484 new_ie->insn_code = ie->insn_code;
2485 new_ie->insn_index = ie->insn_index;
2486 insert_insn_ent (new_av, new_ie);
2487 }
2488 }
2489}
2490
2491/* Utility functions called from above routine. */
2492
2493static rtx
2494identity_fn (exp)
2495 rtx exp;
2496{
2497 return exp;
2498}
2499
2500static rtx
2501zero_fn (exp)
d6f4ec51 2502 rtx exp ATTRIBUTE_UNUSED;
41299f41
TW
2503{
2504 return make_numeric_value (0);
2505}
2506
2507static rtx
2508one_fn (exp)
d6f4ec51 2509 rtx exp ATTRIBUTE_UNUSED;
41299f41
TW
2510{
2511 return make_numeric_value (1);
2512}
2513
2514static rtx
2515max_fn (exp)
2516 rtx exp;
2517{
7ee37ba4
RH
2518 int unknown;
2519 return make_numeric_value (max_attr_value (exp, &unknown));
41299f41 2520}
fc470718
R
2521
2522static void
2523write_length_unit_log ()
2524{
2525 struct attr_desc *length_attr = find_attr ("length", 0);
2526 struct attr_value *av;
2527 struct insn_ent *ie;
2528 unsigned int length_unit_log, length_or;
7ee37ba4 2529 int unknown = 0;
fc470718
R
2530
2531 if (length_attr == 0)
2532 return;
7ee37ba4
RH
2533 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2534 for (av = length_attr->first_value; av; av = av->next)
2535 for (ie = av->first_insn; ie; ie = ie->next)
2536 length_or |= or_attr_value (av->value, &unknown);
2537
2538 if (unknown)
2539 length_unit_log = 0;
2540 else
2541 {
2542 length_or = ~length_or;
2543 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
c9541287 2544 length_unit_log++;
7ee37ba4 2545 }
fc470718
R
2546 printf ("int length_unit_log = %u;\n", length_unit_log);
2547}
41299f41
TW
2548\f
2549/* Take a COND expression and see if any of the conditions in it can be
2550 simplified. If any are known true or known false for the particular insn
2551 code, the COND can be further simplified.
2552
2553 Also call ourselves on any COND operations that are values of this COND.
2554
7339c88d 2555 We do not modify EXP; rather, we make and return a new rtx. */
41299f41
TW
2556
2557static rtx
2558simplify_cond (exp, insn_code, insn_index)
2559 rtx exp;
2560 int insn_code, insn_index;
2561{
2562 int i, j;
7339c88d
RS
2563 /* We store the desired contents here,
2564 then build a new expression if they don't match EXP. */
2565 rtx defval = XEXP (exp, 1);
eaed7119 2566 rtx new_defval = XEXP (exp, 1);
7339c88d 2567 int len = XVECLEN (exp, 0);
b548dffb 2568 rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
7339c88d 2569 int allsame = 1;
b5b6ad46 2570 char *first_spacer;
b548dffb 2571 rtx ret;
41299f41 2572
7339c88d 2573 /* This lets us free all storage allocated below, if appropriate. */
81fd4c6e 2574 first_spacer = (char *) obstack_finish (rtl_obstack);
41299f41 2575
4e135bdd 2576 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
41299f41 2577
7339c88d
RS
2578 /* See if default value needs simplification. */
2579 if (GET_CODE (defval) == COND)
eaed7119 2580 new_defval = simplify_cond (defval, insn_code, insn_index);
41299f41 2581
81fd4c6e 2582 /* Simplify the subexpressions, and see what tests we can get rid of. */
41299f41 2583
81fd4c6e 2584 for (i = 0; i < len; i += 2)
7339c88d
RS
2585 {
2586 rtx newtest, newval;
41299f41 2587
7339c88d 2588 /* Simplify this test. */
2d515d60 2589 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
910eabe5 2590 tests[i] = newtest;
41299f41 2591
910eabe5 2592 newval = tests[i + 1];
7339c88d
RS
2593 /* See if this value may need simplification. */
2594 if (GET_CODE (newval) == COND)
2595 newval = simplify_cond (newval, insn_code, insn_index);
2596
2597 /* Look for ways to delete or combine this test. */
2598 if (newtest == true_rtx)
2599 {
2600 /* If test is true, make this value the default
2601 and discard this + any following tests. */
2602 len = i;
910eabe5 2603 defval = tests[i + 1];
eaed7119 2604 new_defval = newval;
41299f41
TW
2605 }
2606
7339c88d 2607 else if (newtest == false_rtx)
41299f41 2608 {
7339c88d
RS
2609 /* If test is false, discard it and its value. */
2610 for (j = i; j < len - 2; j++)
910eabe5 2611 tests[j] = tests[j + 2];
81fd4c6e
RS
2612 len -= 2;
2613 }
41299f41 2614
910eabe5 2615 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
81fd4c6e
RS
2616 {
2617 /* If this value and the value for the prev test are the same,
2618 merge the tests. */
2619
910eabe5
JL
2620 tests[i - 2]
2621 = insert_right_side (IOR, tests[i - 2], newtest,
81fd4c6e
RS
2622 insn_code, insn_index);
2623
2624 /* Delete this test/value. */
2625 for (j = i; j < len - 2; j++)
910eabe5 2626 tests[j] = tests[j + 2];
7339c88d 2627 len -= 2;
41299f41
TW
2628 }
2629
81fd4c6e 2630 else
910eabe5 2631 tests[i + 1] = newval;
7339c88d 2632 }
41299f41 2633
81fd4c6e
RS
2634 /* If the last test in a COND has the same value
2635 as the default value, that test isn't needed. */
2636
910eabe5 2637 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
81fd4c6e
RS
2638 len -= 2;
2639
2640 /* See if we changed anything. */
2641 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2642 allsame = 0;
2643 else
2644 for (i = 0; i < len; i++)
910eabe5 2645 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
81fd4c6e
RS
2646 {
2647 allsame = 0;
2648 break;
2649 }
41299f41 2650
7339c88d
RS
2651 if (len == 0)
2652 {
7339c88d 2653 if (GET_CODE (defval) == COND)
b548dffb
ZW
2654 ret = simplify_cond (defval, insn_code, insn_index);
2655 else
2656 ret = defval;
7339c88d 2657 }
81fd4c6e 2658 else if (allsame)
b548dffb 2659 ret = exp;
7339c88d
RS
2660 else
2661 {
81fd4c6e 2662 rtx newexp = rtx_alloc (COND);
7339c88d
RS
2663
2664 XVEC (newexp, 0) = rtvec_alloc (len);
4e135bdd 2665 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
81fd4c6e 2666 XEXP (newexp, 1) = new_defval;
b548dffb 2667 ret = newexp;
41299f41 2668 }
b548dffb
ZW
2669 free (tests);
2670 return ret;
41299f41
TW
2671}
2672\f
2673/* Remove an insn entry from an attribute value. */
2674
2675static void
2676remove_insn_ent (av, ie)
2677 struct attr_value *av;
2678 struct insn_ent *ie;
2679{
2680 struct insn_ent *previe;
2681
2682 if (av->first_insn == ie)
2683 av->first_insn = ie->next;
2684 else
2685 {
2686 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2687 ;
2688 previe->next = ie->next;
2689 }
2690
2691 av->num_insns--;
2692 if (ie->insn_code == -1)
2693 av->has_asm_insn = 0;
1c69865d
ILT
2694
2695 num_insn_ents--;
41299f41
TW
2696}
2697
2698/* Insert an insn entry in an attribute value list. */
2699
2700static void
2701insert_insn_ent (av, ie)
2702 struct attr_value *av;
2703 struct insn_ent *ie;
2704{
2705 ie->next = av->first_insn;
2706 av->first_insn = ie;
2707 av->num_insns++;
2708 if (ie->insn_code == -1)
2709 av->has_asm_insn = 1;
1c69865d
ILT
2710
2711 num_insn_ents++;
41299f41
TW
2712}
2713\f
2714/* This is a utility routine to take an expression that is a tree of either
2715 AND or IOR expressions and insert a new term. The new term will be
2716 inserted at the right side of the first node whose code does not match
2717 the root. A new node will be created with the root's code. Its left
2718 side will be the old right side and its right side will be the new
2719 term.
2720
2721 If the `term' is itself a tree, all its leaves will be inserted. */
2722
2723static rtx
2724insert_right_side (code, exp, term, insn_code, insn_index)
f75d38a7 2725 enum rtx_code code;
41299f41
TW
2726 rtx exp;
2727 rtx term;
2728 int insn_code, insn_index;
2729{
2730 rtx newexp;
2731
7339c88d
RS
2732 /* Avoid consing in some special cases. */
2733 if (code == AND && term == true_rtx)
2734 return exp;
2735 if (code == AND && term == false_rtx)
2736 return false_rtx;
2737 if (code == AND && exp == true_rtx)
2738 return term;
2739 if (code == AND && exp == false_rtx)
2740 return false_rtx;
2741 if (code == IOR && term == true_rtx)
2742 return true_rtx;
2743 if (code == IOR && term == false_rtx)
2744 return exp;
2745 if (code == IOR && exp == true_rtx)
2746 return true_rtx;
2747 if (code == IOR && exp == false_rtx)
2748 return term;
81fd4c6e 2749 if (attr_equal_p (exp, term))
7339c88d
RS
2750 return exp;
2751
41299f41
TW
2752 if (GET_CODE (term) == code)
2753 {
2754 exp = insert_right_side (code, exp, XEXP (term, 0),
2755 insn_code, insn_index);
2756 exp = insert_right_side (code, exp, XEXP (term, 1),
2757 insn_code, insn_index);
2758
2759 return exp;
2760 }
2761
2762 if (GET_CODE (exp) == code)
2763 {
7339c88d
RS
2764 rtx new = insert_right_side (code, XEXP (exp, 1),
2765 term, insn_code, insn_index);
2766 if (new != XEXP (exp, 1))
2767 /* Make a copy of this expression and call recursively. */
2768 newexp = attr_rtx (code, XEXP (exp, 0), new);
2769 else
2770 newexp = exp;
41299f41
TW
2771 }
2772 else
2773 {
2774 /* Insert the new term. */
3e7b5313 2775 newexp = attr_rtx (code, exp, term);
7339c88d 2776 }
41299f41 2777
2d515d60 2778 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
2779}
2780\f
2781/* If we have an expression which AND's a bunch of
2782 (not (eq_attrq "alternative" "n"))
2783 terms, we may have covered all or all but one of the possible alternatives.
2784 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2785
2786 This routine is passed an expression and either AND or IOR. It returns a
f75d38a7 2787 bitmask indicating which alternatives are mentioned within EXP. */
41299f41
TW
2788
2789static int
2790compute_alternative_mask (exp, code)
2791 rtx exp;
f75d38a7 2792 enum rtx_code code;
41299f41 2793{
3cce094d 2794 const char *string;
41299f41
TW
2795 if (GET_CODE (exp) == code)
2796 return compute_alternative_mask (XEXP (exp, 0), code)
2797 | compute_alternative_mask (XEXP (exp, 1), code);
2798
2799 else if (code == AND && GET_CODE (exp) == NOT
2800 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2801 && XSTR (XEXP (exp, 0), 0) == alternative_name)
b31a5831 2802 string = XSTR (XEXP (exp, 0), 1);
41299f41
TW
2803
2804 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2805 && XSTR (exp, 0) == alternative_name)
b31a5831 2806 string = XSTR (exp, 1);
41299f41
TW
2807
2808 else
2809 return 0;
b31a5831
RS
2810
2811 if (string[1] == 0)
2812 return 1 << (string[0] - '0');
2813 return 1 << atoi (string);
41299f41
TW
2814}
2815
2816/* Given I, a single-bit mask, return RTX to compare the `alternative'
2817 attribute with the value represented by that bit. */
2818
2819static rtx
2820make_alternative_compare (mask)
2821 int mask;
2822{
2823 rtx newexp;
2824 int i;
41299f41
TW
2825
2826 /* Find the bit. */
2827 for (i = 0; (mask & (1 << i)) == 0; i++)
2828 ;
2829
81fd4c6e 2830 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
41299f41
TW
2831 RTX_UNCHANGING_P (newexp) = 1;
2832
2833 return newexp;
2834}
2835\f
2836/* If we are processing an (eq_attr "attr" "value") test, we find the value
2837 of "attr" for this insn code. From that value, we can compute a test
2838 showing when the EQ_ATTR will be true. This routine performs that
2839 computation. If a test condition involves an address, we leave the EQ_ATTR
c9541287 2840 intact because addresses are only valid for the `length' attribute.
41299f41 2841
f75d38a7
RK
2842 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2843 for the insn corresponding to INSN_CODE and INSN_INDEX. */
7339c88d 2844
41299f41
TW
2845static rtx
2846evaluate_eq_attr (exp, value, insn_code, insn_index)
2847 rtx exp;
2848 rtx value;
2849 int insn_code, insn_index;
2850{
2851 rtx orexp, andexp;
2852 rtx right;
2853 rtx newexp;
2854 int i;
2855
2856 if (GET_CODE (value) == CONST_STRING)
2857 {
2858 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2859 newexp = true_rtx;
2860 else
2861 newexp = false_rtx;
2862 }
71d9b493
RH
2863 else if (GET_CODE (value) == SYMBOL_REF)
2864 {
b548dffb
ZW
2865 char *p;
2866 char string[256];
71d9b493
RH
2867
2868 if (GET_CODE (exp) != EQ_ATTR)
c9541287 2869 abort ();
71d9b493 2870
b548dffb
ZW
2871 if (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 > 256)
2872 abort ();
2873
71d9b493
RH
2874 strcpy (string, XSTR (exp, 0));
2875 strcat (string, "_");
2876 strcat (string, XSTR (exp, 1));
c9541287 2877 for (p = string; *p; p++)
92a438d1 2878 *p = TOUPPER (*p);
c9541287 2879
71d9b493
RH
2880 newexp = attr_rtx (EQ, value,
2881 attr_rtx (SYMBOL_REF,
c9541287 2882 attr_string (string, strlen (string))));
71d9b493 2883 }
41299f41
TW
2884 else if (GET_CODE (value) == COND)
2885 {
2886 /* We construct an IOR of all the cases for which the requested attribute
2887 value is present. Since we start with FALSE, if it is not present,
2888 FALSE will be returned.
2889
2890 Each case is the AND of the NOT's of the previous conditions with the
c9541287 2891 current condition; in the default case the current condition is TRUE.
41299f41
TW
2892
2893 For each possible COND value, call ourselves recursively.
2894
2895 The extra TRUE and FALSE expressions will be eliminated by another
0f41302f 2896 call to the simplification routine. */
41299f41
TW
2897
2898 orexp = false_rtx;
2899 andexp = true_rtx;
2900
3715a518
RS
2901 if (current_alternative_string)
2902 clear_struct_flag (value);
2903
41299f41
TW
2904 for (i = 0; i < XVECLEN (value, 0); i += 2)
2905 {
2d515d60
JH
2906 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2907 insn_code, insn_index);
7339c88d 2908
3715a518
RS
2909 SIMPLIFY_ALTERNATIVE (this);
2910
7339c88d 2911 right = insert_right_side (AND, andexp, this,
41299f41
TW
2912 insn_code, insn_index);
2913 right = insert_right_side (AND, right,
f75d38a7
RK
2914 evaluate_eq_attr (exp,
2915 XVECEXP (value, 0,
2916 i + 1),
2917 insn_code, insn_index),
41299f41
TW
2918 insn_code, insn_index);
2919 orexp = insert_right_side (IOR, orexp, right,
2920 insn_code, insn_index);
2921
2922 /* Add this condition into the AND expression. */
7339c88d 2923 newexp = attr_rtx (NOT, this);
41299f41
TW
2924 andexp = insert_right_side (AND, andexp, newexp,
2925 insn_code, insn_index);
2926 }
2927
2928 /* Handle the default case. */
2929 right = insert_right_side (AND, andexp,
2930 evaluate_eq_attr (exp, XEXP (value, 1),
f75d38a7 2931 insn_code, insn_index),
41299f41
TW
2932 insn_code, insn_index);
2933 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2934 }
2935 else
2936 abort ();
2937
052aaaef
RK
2938 /* If uses an address, must return original expression. But set the
2939 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
41299f41
TW
2940
2941 address_used = 0;
2942 walk_attr_value (newexp);
2943
2944 if (address_used)
052aaaef 2945 {
45044655
RS
2946 /* This had `&& current_alternative_string', which seems to be wrong. */
2947 if (! RTX_UNCHANGING_P (exp))
7339c88d 2948 return copy_rtx_unchanging (exp);
052aaaef
RK
2949 return exp;
2950 }
41299f41
TW
2951 else
2952 return newexp;
2953}
2954\f
2955/* This routine is called when an AND of a term with a tree of AND's is
2956 encountered. If the term or its complement is present in the tree, it
2957 can be replaced with TRUE or FALSE, respectively.
2958
2959 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
c9541287 2960 be true and hence are complementary.
41299f41
TW
2961
2962 There is one special case: If we see
2963 (and (not (eq_attr "att" "v1"))
2964 (eq_attr "att" "v2"))
2965 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2966 replace the term, not anything in the AND tree. So we pass a pointer to
2967 the term. */
2968
2969static rtx
2970simplify_and_tree (exp, pterm, insn_code, insn_index)
2971 rtx exp;
2972 rtx *pterm;
2973 int insn_code, insn_index;
2974{
2975 rtx left, right;
2976 rtx newexp;
2977 rtx temp;
2978 int left_eliminates_term, right_eliminates_term;
2979
2980 if (GET_CODE (exp) == AND)
2981 {
c9541287 2982 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
41299f41
TW
2983 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2984 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2985 {
3e7b5313 2986 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41 2987
2d515d60 2988 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
2989 }
2990 }
2991
2992 else if (GET_CODE (exp) == IOR)
2993 {
2994 /* For the IOR case, we do the same as above, except that we can
2995 only eliminate `term' if both sides of the IOR would do so. */
2996 temp = *pterm;
c9541287 2997 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
41299f41
TW
2998 left_eliminates_term = (temp == true_rtx);
2999
3000 temp = *pterm;
3001 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3002 right_eliminates_term = (temp == true_rtx);
3003
3004 if (left_eliminates_term && right_eliminates_term)
3005 *pterm = true_rtx;
3006
3007 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3008 {
3e7b5313 3009 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41 3010
2d515d60 3011 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
3012 }
3013 }
3014
3015 /* Check for simplifications. Do some extra checking here since this
3016 routine is called so many times. */
3017
3018 if (exp == *pterm)
3019 return true_rtx;
3020
3021 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
3022 return false_rtx;
3023
3024 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
3025 return false_rtx;
3026
3027 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
3028 {
3029 if (XSTR (exp, 0) != XSTR (*pterm, 0))
3030 return exp;
3031
3032 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
3033 return true_rtx;
3034 else
3035 return false_rtx;
3036 }
3037
3038 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3039 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3040 {
3041 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3042 return exp;
3043
3044 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3045 return false_rtx;
3046 else
3047 return true_rtx;
3048 }
3049
3050 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3051 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3052 {
3053 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3054 return exp;
3055
3056 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3057 return false_rtx;
3058 else
3059 *pterm = true_rtx;
3060 }
3061
3062 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3063 {
81fd4c6e 3064 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
41299f41
TW
3065 return true_rtx;
3066 }
3067
3068 else if (GET_CODE (exp) == NOT)
3069 {
81fd4c6e 3070 if (attr_equal_p (XEXP (exp, 0), *pterm))
41299f41
TW
3071 return false_rtx;
3072 }
3073
3074 else if (GET_CODE (*pterm) == NOT)
3075 {
81fd4c6e 3076 if (attr_equal_p (XEXP (*pterm, 0), exp))
41299f41
TW
3077 return false_rtx;
3078 }
3079
81fd4c6e 3080 else if (attr_equal_p (exp, *pterm))
41299f41
TW
3081 return true_rtx;
3082
3083 return exp;
3084}
3085\f
6dc42e49 3086/* Similar to `simplify_and_tree', but for IOR trees. */
41299f41
TW
3087
3088static rtx
3089simplify_or_tree (exp, pterm, insn_code, insn_index)
3090 rtx exp;
3091 rtx *pterm;
3092 int insn_code, insn_index;
3093{
3094 rtx left, right;
3095 rtx newexp;
3096 rtx temp;
3097 int left_eliminates_term, right_eliminates_term;
3098
3099 if (GET_CODE (exp) == IOR)
3100 {
c9541287 3101 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
41299f41
TW
3102 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3103 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3104 {
3e7b5313 3105 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41 3106
2d515d60 3107 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
3108 }
3109 }
3110
3111 else if (GET_CODE (exp) == AND)
3112 {
3113 /* For the AND case, we do the same as above, except that we can
3114 only eliminate `term' if both sides of the AND would do so. */
3115 temp = *pterm;
c9541287 3116 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
41299f41
TW
3117 left_eliminates_term = (temp == false_rtx);
3118
3119 temp = *pterm;
3120 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3121 right_eliminates_term = (temp == false_rtx);
3122
3123 if (left_eliminates_term && right_eliminates_term)
3124 *pterm = false_rtx;
3125
3126 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3127 {
3e7b5313 3128 newexp = attr_rtx (GET_CODE (exp), left, right);
41299f41 3129
2d515d60 3130 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
41299f41
TW
3131 }
3132 }
3133
81fd4c6e 3134 if (attr_equal_p (exp, *pterm))
41299f41
TW
3135 return false_rtx;
3136
81fd4c6e 3137 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
41299f41
TW
3138 return true_rtx;
3139
81fd4c6e 3140 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
41299f41
TW
3141 return true_rtx;
3142
3143 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3144 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3145 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3146 *pterm = false_rtx;
3147
3148 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3149 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3150 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3151 return false_rtx;
3152
3153 return exp;
3154}
2bed3391
JH
3155/* Compute approximate cost of the expression. Used to decide whether
3156 expression is cheap enought for inline. */
3157static int
3158attr_rtx_cost (x)
3159 rtx x;
3160{
3161 int cost = 0;
3162 enum rtx_code code;
3163 if (!x)
3164 return 0;
3165 code = GET_CODE (x);
3166 switch (code)
3167 {
3168 case MATCH_OPERAND:
3169 if (XSTR (x, 1)[0])
3170 return 10;
3171 else
3172 return 0;
3173 case EQ_ATTR:
3174 /* Alternatives don't result into function call. */
3175 if (!strcmp (XSTR (x, 0), "alternative"))
3176 return 0;
3177 else
3178 return 5;
3179 default:
3180 {
3181 int i, j;
3182 const char *fmt = GET_RTX_FORMAT (code);
3183 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3184 {
3185 switch (fmt[i])
3186 {
3187 case 'V':
3188 case 'E':
3189 for (j = 0; j < XVECLEN (x, i); j++)
3190 cost += attr_rtx_cost (XVECEXP (x, i, j));
3191 break;
3192 case 'e':
3193 cost += attr_rtx_cost (XEXP (x, i));
3194 break;
3195 }
3196 }
3197 }
3198 break;
3199 }
3200 return cost;
3201}
41299f41 3202\f
2d515d60
JH
3203
3204/* Simplify test expression and use temporary obstack in order to avoid
3205 memory bloat. Use RTX_UNCHANGING_P to avoid unnecesary simplifications
3206 and avoid unnecesary copying if possible. */
3207
3208static rtx
3209simplify_test_exp_in_temp (exp, insn_code, insn_index)
3210 rtx exp;
3211 int insn_code, insn_index;
3212{
3213 rtx x;
3214 struct obstack *old;
3215 if (RTX_UNCHANGING_P (exp))
3216 return exp;
3217 old = rtl_obstack;
3218 rtl_obstack = temp_obstack;
3219 x = simplify_test_exp (exp, insn_code, insn_index);
3220 rtl_obstack = old;
3221 if (x == exp || rtl_obstack == temp_obstack)
3222 return x;
3223 return attr_copy_rtx (x);
3224}
3225
41299f41
TW
3226/* Given an expression, see if it can be simplified for a particular insn
3227 code based on the values of other attributes being tested. This can
3228 eliminate nested get_attr_... calls.
3229
c9541287 3230 Note that if an endless recursion is specified in the patterns, the
41299f41
TW
3231 optimization will loop. However, it will do so in precisely the cases where
3232 an infinite recursion loop could occur during compilation. It's better that
3233 it occurs here! */
3234
3235static rtx
3236simplify_test_exp (exp, insn_code, insn_index)
3237 rtx exp;
3238 int insn_code, insn_index;
3239{
3240 rtx left, right;
3241 struct attr_desc *attr;
3242 struct attr_value *av;
3243 struct insn_ent *ie;
3244 int i;
3245 rtx newexp = exp;
7339c88d 3246
7339c88d 3247 /* Don't re-simplify something we already simplified. */
85093b9c 3248 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
7339c88d 3249 return exp;
41299f41
TW
3250
3251 switch (GET_CODE (exp))
3252 {
3253 case AND:
61abc2ca 3254 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3715a518
RS
3255 SIMPLIFY_ALTERNATIVE (left);
3256 if (left == false_rtx)
1f8f4a0b 3257 return false_rtx;
61abc2ca 3258 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3715a518
RS
3259 SIMPLIFY_ALTERNATIVE (right);
3260 if (left == false_rtx)
1f8f4a0b 3261 return false_rtx;
61abc2ca
RS
3262
3263 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3264 present on both sides, apply the distributive law since this will
3265 yield simplifications. */
3266 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3267 && compute_alternative_mask (left, IOR)
3268 && compute_alternative_mask (right, IOR))
41299f41 3269 {
61abc2ca 3270 if (GET_CODE (left) == IOR)
41299f41 3271 {
61abc2ca
RS
3272 rtx tem = left;
3273 left = right;
3274 right = tem;
3275 }
3276
3277 newexp = attr_rtx (IOR,
3278 attr_rtx (AND, left, XEXP (right, 0)),
3279 attr_rtx (AND, left, XEXP (right, 1)));
3280
3281 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3282 }
3283
3284 /* Try with the term on both sides. */
3285 right = simplify_and_tree (right, &left, insn_code, insn_index);
3286 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3287 left = simplify_and_tree (left, &right, insn_code, insn_index);
3288
3289 if (left == false_rtx || right == false_rtx)
1f8f4a0b 3290 return false_rtx;
61abc2ca
RS
3291 else if (left == true_rtx)
3292 {
85093b9c 3293 return right;
61abc2ca
RS
3294 }
3295 else if (right == true_rtx)
3296 {
85093b9c 3297 return left;
61abc2ca 3298 }
61abc2ca
RS
3299 /* See if all or all but one of the insn's alternatives are specified
3300 in this tree. Optimize if so. */
3301
3302 else if (insn_code >= 0
3303 && (GET_CODE (left) == AND
3304 || (GET_CODE (left) == NOT
3305 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3306 && XSTR (XEXP (left, 0), 0) == alternative_name)
3307 || GET_CODE (right) == AND
3308 || (GET_CODE (right) == NOT
3309 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3310 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3311 {
3312 i = compute_alternative_mask (exp, AND);
3313 if (i & ~insn_alternatives[insn_code])
9916c524 3314 fatal ("Invalid alternative specified for pattern number %d",
61abc2ca
RS
3315 insn_index);
3316
0f41302f 3317 /* If all alternatives are excluded, this is false. */
61abc2ca
RS
3318 i ^= insn_alternatives[insn_code];
3319 if (i == 0)
3320 return false_rtx;
3321 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3322 {
3323 /* If just one excluded, AND a comparison with that one to the
3324 front of the tree. The others will be eliminated by
3325 optimization. We do not want to do this if the insn has one
3326 alternative and we have tested none of them! */
3327 left = make_alternative_compare (i);
3328 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3329 newexp = attr_rtx (AND, left, right);
41299f41
TW
3330
3331 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3332 }
3333 }
61abc2ca
RS
3334
3335 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3336 {
3337 newexp = attr_rtx (AND, left, right);
3338 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3339 }
3340 break;
41299f41
TW
3341
3342 case IOR:
61abc2ca 3343 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3715a518
RS
3344 SIMPLIFY_ALTERNATIVE (left);
3345 if (left == true_rtx)
1f8f4a0b 3346 return true_rtx;
61abc2ca 3347 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3715a518
RS
3348 SIMPLIFY_ALTERNATIVE (right);
3349 if (right == true_rtx)
1f8f4a0b 3350 return true_rtx;
61abc2ca
RS
3351
3352 right = simplify_or_tree (right, &left, insn_code, insn_index);
3353 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3354 left = simplify_or_tree (left, &right, insn_code, insn_index);
3355
3356 if (right == true_rtx || left == true_rtx)
1f8f4a0b 3357 return true_rtx;
61abc2ca
RS
3358 else if (left == false_rtx)
3359 {
85093b9c 3360 return right;
61abc2ca
RS
3361 }
3362 else if (right == false_rtx)
3363 {
85093b9c 3364 return left;
61abc2ca
RS
3365 }
3366
3367 /* Test for simple cases where the distributive law is useful. I.e.,
3368 convert (ior (and (x) (y))
3369 (and (x) (z)))
3370 to (and (x)
3371 (ior (y) (z)))
3372 */
3373
3374 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
c9541287 3375 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
61abc2ca
RS
3376 {
3377 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3378
3379 left = XEXP (left, 0);
3380 right = newexp;
3381 newexp = attr_rtx (AND, left, right);
3382 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3383 }
3384
3385 /* See if all or all but one of the insn's alternatives are specified
3386 in this tree. Optimize if so. */
3387
3388 else if (insn_code >= 0
c9541287
KH
3389 && (GET_CODE (left) == IOR
3390 || (GET_CODE (left) == EQ_ATTR
3391 && XSTR (left, 0) == alternative_name)
3392 || GET_CODE (right) == IOR
3393 || (GET_CODE (right) == EQ_ATTR
3394 && XSTR (right, 0) == alternative_name)))
61abc2ca
RS
3395 {
3396 i = compute_alternative_mask (exp, IOR);
3397 if (i & ~insn_alternatives[insn_code])
9916c524 3398 fatal ("Invalid alternative specified for pattern number %d",
61abc2ca
RS
3399 insn_index);
3400
0f41302f 3401 /* If all alternatives are included, this is true. */
61abc2ca
RS
3402 i ^= insn_alternatives[insn_code];
3403 if (i == 0)
3404 return true_rtx;
3405 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3406 {
3407 /* If just one excluded, IOR a comparison with that one to the
3408 front of the tree. The others will be eliminated by
3409 optimization. We do not want to do this if the insn has one
3410 alternative and we have tested none of them! */
3411 left = make_alternative_compare (i);
3412 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3413 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3414
3415 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3416 }
3417 }
3418
3419 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3420 {
3421 newexp = attr_rtx (IOR, left, right);
3422 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3423 }
3424 break;
41299f41
TW
3425
3426 case NOT:
7339c88d 3427 if (GET_CODE (XEXP (exp, 0)) == NOT)
3715a518
RS
3428 {
3429 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3430 insn_code, insn_index);
3431 SIMPLIFY_ALTERNATIVE (left);
3432 return left;
3433 }
3434
41299f41 3435 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3715a518 3436 SIMPLIFY_ALTERNATIVE (left);
41299f41
TW
3437 if (GET_CODE (left) == NOT)
3438 return XEXP (left, 0);
3439
3440 if (left == false_rtx)
1f8f4a0b 3441 return true_rtx;
41299f41 3442 else if (left == true_rtx)
1f8f4a0b 3443 return false_rtx;
41299f41
TW
3444
3445 /* Try to apply De`Morgan's laws. */
3446 else if (GET_CODE (left) == IOR)
3447 {
3e7b5313
TW
3448 newexp = attr_rtx (AND,
3449 attr_rtx (NOT, XEXP (left, 0)),
3450 attr_rtx (NOT, XEXP (left, 1)));
41299f41
TW
3451
3452 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3453 }
3454 else if (GET_CODE (left) == AND)
3455 {
3e7b5313
TW
3456 newexp = attr_rtx (IOR,
3457 attr_rtx (NOT, XEXP (left, 0)),
3458 attr_rtx (NOT, XEXP (left, 1)));
41299f41
TW
3459
3460 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3461 }
3462 else if (left != XEXP (exp, 0))
3463 {
3e7b5313 3464 newexp = attr_rtx (NOT, left);
41299f41
TW
3465 }
3466 break;
3467
3468 case EQ_ATTR:
3715a518
RS
3469 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3470 return (XSTR (exp, 1) == current_alternative_string
3471 ? true_rtx : false_rtx);
c9541287 3472
41299f41
TW
3473 /* Look at the value for this insn code in the specified attribute.
3474 We normally can replace this comparison with the condition that
3475 would give this insn the values being tested for. */
3476 if (XSTR (exp, 0) != alternative_name
3477 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3478 for (av = attr->first_value; av; av = av->next)
3479 for (ie = av->first_insn; ie; ie = ie->next)
3480 if (ie->insn_code == insn_code)
2bed3391
JH
3481 {
3482 rtx x;
2bed3391
JH
3483 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3484 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
2bed3391 3485 if (attr_rtx_cost(x) < 20)
2d515d60 3486 return x;
2bed3391 3487 }
e9a25f70 3488 break;
c9541287 3489
e9a25f70
JL
3490 default:
3491 break;
41299f41
TW
3492 }
3493
3494 /* We have already simplified this expression. Simplifying it again
3495 won't buy anything unless we weren't given a valid insn code
3496 to process (i.e., we are canonicalizing something.). */
45044655 3497 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3715a518
RS
3498 && ! RTX_UNCHANGING_P (newexp))
3499 return copy_rtx_unchanging (newexp);
41299f41
TW
3500
3501 return newexp;
3502}
3503\f
3504/* Optimize the attribute lists by seeing if we can determine conditional
3505 values from the known values of other attributes. This will save subroutine
3506 calls during the compilation. */
3507
3508static void
3509optimize_attrs ()
3510{
3511 struct attr_desc *attr;
3512 struct attr_value *av;
b5b6ad46 3513 struct insn_ent *ie;
41299f41 3514 rtx newexp;
85093b9c 3515 int i;
c9541287
KH
3516 struct attr_value_list
3517 {
3518 struct attr_value *av;
3519 struct insn_ent *ie;
3520 struct attr_desc *attr;
3521 struct attr_value_list *next;
3522 };
85093b9c 3523 struct attr_value_list **insn_code_values;
1c69865d 3524 struct attr_value_list *ivbuf;
85093b9c
RS
3525 struct attr_value_list *iv;
3526
3527 /* For each insn code, make a list of all the insn_ent's for it,
3528 for all values for all attributes. */
3529
bd1b0893
ILT
3530 if (num_insn_ents == 0)
3531 return;
3532
85093b9c
RS
3533 /* Make 2 extra elements, for "code" values -2 and -1. */
3534 insn_code_values
b548dffb 3535 = (struct attr_value_list **) xmalloc ((insn_code_number + 2)
85093b9c 3536 * sizeof (struct attr_value_list *));
961192e1 3537 memset ((char *) insn_code_values, 0,
85093b9c 3538 (insn_code_number + 2) * sizeof (struct attr_value_list *));
4c9a05bc 3539
85093b9c
RS
3540 /* Offset the table address so we can index by -2 or -1. */
3541 insn_code_values += 2;
3542
1c69865d
ILT
3543 iv = ivbuf = ((struct attr_value_list *)
3544 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3545
3715a518
RS
3546 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3547 for (attr = attrs[i]; attr; attr = attr->next)
3548 for (av = attr->first_value; av; av = av->next)
3549 for (ie = av->first_insn; ie; ie = ie->next)
3550 {
3715a518
RS
3551 iv->attr = attr;
3552 iv->av = av;
3553 iv->ie = ie;
3554 iv->next = insn_code_values[ie->insn_code];
3555 insn_code_values[ie->insn_code] = iv;
1c69865d 3556 iv++;
3715a518 3557 }
41299f41 3558
1c69865d
ILT
3559 /* Sanity check on num_insn_ents. */
3560 if (iv != ivbuf + num_insn_ents)
3561 abort ();
3562
3715a518
RS
3563 /* Process one insn code at a time. */
3564 for (i = -2; i < insn_code_number; i++)
41299f41 3565 {
3715a518
RS
3566 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3567 We use it to mean "already simplified for this insn". */
3568 for (iv = insn_code_values[i]; iv; iv = iv->next)
3569 clear_struct_flag (iv->av->value);
3570
2d515d60 3571 for (iv = insn_code_values[i]; iv; iv = iv->next)
85093b9c 3572 {
2d515d60 3573 struct obstack *old = rtl_obstack;
85093b9c 3574
2d515d60
JH
3575 attr = iv->attr;
3576 av = iv->av;
3577 ie = iv->ie;
3578 if (GET_CODE (av->value) != COND)
3579 continue;
85093b9c 3580
2d515d60 3581 rtl_obstack = temp_obstack;
3715a518 3582#if 0 /* This was intended as a speed up, but it was slower. */
2d515d60
JH
3583 if (insn_n_alternatives[ie->insn_code] > 6
3584 && count_sub_rtxs (av->value, 200) >= 200)
3585 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3586 ie->insn_index);
3587 else
3715a518 3588#endif
2d515d60
JH
3589 newexp = av->value;
3590 while (GET_CODE (newexp) == COND)
3591 {
3592 rtx newexp2 = simplify_cond (newexp, ie->insn_code,
3593 ie->insn_index);
3594 if (newexp2 == newexp)
3595 break;
3596 newexp = newexp2;
3597 }
3715a518 3598
2d515d60
JH
3599 rtl_obstack = old;
3600 if (newexp != av->value)
3601 {
3602 newexp = attr_copy_rtx (newexp);
3603 remove_insn_ent (av, ie);
3604 av = get_attr_value (newexp, attr, ie->insn_code);
3605 iv->av = av;
3606 insert_insn_ent (av, ie);
85093b9c
RS
3607 }
3608 }
3609 }
1c69865d
ILT
3610
3611 free (ivbuf);
b548dffb 3612 free (insn_code_values - 2);
85093b9c
RS
3613}
3614
b5b6ad46 3615#if 0
3715a518
RS
3616static rtx
3617simplify_by_alternatives (exp, insn_code, insn_index)
3618 rtx exp;
3619 int insn_code, insn_index;
3620{
3621 int i;
3622 int len = insn_n_alternatives[insn_code];
3623 rtx newexp = rtx_alloc (COND);
3624 rtx ultimate;
3625
3715a518
RS
3626 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3627
3628 /* It will not matter what value we use as the default value
3629 of the new COND, since that default will never be used.
3630 Choose something of the right type. */
3631 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3632 ultimate = XEXP (ultimate, 1);
3633 XEXP (newexp, 1) = ultimate;
3634
3635 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3636 {
3637 current_alternative_string = attr_numeral (i);
3638 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3639 XVECEXP (newexp, 0, i * 2 + 1)
3640 = simplify_cond (exp, insn_code, insn_index);
3641 }
3642
3643 current_alternative_string = 0;
3644 return simplify_cond (newexp, insn_code, insn_index);
3645}
b5b6ad46 3646#endif
3715a518 3647\f
72f1215c
TW
3648/* If EXP is a suitable expression, reorganize it by constructing an
3649 equivalent expression that is a COND with the tests being all combinations
3650 of attribute values and the values being simple constants. */
3651
3652static rtx
3653simplify_by_exploding (exp)
3654 rtx exp;
3655{
aefdd5ab 3656 rtx list = 0, link, condexp, defval = NULL_RTX;
72f1215c
TW
3657 struct dimension *space;
3658 rtx *condtest, *condval;
bee757e1 3659 int i, j, total, ndim = 0;
72f1215c 3660 int most_tests, num_marks, new_marks;
b548dffb 3661 rtx ret;
72f1215c
TW
3662
3663 /* Locate all the EQ_ATTR expressions. */
bee757e1 3664 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
72f1215c
TW
3665 {
3666 unmark_used_attributes (list, 0, 0);
3667 return exp;
3668 }
3669
3670 /* Create an attribute space from the list of used attributes. For each
3671 dimension in the attribute space, record the attribute, list of values
3672 used, and number of values used. Add members to the list of values to
3673 cover the domain of the attribute. This makes the expanded COND form
3674 order independent. */
3675
b548dffb 3676 space = (struct dimension *) xmalloc (ndim * sizeof (struct dimension));
72f1215c
TW
3677
3678 total = 1;
3679 for (ndim = 0; list; ndim++)
3680 {
3681 /* Pull the first attribute value from the list and record that
3682 attribute as another dimension in the attribute space. */
3cce094d 3683 const char *name = XSTR (XEXP (list, 0), 0);
72f1215c
TW
3684 rtx *prev;
3685
3686 if ((space[ndim].attr = find_attr (name, 0)) == 0
3687 || space[ndim].attr->is_numeric)
3688 {
3689 unmark_used_attributes (list, space, ndim);
3690 return exp;
3691 }
3692
3693 /* Add all remaining attribute values that refer to this attribute. */
3694 space[ndim].num_values = 0;
3695 space[ndim].values = 0;
3696 prev = &list;
3697 for (link = list; link; link = *prev)
3698 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3699 {
3700 space[ndim].num_values++;
3701 *prev = XEXP (link, 1);
3702 XEXP (link, 1) = space[ndim].values;
3703 space[ndim].values = link;
3704 }
3705 else
3706 prev = &XEXP (link, 1);
3707
3708 /* Add sufficient members to the list of values to make the list
3709 mutually exclusive and record the total size of the attribute
3710 space. */
3711 total *= add_values_to_cover (&space[ndim]);
3712 }
3713
3714 /* Sort the attribute space so that the attributes go from non-constant
3715 to constant and from most values to least values. */
3716 for (i = 0; i < ndim; i++)
3717 for (j = ndim - 1; j > i; j--)
3718 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3719 || space[j-1].num_values < space[j].num_values)
3720 {
3721 struct dimension tmp;
3722 tmp = space[j];
c9541287
KH
3723 space[j] = space[j - 1];
3724 space[j - 1] = tmp;
72f1215c
TW
3725 }
3726
3727 /* Establish the initial current value. */
3728 for (i = 0; i < ndim; i++)
3729 space[i].current_value = space[i].values;
3730
b548dffb
ZW
3731 condtest = (rtx *) xmalloc (total * sizeof (rtx));
3732 condval = (rtx *) xmalloc (total * sizeof (rtx));
72f1215c
TW
3733
3734 /* Expand the tests and values by iterating over all values in the
3735 attribute space. */
3736 for (i = 0;; i++)
3737 {
3738 condtest[i] = test_for_current_value (space, ndim);
3739 condval[i] = simplify_with_current_value (exp, space, ndim);
3740 if (! increment_current_value (space, ndim))
3741 break;
3742 }
3743 if (i != total - 1)
3744 abort ();
3745
3746 /* We are now finished with the original expression. */
3747 unmark_used_attributes (0, space, ndim);
b548dffb 3748 free (space);
72f1215c
TW
3749
3750 /* Find the most used constant value and make that the default. */
3751 most_tests = -1;
3752 for (i = num_marks = 0; i < total; i++)
3753 if (GET_CODE (condval[i]) == CONST_STRING
3754 && ! MEM_VOLATILE_P (condval[i]))
3755 {
3756 /* Mark the unmarked constant value and count how many are marked. */
3757 MEM_VOLATILE_P (condval[i]) = 1;
3758 for (j = new_marks = 0; j < total; j++)
3759 if (GET_CODE (condval[j]) == CONST_STRING
3760 && MEM_VOLATILE_P (condval[j]))
3761 new_marks++;
3762 if (new_marks - num_marks > most_tests)
3763 {
3764 most_tests = new_marks - num_marks;
3765 defval = condval[i];
3766 }
3767 num_marks = new_marks;
3768 }
3769 /* Clear all the marks. */
3770 for (i = 0; i < total; i++)
3771 MEM_VOLATILE_P (condval[i]) = 0;
3772
3773 /* Give up if nothing is constant. */
3774 if (num_marks == 0)
b548dffb
ZW
3775 ret = exp;
3776
bee757e1 3777 /* If all values are the default, use that. */
b548dffb
ZW
3778 else if (total == most_tests)
3779 ret = defval;
bee757e1 3780
72f1215c
TW
3781 /* Make a COND with the most common constant value the default. (A more
3782 complex method where tests with the same value were combined didn't
3783 seem to improve things.) */
b548dffb
ZW
3784 else
3785 {
3786 condexp = rtx_alloc (COND);
3787 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3788 XEXP (condexp, 1) = defval;
3789 for (i = j = 0; i < total; i++)
3790 if (condval[i] != defval)
3791 {
3792 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3793 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3794 j++;
3795 }
3796 ret = condexp;
3797 }
3798 free (condtest);
3799 free (condval);
3800 return ret;
72f1215c
TW
3801}
3802
3803/* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3804 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3805 tests have known value. */
3806
3807static int
bee757e1 3808find_and_mark_used_attributes (exp, terms, nterms)
72f1215c 3809 rtx exp, *terms;
bee757e1 3810 int *nterms;
72f1215c
TW
3811{
3812 int i;
3813
3814 switch (GET_CODE (exp))
3815 {
3816 case EQ_ATTR:
3817 if (! MEM_VOLATILE_P (exp))
3818 {
3819 rtx link = rtx_alloc (EXPR_LIST);
3820 XEXP (link, 0) = exp;
3821 XEXP (link, 1) = *terms;
3822 *terms = link;
bee757e1 3823 *nterms += 1;
72f1215c
TW
3824 MEM_VOLATILE_P (exp) = 1;
3825 }
7ee37ba4
RH
3826 return 1;
3827
72f1215c 3828 case CONST_STRING:
5830e3a0 3829 case CONST_INT:
72f1215c
TW
3830 return 1;
3831
3832 case IF_THEN_ELSE:
bee757e1 3833 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
72f1215c
TW
3834 return 0;
3835 case IOR:
3836 case AND:
bee757e1 3837 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
72f1215c
TW
3838 return 0;
3839 case NOT:
bee757e1 3840 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
72f1215c
TW
3841 return 0;
3842 return 1;
3843
3844 case COND:
3845 for (i = 0; i < XVECLEN (exp, 0); i++)
bee757e1 3846 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
72f1215c 3847 return 0;
bee757e1 3848 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
72f1215c
TW
3849 return 0;
3850 return 1;
72f1215c 3851
e9a25f70
JL
3852 default:
3853 return 0;
3854 }
72f1215c
TW
3855}
3856
3857/* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3858 in the values of the NDIM-dimensional attribute space SPACE. */
3859
3860static void
3861unmark_used_attributes (list, space, ndim)
3862 rtx list;
3863 struct dimension *space;
3864 int ndim;
3865{
3866 rtx link, exp;
3867 int i;
3868
3869 for (i = 0; i < ndim; i++)
3870 unmark_used_attributes (space[i].values, 0, 0);
3871
3872 for (link = list; link; link = XEXP (link, 1))
3873 {
3874 exp = XEXP (link, 0);
3875 if (GET_CODE (exp) == EQ_ATTR)
3876 MEM_VOLATILE_P (exp) = 0;
3877 }
3878}
3879
3880/* Update the attribute dimension DIM so that all values of the attribute
3881 are tested. Return the updated number of values. */
3882
3883static int
3884add_values_to_cover (dim)
3885 struct dimension *dim;
3886{
3887 struct attr_value *av;
3888 rtx exp, link, *prev;
3889 int nalt = 0;
3890
3891 for (av = dim->attr->first_value; av; av = av->next)
3892 if (GET_CODE (av->value) == CONST_STRING)
3893 nalt++;
3894
3895 if (nalt < dim->num_values)
3896 abort ();
3897 else if (nalt == dim->num_values)
c9541287
KH
3898 /* OK. */
3899 ;
5830e3a0 3900 else if (nalt * 2 < dim->num_values * 3)
72f1215c
TW
3901 {
3902 /* Most all the values of the attribute are used, so add all the unused
3903 values. */
3904 prev = &dim->values;
3905 for (link = dim->values; link; link = *prev)
3906 prev = &XEXP (link, 1);
3907
3908 for (av = dim->attr->first_value; av; av = av->next)
3909 if (GET_CODE (av->value) == CONST_STRING)
3910 {
3911 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3912 if (MEM_VOLATILE_P (exp))
3913 continue;
3914
3915 link = rtx_alloc (EXPR_LIST);
3916 XEXP (link, 0) = exp;
3917 XEXP (link, 1) = 0;
3918 *prev = link;
3919 prev = &XEXP (link, 1);
3920 }
3921 dim->num_values = nalt;
3922 }
3923 else
3924 {
3925 rtx orexp = false_rtx;
3926
3927 /* Very few values are used, so compute a mutually exclusive
3928 expression. (We could do this for numeric values if that becomes
3929 important.) */
3930 prev = &dim->values;
3931 for (link = dim->values; link; link = *prev)
3932 {
f75d38a7 3933 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
72f1215c
TW
3934 prev = &XEXP (link, 1);
3935 }
3936 link = rtx_alloc (EXPR_LIST);
3937 XEXP (link, 0) = attr_rtx (NOT, orexp);
3938 XEXP (link, 1) = 0;
3939 *prev = link;
3940 dim->num_values++;
3941 }
3942 return dim->num_values;
3943}
3944
3945/* Increment the current value for the NDIM-dimensional attribute space SPACE
3946 and return FALSE if the increment overflowed. */
3947
3948static int
3949increment_current_value (space, ndim)
3950 struct dimension *space;
3951 int ndim;
3952{
3953 int i;
3954
3955 for (i = ndim - 1; i >= 0; i--)
3956 {
3957 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3958 space[i].current_value = space[i].values;
3959 else
3960 return 1;
3961 }
3962 return 0;
3963}
3964
3965/* Construct an expression corresponding to the current value for the
3966 NDIM-dimensional attribute space SPACE. */
3967
3968static rtx
3969test_for_current_value (space, ndim)
3970 struct dimension *space;
3971 int ndim;
3972{
3973 int i;
3974 rtx exp = true_rtx;
3975
3976 for (i = 0; i < ndim; i++)
f75d38a7
RK
3977 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3978 -2, -2);
72f1215c
TW
3979
3980 return exp;
3981}
3982
3983/* Given the current value of the NDIM-dimensional attribute space SPACE,
3984 set the corresponding EQ_ATTR expressions to that value and reduce
3985 the expression EXP as much as possible. On input [and output], all
3986 known EQ_ATTR expressions are set to FALSE. */
3987
3988static rtx
3989simplify_with_current_value (exp, space, ndim)
3990 rtx exp;
3991 struct dimension *space;
3992 int ndim;
3993{
3994 int i;
3995 rtx x;
3996
3997 /* Mark each current value as TRUE. */
3998 for (i = 0; i < ndim; i++)
3999 {
4000 x = XEXP (space[i].current_value, 0);
4001 if (GET_CODE (x) == EQ_ATTR)
4002 MEM_VOLATILE_P (x) = 0;
4003 }
4004
4005 exp = simplify_with_current_value_aux (exp);
4006
4007 /* Change each current value back to FALSE. */
4008 for (i = 0; i < ndim; i++)
4009 {
4010 x = XEXP (space[i].current_value, 0);
4011 if (GET_CODE (x) == EQ_ATTR)
4012 MEM_VOLATILE_P (x) = 1;
4013 }
b5b6ad46
MM
4014
4015 return exp;
72f1215c
TW
4016}
4017
4018/* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
4019 all EQ_ATTR expressions. */
4020
4021static rtx
4022simplify_with_current_value_aux (exp)
4023 rtx exp;
4024{
4025 register int i;
4026 rtx cond;
4027
4028 switch (GET_CODE (exp))
4029 {
4030 case EQ_ATTR:
4031 if (MEM_VOLATILE_P (exp))
4032 return false_rtx;
4033 else
4034 return true_rtx;
4035 case CONST_STRING:
5830e3a0 4036 case CONST_INT:
72f1215c
TW
4037 return exp;
4038
4039 case IF_THEN_ELSE:
4040 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4041 if (cond == true_rtx)
4042 return simplify_with_current_value_aux (XEXP (exp, 1));
4043 else if (cond == false_rtx)
4044 return simplify_with_current_value_aux (XEXP (exp, 2));
4045 else
4046 return attr_rtx (IF_THEN_ELSE, cond,
4047 simplify_with_current_value_aux (XEXP (exp, 1)),
4048 simplify_with_current_value_aux (XEXP (exp, 2)));
4049
4050 case IOR:
4051 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4052 if (cond == true_rtx)
4053 return cond;
4054 else if (cond == false_rtx)
4055 return simplify_with_current_value_aux (XEXP (exp, 0));
4056 else
4057 return attr_rtx (IOR, cond,
4058 simplify_with_current_value_aux (XEXP (exp, 0)));
4059
4060 case AND:
4061 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4062 if (cond == true_rtx)
4063 return simplify_with_current_value_aux (XEXP (exp, 0));
4064 else if (cond == false_rtx)
4065 return cond;
4066 else
4067 return attr_rtx (AND, cond,
4068 simplify_with_current_value_aux (XEXP (exp, 0)));
4069
4070 case NOT:
4071 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4072 if (cond == true_rtx)
4073 return false_rtx;
4074 else if (cond == false_rtx)
4075 return true_rtx;
4076 else
4077 return attr_rtx (NOT, cond);
4078
4079 case COND:
4080 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4081 {
4082 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
4083 if (cond == true_rtx)
4084 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4085 else if (cond == false_rtx)
4086 continue;
4087 else
4088 abort (); /* With all EQ_ATTR's of known value, a case should
4089 have been selected. */
4090 }
4091 return simplify_with_current_value_aux (XEXP (exp, 1));
e9a25f70
JL
4092
4093 default:
4094 abort ();
72f1215c 4095 }
72f1215c
TW
4096}
4097\f
85093b9c
RS
4098/* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4099
9a63e81d 4100static void
85093b9c
RS
4101clear_struct_flag (x)
4102 rtx x;
4103{
4104 register int i;
4105 register int j;
4106 register enum rtx_code code;
6f7d635c 4107 register const char *fmt;
85093b9c
RS
4108
4109 MEM_IN_STRUCT_P (x) = 0;
4110 if (RTX_UNCHANGING_P (x))
4111 return;
4112
4113 code = GET_CODE (x);
4114
4115 switch (code)
4116 {
4117 case REG:
4118 case QUEUED:
4119 case CONST_INT:
4120 case CONST_DOUBLE:
4121 case SYMBOL_REF:
4122 case CODE_LABEL:
4123 case PC:
4124 case CC0:
4125 case EQ_ATTR:
0b0316dc 4126 case ATTR_FLAG:
85093b9c 4127 return;
c9541287 4128
e9a25f70
JL
4129 default:
4130 break;
85093b9c
RS
4131 }
4132
4133 /* Compare the elements. If any pair of corresponding elements
4134 fail to match, return 0 for the whole things. */
4135
4136 fmt = GET_RTX_FORMAT (code);
4137 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4138 {
4139 switch (fmt[i])
4140 {
4141 case 'V':
4142 case 'E':
85093b9c
RS
4143 for (j = 0; j < XVECLEN (x, i); j++)
4144 clear_struct_flag (XVECEXP (x, i, j));
4145 break;
4146
4147 case 'e':
4148 clear_struct_flag (XEXP (x, i));
4149 break;
4150 }
41299f41
TW
4151 }
4152}
3715a518
RS
4153
4154/* Return the number of RTX objects making up the expression X.
38e01259 4155 But if we count more than MAX objects, stop counting. */
3715a518 4156
9a63e81d 4157static int
3715a518
RS
4158count_sub_rtxs (x, max)
4159 rtx x;
4160 int max;
4161{
4162 register int i;
4163 register int j;
4164 register enum rtx_code code;
6f7d635c 4165 register const char *fmt;
3715a518
RS
4166 int total = 0;
4167
4168 code = GET_CODE (x);
4169
4170 switch (code)
4171 {
4172 case REG:
4173 case QUEUED:
4174 case CONST_INT:
4175 case CONST_DOUBLE:
4176 case SYMBOL_REF:
4177 case CODE_LABEL:
4178 case PC:
4179 case CC0:
4180 case EQ_ATTR:
0b0316dc 4181 case ATTR_FLAG:
3715a518 4182 return 1;
c9541287 4183
e9a25f70
JL
4184 default:
4185 break;
3715a518
RS
4186 }
4187
4188 /* Compare the elements. If any pair of corresponding elements
4189 fail to match, return 0 for the whole things. */
4190
4191 fmt = GET_RTX_FORMAT (code);
4192 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4193 {
4194 if (total >= max)
4195 return total;
4196
4197 switch (fmt[i])
4198 {
4199 case 'V':
4200 case 'E':
4201 for (j = 0; j < XVECLEN (x, i); j++)
4202 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4203 break;
4204
4205 case 'e':
4206 total += count_sub_rtxs (XEXP (x, i), max);
4207 break;
4208 }
4209 }
4210 return total;
4211
4212}
41299f41
TW
4213\f
4214/* Create table entries for DEFINE_ATTR. */
4215
4216static void
a4cad544 4217gen_attr (exp, lineno)
41299f41 4218 rtx exp;
a4cad544 4219 int lineno;
41299f41
TW
4220{
4221 struct attr_desc *attr;
4222 struct attr_value *av;
3cce094d 4223 const char *name_ptr;
41299f41
TW
4224 char *p;
4225
4226 /* Make a new attribute structure. Check for duplicate by looking at
4227 attr->default_val, since it is initialized by this routine. */
4228 attr = find_attr (XSTR (exp, 0), 1);
4229 if (attr->default_val)
a4cad544
RH
4230 {
4231 message_with_line (lineno, "duplicate definition for attribute %s",
4232 attr->name);
4233 message_with_line (attr->lineno, "previous definition");
4234 have_error = 1;
4235 return;
4236 }
4237 attr->lineno = lineno;
41299f41
TW
4238
4239 if (*XSTR (exp, 1) == '\0')
7ee37ba4 4240 attr->is_numeric = 1;
41299f41
TW
4241 else
4242 {
4243 name_ptr = XSTR (exp, 1);
4244 while ((p = next_comma_elt (&name_ptr)) != NULL)
4245 {
0e9414fd 4246 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
3e7b5313 4247 av->value = attr_rtx (CONST_STRING, p);
41299f41
TW
4248 av->next = attr->first_value;
4249 attr->first_value = av;
4250 av->first_insn = NULL;
4251 av->num_insns = 0;
4252 av->has_asm_insn = 0;
4253 }
4254 }
4255
3e7b5313
TW
4256 if (GET_CODE (XEXP (exp, 2)) == CONST)
4257 {
4258 attr->is_const = 1;
4259 if (attr->is_numeric)
a4cad544
RH
4260 {
4261 message_with_line (lineno,
4262 "constant attributes may not take numeric values");
4263 have_error = 1;
4264 }
4265
3e7b5313
TW
4266 /* Get rid of the CONST node. It is allowed only at top-level. */
4267 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4268 }
4269
41299f41 4270 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
a4cad544 4271 {
c9541287
KH
4272 message_with_line (lineno,
4273 "`length' attribute must take numeric values");
a4cad544
RH
4274 have_error = 1;
4275 }
41299f41 4276
0f41302f 4277 /* Set up the default value. */
81fd4c6e 4278 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
41299f41
TW
4279 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4280}
4281\f
4282/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4283 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4284 number of alternatives as this should be checked elsewhere. */
4285
4286static int
4287count_alternatives (exp)
4288 rtx exp;
4289{
4290 int i, j, n;
6f7d635c 4291 const char *fmt;
c9541287 4292
41299f41
TW
4293 if (GET_CODE (exp) == MATCH_OPERAND)
4294 return n_comma_elts (XSTR (exp, 2));
4295
4296 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4297 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4298 switch (*fmt++)
4299 {
4300 case 'e':
4301 case 'u':
4302 n = count_alternatives (XEXP (exp, i));
4303 if (n)
4304 return n;
4305 break;
4306
4307 case 'E':
4308 case 'V':
4309 if (XVEC (exp, i) != NULL)
4310 for (j = 0; j < XVECLEN (exp, i); j++)
4311 {
4312 n = count_alternatives (XVECEXP (exp, i, j));
4313 if (n)
4314 return n;
4315 }
4316 }
4317
4318 return 0;
4319}
4320\f
4321/* Returns non-zero if the given expression contains an EQ_ATTR with the
4322 `alternative' attribute. */
4323
4324static int
4325compares_alternatives_p (exp)
4326 rtx exp;
4327{
4328 int i, j;
6f7d635c 4329 const char *fmt;
41299f41
TW
4330
4331 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4332 return 1;
4333
4334 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4335 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4336 switch (*fmt++)
4337 {
4338 case 'e':
4339 case 'u':
4340 if (compares_alternatives_p (XEXP (exp, i)))
4341 return 1;
4342 break;
4343
4344 case 'E':
4345 for (j = 0; j < XVECLEN (exp, i); j++)
4346 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4347 return 1;
4348 break;
4349 }
4350
4351 return 0;
4352}
4353\f
4354/* Returns non-zero is INNER is contained in EXP. */
4355
4356static int
4357contained_in_p (inner, exp)
4358 rtx inner;
4359 rtx exp;
4360{
4361 int i, j;
6f7d635c 4362 const char *fmt;
41299f41
TW
4363
4364 if (rtx_equal_p (inner, exp))
4365 return 1;
4366
4367 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4368 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4369 switch (*fmt++)
4370 {
4371 case 'e':
4372 case 'u':
4373 if (contained_in_p (inner, XEXP (exp, i)))
4374 return 1;
4375 break;
4376
4377 case 'E':
4378 for (j = 0; j < XVECLEN (exp, i); j++)
4379 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4380 return 1;
4381 break;
4382 }
4383
4384 return 0;
4385}
c9541287 4386\f
41299f41
TW
4387/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4388
4389static void
a4cad544 4390gen_insn (exp, lineno)
41299f41 4391 rtx exp;
a4cad544 4392 int lineno;
41299f41
TW
4393{
4394 struct insn_def *id;
4395
0e9414fd 4396 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
41299f41
TW
4397 id->next = defs;
4398 defs = id;
4399 id->def = exp;
a4cad544 4400 id->lineno = lineno;
41299f41
TW
4401
4402 switch (GET_CODE (exp))
4403 {
4404 case DEFINE_INSN:
c88c0d42
CP
4405 id->insn_code = insn_code_number;
4406 id->insn_index = insn_index_number;
41299f41
TW
4407 id->num_alternatives = count_alternatives (exp);
4408 if (id->num_alternatives == 0)
4409 id->num_alternatives = 1;
4410 id->vec_idx = 4;
4411 break;
4412
4413 case DEFINE_PEEPHOLE:
c88c0d42
CP
4414 id->insn_code = insn_code_number;
4415 id->insn_index = insn_index_number;
41299f41
TW
4416 id->num_alternatives = count_alternatives (exp);
4417 if (id->num_alternatives == 0)
4418 id->num_alternatives = 1;
4419 id->vec_idx = 3;
4420 break;
4421
4422 case DEFINE_ASM_ATTRIBUTES:
4423 id->insn_code = -1;
4424 id->insn_index = -1;
4425 id->num_alternatives = 1;
4426 id->vec_idx = 0;
4427 got_define_asm_attributes = 1;
4428 break;
c9541287 4429
e9a25f70
JL
4430 default:
4431 abort ();
41299f41
TW
4432 }
4433}
4434\f
4435/* Process a DEFINE_DELAY. Validate the vector length, check if annul
4436 true or annul false is specified, and make a `struct delay_desc'. */
4437
4438static void
a4cad544 4439gen_delay (def, lineno)
41299f41 4440 rtx def;
a4cad544 4441 int lineno;
41299f41
TW
4442{
4443 struct delay_desc *delay;
4444 int i;
4445
4446 if (XVECLEN (def, 1) % 3 != 0)
a4cad544
RH
4447 {
4448 message_with_line (lineno,
c9541287 4449 "number of elements in DEFINE_DELAY must be multiple of three");
a4cad544
RH
4450 have_error = 1;
4451 return;
4452 }
41299f41
TW
4453
4454 for (i = 0; i < XVECLEN (def, 1); i += 3)
4455 {
4456 if (XVECEXP (def, 1, i + 1))
4457 have_annul_true = 1;
4458 if (XVECEXP (def, 1, i + 2))
4459 have_annul_false = 1;
4460 }
c9541287 4461
0e9414fd 4462 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
41299f41
TW
4463 delay->def = def;
4464 delay->num = ++num_delays;
4465 delay->next = delays;
a4cad544 4466 delay->lineno = lineno;
41299f41
TW
4467 delays = delay;
4468}
4469\f
c9541287 4470/* Process a DEFINE_FUNCTION_UNIT.
41299f41
TW
4471
4472 This gives information about a function unit contained in the CPU.
4473 We fill in a `struct function_unit_op' and a `struct function_unit'
4474 with information used later by `expand_unit'. */
4475
4476static void
a4cad544 4477gen_unit (def, lineno)
41299f41 4478 rtx def;
a4cad544 4479 int lineno;
41299f41
TW
4480{
4481 struct function_unit *unit;
4482 struct function_unit_op *op;
3cce094d 4483 const char *name = XSTR (def, 0);
bee757e1
TW
4484 int multiplicity = XINT (def, 1);
4485 int simultaneity = XINT (def, 2);
4486 rtx condexp = XEXP (def, 3);
4487 int ready_cost = MAX (XINT (def, 4), 1);
4488 int issue_delay = MAX (XINT (def, 5), 1);
41299f41
TW
4489
4490 /* See if we have already seen this function unit. If so, check that
6dc42e49 4491 the multiplicity and simultaneity values are the same. If not, make
41299f41
TW
4492 a structure for this function unit. */
4493 for (unit = units; unit; unit = unit->next)
bee757e1 4494 if (! strcmp (unit->name, name))
41299f41 4495 {
bee757e1
TW
4496 if (unit->multiplicity != multiplicity
4497 || unit->simultaneity != simultaneity)
a4cad544
RH
4498 {
4499 message_with_line (lineno,
c9541287
KH
4500 "differing specifications given for function unit %s",
4501 unit->name);
a4cad544
RH
4502 message_with_line (unit->first_lineno, "previous definition");
4503 have_error = 1;
4504 return;
4505 }
41299f41
TW
4506 break;
4507 }
4508
4509 if (unit == 0)
4510 {
0e9414fd 4511 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
bee757e1
TW
4512 unit->name = name;
4513 unit->multiplicity = multiplicity;
4514 unit->simultaneity = simultaneity;
4515 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
41299f41
TW
4516 unit->num = num_units++;
4517 unit->num_opclasses = 0;
4518 unit->condexp = false_rtx;
4519 unit->ops = 0;
4520 unit->next = units;
a4cad544 4521 unit->first_lineno = lineno;
41299f41
TW
4522 units = unit;
4523 }
4524
4525 /* Make a new operation class structure entry and initialize it. */
0e9414fd 4526 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
bee757e1 4527 op->condexp = condexp;
41299f41 4528 op->num = unit->num_opclasses++;
bee757e1
TW
4529 op->ready = ready_cost;
4530 op->issue_delay = issue_delay;
41299f41 4531 op->next = unit->ops;
a4cad544 4532 op->lineno = lineno;
41299f41 4533 unit->ops = op;
71d9b493 4534 num_unit_opclasses++;
41299f41 4535
bee757e1 4536 /* Set our issue expression based on whether or not an optional conflict
41299f41
TW
4537 vector was specified. */
4538 if (XVEC (def, 6))
4539 {
4540 /* Compute the IOR of all the specified expressions. */
4541 rtx orexp = false_rtx;
4542 int i;
4543
4544 for (i = 0; i < XVECLEN (def, 6); i++)
f75d38a7 4545 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
41299f41 4546
bee757e1
TW
4547 op->conflict_exp = orexp;
4548 extend_range (&unit->issue_delay, 1, issue_delay);
41299f41
TW
4549 }
4550 else
72f1215c 4551 {
bee757e1
TW
4552 op->conflict_exp = true_rtx;
4553 extend_range (&unit->issue_delay, issue_delay, issue_delay);
72f1215c 4554 }
41299f41
TW
4555
4556 /* Merge our conditional into that of the function unit so we can determine
4557 which insns are used by the function unit. */
f75d38a7 4558 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
41299f41
TW
4559}
4560\f
9ec36da5 4561/* Given a piece of RTX, print a C expression to test its truth value.
c9541287 4562 We use AND and IOR both for logical and bit-wise operations, so
41299f41 4563 interpret them as logical unless they are inside a comparison expression.
71d9b493
RH
4564 The first bit of FLAGS will be non-zero in that case.
4565
4566 Set the second bit of FLAGS to make references to attribute values use
4567 a cached local variable instead of calling a function. */
41299f41
TW
4568
4569static void
71d9b493 4570write_test_expr (exp, flags)
41299f41 4571 rtx exp;
71d9b493 4572 int flags;
41299f41
TW
4573{
4574 int comparison_operator = 0;
4575 RTX_CODE code;
4576 struct attr_desc *attr;
4577
4578 /* In order not to worry about operator precedence, surround our part of
4579 the expression with parentheses. */
4580
4581 printf ("(");
4582 code = GET_CODE (exp);
4583 switch (code)
4584 {
4585 /* Binary operators. */
4586 case EQ: case NE:
4587 case GE: case GT: case GEU: case GTU:
4588 case LE: case LT: case LEU: case LTU:
4589 comparison_operator = 1;
4590
4591 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4592 case AND: case IOR: case XOR:
45620ed4 4593 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
71d9b493 4594 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
41299f41 4595 switch (code)
c9541287 4596 {
41299f41
TW
4597 case EQ:
4598 printf (" == ");
4599 break;
4600 case NE:
4601 printf (" != ");
4602 break;
4603 case GE:
4604 printf (" >= ");
4605 break;
4606 case GT:
4607 printf (" > ");
4608 break;
4609 case GEU:
4610 printf (" >= (unsigned) ");
4611 break;
4612 case GTU:
4613 printf (" > (unsigned) ");
4614 break;
4615 case LE:
4616 printf (" <= ");
4617 break;
4618 case LT:
4619 printf (" < ");
4620 break;
4621 case LEU:
4622 printf (" <= (unsigned) ");
4623 break;
4624 case LTU:
4625 printf (" < (unsigned) ");
4626 break;
4627 case PLUS:
4628 printf (" + ");
4629 break;
4630 case MINUS:
4631 printf (" - ");
4632 break;
4633 case MULT:
4634 printf (" * ");
4635 break;
4636 case DIV:
4637 printf (" / ");
4638 break;
4639 case MOD:
412dc348 4640 printf (" %% ");
41299f41
TW
4641 break;
4642 case AND:
71d9b493 4643 if (flags & 1)
41299f41
TW
4644 printf (" & ");
4645 else
4646 printf (" && ");
4647 break;
4648 case IOR:
71d9b493 4649 if (flags & 1)
41299f41
TW
4650 printf (" | ");
4651 else
4652 printf (" || ");
4653 break;
4654 case XOR:
4655 printf (" ^ ");
4656 break;
41299f41
TW
4657 case ASHIFT:
4658 printf (" << ");
4659 break;
4660 case LSHIFTRT:
4661 case ASHIFTRT:
4662 printf (" >> ");
4663 break;
e9a25f70
JL
4664 default:
4665 abort ();
c9541287 4666 }
41299f41 4667
71d9b493 4668 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
41299f41
TW
4669 break;
4670
4671 case NOT:
4672 /* Special-case (not (eq_attrq "alternative" "x")) */
71d9b493 4673 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
41299f41
TW
4674 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4675 {
4676 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4677 break;
4678 }
4679
4680 /* Otherwise, fall through to normal unary operator. */
4681
c9541287 4682 /* Unary operators. */
41299f41
TW
4683 case ABS: case NEG:
4684 switch (code)
4685 {
4686 case NOT:
71d9b493 4687 if (flags & 1)
41299f41
TW
4688 printf ("~ ");
4689 else
4690 printf ("! ");
4691 break;
4692 case ABS:
4693 printf ("abs ");
4694 break;
4695 case NEG:
4696 printf ("-");
4697 break;
e9a25f70
JL
4698 default:
4699 abort ();
41299f41
TW
4700 }
4701
71d9b493 4702 write_test_expr (XEXP (exp, 0), flags);
41299f41
TW
4703 break;
4704
4705 /* Comparison test of an attribute with a value. Most of these will
4706 have been removed by optimization. Handle "alternative"
4707 specially and give error if EQ_ATTR present inside a comparison. */
4708 case EQ_ATTR:
71d9b493 4709 if (flags & 1)
41299f41
TW
4710 fatal ("EQ_ATTR not valid inside comparison");
4711
4712 if (XSTR (exp, 0) == alternative_name)
4713 {
4714 printf ("which_alternative == %s", XSTR (exp, 1));
4715 break;
4716 }
4717
4718 attr = find_attr (XSTR (exp, 0), 0);
c9541287
KH
4719 if (! attr)
4720 abort ();
b31a5831
RS
4721
4722 /* Now is the time to expand the value of a constant attribute. */
4723 if (attr->is_const)
4724 {
4725 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
dedb78d4 4726 -2, -2),
71d9b493 4727 flags);
b31a5831
RS
4728 }
4729 else
4730 {
71d9b493
RH
4731 if (flags & 2)
4732 printf ("attr_%s", attr->name);
4733 else
4734 printf ("get_attr_%s (insn)", attr->name);
4735 printf (" == ");
4736 write_attr_valueq (attr, XSTR (exp, 1));
b31a5831 4737 }
41299f41
TW
4738 break;
4739
0b0316dc
JL
4740 /* Comparison test of flags for define_delays. */
4741 case ATTR_FLAG:
71d9b493 4742 if (flags & 1)
0b0316dc
JL
4743 fatal ("ATTR_FLAG not valid inside comparison");
4744 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4745 break;
4746
41299f41
TW
4747 /* See if an operand matches a predicate. */
4748 case MATCH_OPERAND:
4749 /* If only a mode is given, just ensure the mode matches the operand.
4750 If neither a mode nor predicate is given, error. */
c9541287 4751 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
41299f41
TW
4752 {
4753 if (GET_MODE (exp) == VOIDmode)
4754 fatal ("Null MATCH_OPERAND specified as test");
4755 else
4756 printf ("GET_MODE (operands[%d]) == %smode",
4757 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4758 }
4759 else
4760 printf ("%s (operands[%d], %smode)",
4761 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4762 break;
4763
8450a694
JC
4764 case MATCH_INSN:
4765 printf ("%s (insn)", XSTR (exp, 0));
4766 break;
4767
0f41302f 4768 /* Constant integer. */
41299f41 4769 case CONST_INT:
76d31c63 4770 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
41299f41
TW
4771 break;
4772
0f41302f 4773 /* A random C expression. */
41299f41
TW
4774 case SYMBOL_REF:
4775 printf ("%s", XSTR (exp, 0));
4776 break;
4777
4778 /* The address of the branch target. */
4779 case MATCH_DUP:
a4cad544 4780 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
5ab7138b 4781 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
41299f41
TW
4782 break;
4783
41299f41 4784 case PC:
fc470718
R
4785 /* The address of the current insn. We implement this actually as the
4786 address of the current insn for backward branches, but the last
4787 address of the next insn for forward branches, and both with
4788 adjustments that account for the worst-case possible stretching of
4789 intervening alignments between this insn and its destination. */
c9541287 4790 printf ("insn_current_reference_address (insn)");
41299f41
TW
4791 break;
4792
71d9b493
RH
4793 case CONST_STRING:
4794 printf ("%s", XSTR (exp, 0));
4795 break;
4796
4797 case IF_THEN_ELSE:
4798 write_test_expr (XEXP (exp, 0), flags & 2);
4799 printf (" ? ");
4800 write_test_expr (XEXP (exp, 1), flags | 1);
4801 printf (" : ");
4802 write_test_expr (XEXP (exp, 2), flags | 1);
4803 break;
4804
41299f41
TW
4805 default:
4806 fatal ("bad RTX code `%s' in attribute calculation\n",
4807 GET_RTX_NAME (code));
4808 }
4809
4810 printf (")");
4811}
4812\f
4813/* Given an attribute value, return the maximum CONST_STRING argument
7ee37ba4 4814 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
41299f41
TW
4815
4816static int
7ee37ba4 4817max_attr_value (exp, unknownp)
41299f41 4818 rtx exp;
7ee37ba4 4819 int *unknownp;
41299f41 4820{
7ee37ba4
RH
4821 int current_max;
4822 int i, n;
41299f41 4823
7ee37ba4 4824 switch (GET_CODE (exp))
41299f41 4825 {
7ee37ba4
RH
4826 case CONST_STRING:
4827 current_max = atoi (XSTR (exp, 0));
4828 break;
4829
4830 case COND:
4831 current_max = max_attr_value (XEXP (exp, 1), unknownp);
41299f41
TW
4832 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4833 {
7ee37ba4 4834 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
41299f41
TW
4835 if (n > current_max)
4836 current_max = n;
4837 }
7ee37ba4 4838 break;
41299f41 4839
7ee37ba4
RH
4840 case IF_THEN_ELSE:
4841 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4842 n = max_attr_value (XEXP (exp, 2), unknownp);
41299f41
TW
4843 if (n > current_max)
4844 current_max = n;
7ee37ba4 4845 break;
41299f41 4846
7ee37ba4
RH
4847 default:
4848 *unknownp = 1;
4849 current_max = INT_MAX;
4850 break;
bee757e1
TW
4851 }
4852
41299f41
TW
4853 return current_max;
4854}
fc470718
R
4855
4856/* Given an attribute value, return the result of ORing together all
7ee37ba4
RH
4857 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4858 if the numeric value is not known. */
fc470718
R
4859
4860static int
7ee37ba4 4861or_attr_value (exp, unknownp)
fc470718 4862 rtx exp;
7ee37ba4 4863 int *unknownp;
fc470718 4864{
7ee37ba4 4865 int current_or;
fc470718
R
4866 int i;
4867
7ee37ba4 4868 switch (GET_CODE (exp))
fc470718 4869 {
7ee37ba4
RH
4870 case CONST_STRING:
4871 current_or = atoi (XSTR (exp, 0));
4872 break;
4873
4874 case COND:
4875 current_or = or_attr_value (XEXP (exp, 1), unknownp);
fc470718 4876 for (i = 0; i < XVECLEN (exp, 0); i += 2)
7ee37ba4
RH
4877 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4878 break;
fc470718 4879
7ee37ba4
RH
4880 case IF_THEN_ELSE:
4881 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4882 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4883 break;
fc470718 4884
7ee37ba4
RH
4885 default:
4886 *unknownp = 1;
4887 current_or = -1;
4888 break;
fc470718
R
4889 }
4890
fc470718
R
4891 return current_or;
4892}
41299f41
TW
4893\f
4894/* Scan an attribute value, possibly a conditional, and record what actions
4895 will be required to do any conditional tests in it.
4896
4897 Specifically, set
4898 `must_extract' if we need to extract the insn operands
4899 `must_constrain' if we must compute `which_alternative'
4900 `address_used' if an address expression was used
d7c665bf 4901 `length_used' if an (eq_attr "length" ...) was used
41299f41
TW
4902 */
4903
4904static void
4905walk_attr_value (exp)
4906 rtx exp;
4907{
4908 register int i, j;
6f7d635c 4909 register const char *fmt;
41299f41
TW
4910 RTX_CODE code;
4911
4912 if (exp == NULL)
4913 return;
4914
4915 code = GET_CODE (exp);
4916 switch (code)
4917 {
4918 case SYMBOL_REF:
3e7b5313
TW
4919 if (! RTX_UNCHANGING_P (exp))
4920 /* Since this is an arbitrary expression, it can look at anything.
4921 However, constant expressions do not depend on any particular
4922 insn. */
4923 must_extract = must_constrain = 1;
41299f41
TW
4924 return;
4925
4926 case MATCH_OPERAND:
4927 must_extract = 1;
4928 return;
4929
4930 case EQ_ATTR:
4931 if (XSTR (exp, 0) == alternative_name)
4932 must_extract = must_constrain = 1;
d7c665bf
RK
4933 else if (strcmp (XSTR (exp, 0), "length") == 0)
4934 length_used = 1;
41299f41
TW
4935 return;
4936
4937 case MATCH_DUP:
426cd2f4
RK
4938 must_extract = 1;
4939 address_used = 1;
4940 return;
4941
41299f41
TW
4942 case PC:
4943 address_used = 1;
4944 return;
0b0316dc
JL
4945
4946 case ATTR_FLAG:
4947 return;
e9a25f70
JL
4948
4949 default:
4950 break;
41299f41
TW
4951 }
4952
4953 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4954 switch (*fmt++)
4955 {
4956 case 'e':
4957 case 'u':
4958 walk_attr_value (XEXP (exp, i));
4959 break;
4960
4961 case 'E':
4962 if (XVEC (exp, i) != NULL)
4963 for (j = 0; j < XVECLEN (exp, i); j++)
4964 walk_attr_value (XVECEXP (exp, i, j));
4965 break;
4966 }
4967}
4968\f
4969/* Write out a function to obtain the attribute for a given INSN. */
4970
4971static void
4972write_attr_get (attr)
4973 struct attr_desc *attr;
4974{
4975 struct attr_value *av, *common_av;
4976
4977 /* Find the most used attribute value. Handle that as the `default' of the
0f41302f 4978 switch we will generate. */
41299f41
TW
4979 common_av = find_most_used (attr);
4980
c9541287 4981 /* Write out prototype of function. */
69277eec
KG
4982 if (!attr->is_numeric)
4983 printf ("extern enum attr_%s ", attr->name);
4984 else if (attr->unsigned_p)
4985 printf ("extern unsigned int ");
4986 else
4987 printf ("extern int ");
4988 /* If the attribute name starts with a star, the remainder is the name of
4989 the subroutine to use, instead of `get_attr_...'. */
4990 if (attr->name[0] == '*')
a94ae8f5 4991 printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
69277eec 4992 else
a94ae8f5 4993 printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
69277eec
KG
4994 (attr->is_const ? "void" : "rtx"));
4995
41299f41
TW
4996 /* Write out start of function, then all values with explicit `case' lines,
4997 then a `default', then the value with the most uses. */
bee757e1 4998 if (!attr->is_numeric)
41299f41 4999 printf ("enum attr_%s\n", attr->name);
bee757e1
TW
5000 else if (attr->unsigned_p)
5001 printf ("unsigned int\n");
5002 else
5003 printf ("int\n");
41299f41
TW
5004
5005 /* If the attribute name starts with a star, the remainder is the name of
5006 the subroutine to use, instead of `get_attr_...'. */
5007 if (attr->name[0] == '*')
5008 printf ("%s (insn)\n", &attr->name[1]);
3e7b5313 5009 else if (attr->is_const == 0)
41299f41 5010 printf ("get_attr_%s (insn)\n", attr->name);
3e7b5313
TW
5011 else
5012 {
5013 printf ("get_attr_%s ()\n", attr->name);
5014 printf ("{\n");
5015
5016 for (av = attr->first_value; av; av = av->next)
5017 if (av->num_insns != 0)
5018 write_attr_set (attr, 2, av->value, "return", ";",
5019 true_rtx, av->first_insn->insn_code,
5020 av->first_insn->insn_index);
5021
5022 printf ("}\n\n");
5023 return;
5024 }
71d9b493 5025
41299f41
TW
5026 printf (" rtx insn;\n");
5027 printf ("{\n");
41299f41 5028
71d9b493
RH
5029 if (GET_CODE (common_av->value) == FFS)
5030 {
5031 rtx p = XEXP (common_av->value, 0);
41299f41 5032
c9541287 5033 /* No need to emit code to abort if the insn is unrecognized; the
71d9b493
RH
5034 other get_attr_foo functions will do that when we call them. */
5035
5036 write_toplevel_expr (p);
5037
5038 printf ("\n if (accum && accum == (accum & -accum))\n");
5039 printf (" {\n");
5040 printf (" int i;\n");
5041 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
5042 printf (" accum = i;\n");
5043 printf (" }\n else\n");
5044 printf (" accum = ~accum;\n");
5045 printf (" return accum;\n}\n\n");
5046 }
5047 else
5048 {
5049 printf (" switch (recog_memoized (insn))\n");
5050 printf (" {\n");
5051
5052 for (av = attr->first_value; av; av = av->next)
5053 if (av != common_av)
5054 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5055
5056 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5057 printf (" }\n}\n\n");
5058 }
41299f41
TW
5059}
5060\f
5061/* Given an AND tree of known true terms (because we are inside an `if' with
5062 that as the condition or are in an `else' clause) and an expression,
5063 replace any known true terms with TRUE. Use `simplify_and_tree' to do
5064 the bulk of the work. */
5065
5066static rtx
5067eliminate_known_true (known_true, exp, insn_code, insn_index)
5068 rtx known_true;
5069 rtx exp;
5070 int insn_code, insn_index;
5071{
5072 rtx term;
5073
61abc2ca
RS
5074 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
5075
5076 if (GET_CODE (known_true) == AND)
5077 {
5078 exp = eliminate_known_true (XEXP (known_true, 0), exp,
5079 insn_code, insn_index);
5080 exp = eliminate_known_true (XEXP (known_true, 1), exp,
5081 insn_code, insn_index);
5082 }
5083 else
5084 {
5085 term = known_true;
5086 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
5087 }
5088
5089 return exp;
41299f41
TW
5090}
5091\f
5092/* Write out a series of tests and assignment statements to perform tests and
5093 sets of an attribute value. We are passed an indentation amount and prefix
5094 and suffix strings to write around each attribute value (e.g., "return"
5095 and ";"). */
5096
5097static void
5098write_attr_set (attr, indent, value, prefix, suffix, known_true,
5099 insn_code, insn_index)
5100 struct attr_desc *attr;
5101 int indent;
5102 rtx value;
85fda1eb
KG
5103 const char *prefix;
5104 const char *suffix;
41299f41
TW
5105 rtx known_true;
5106 int insn_code, insn_index;
5107{
7ee37ba4 5108 if (GET_CODE (value) == COND)
41299f41
TW
5109 {
5110 /* Assume the default value will be the default of the COND unless we
5111 find an always true expression. */
5112 rtx default_val = XEXP (value, 1);
5113 rtx our_known_true = known_true;
5114 rtx newexp;
5115 int first_if = 1;
5116 int i;
5117
5118 for (i = 0; i < XVECLEN (value, 0); i += 2)
5119 {
5120 rtx testexp;
5121 rtx inner_true;
5122
5123 testexp = eliminate_known_true (our_known_true,
5124 XVECEXP (value, 0, i),
5125 insn_code, insn_index);
3e7b5313 5126 newexp = attr_rtx (NOT, testexp);
c9541287
KH
5127 newexp = insert_right_side (AND, our_known_true, newexp,
5128 insn_code, insn_index);
41299f41
TW
5129
5130 /* If the test expression is always true or if the next `known_true'
5131 expression is always false, this is the last case, so break
5132 out and let this value be the `else' case. */
5133 if (testexp == true_rtx || newexp == false_rtx)
5134 {
5135 default_val = XVECEXP (value, 0, i + 1);
5136 break;
5137 }
5138
5139 /* Compute the expression to pass to our recursive call as being
5140 known true. */
5141 inner_true = insert_right_side (AND, our_known_true,
5142 testexp, insn_code, insn_index);
5143
5144 /* If this is always false, skip it. */
5145 if (inner_true == false_rtx)
5146 continue;
5147
5148 write_indent (indent);
5149 printf ("%sif ", first_if ? "" : "else ");
5150 first_if = 0;
5151 write_test_expr (testexp, 0);
5152 printf ("\n");
5153 write_indent (indent + 2);
5154 printf ("{\n");
5155
c9541287 5156 write_attr_set (attr, indent + 4,
41299f41
TW
5157 XVECEXP (value, 0, i + 1), prefix, suffix,
5158 inner_true, insn_code, insn_index);
5159 write_indent (indent + 2);
5160 printf ("}\n");
5161 our_known_true = newexp;
5162 }
5163
5164 if (! first_if)
5165 {
5166 write_indent (indent);
5167 printf ("else\n");
5168 write_indent (indent + 2);
5169 printf ("{\n");
5170 }
5171
5172 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5173 prefix, suffix, our_known_true, insn_code, insn_index);
5174
5175 if (! first_if)
5176 {
5177 write_indent (indent + 2);
5178 printf ("}\n");
5179 }
5180 }
5181 else
7ee37ba4
RH
5182 {
5183 write_indent (indent);
5184 printf ("%s ", prefix);
5185 write_attr_value (attr, value);
5186 printf ("%s\n", suffix);
5187 }
41299f41
TW
5188}
5189\f
5190/* Write out the computation for one attribute value. */
5191
5192static void
f75d38a7
RK
5193write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5194 known_true)
41299f41
TW
5195 struct attr_desc *attr;
5196 struct attr_value *av;
5197 int write_case_lines;
85fda1eb 5198 const char *prefix, *suffix;
41299f41
TW
5199 int indent;
5200 rtx known_true;
5201{
5202 struct insn_ent *ie;
5203
5204 if (av->num_insns == 0)
5205 return;
5206
5207 if (av->has_asm_insn)
5208 {
5209 write_indent (indent);
5210 printf ("case -1:\n");
5211 write_indent (indent + 2);
5212 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5213 write_indent (indent + 2);
5214 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5215 write_indent (indent + 2);
5216 printf (" fatal_insn_not_found (insn);\n");
5217 }
5218
5219 if (write_case_lines)
5220 {
5221 for (ie = av->first_insn; ie; ie = ie->next)
5222 if (ie->insn_code != -1)
5223 {
5224 write_indent (indent);
5225 printf ("case %d:\n", ie->insn_code);
5226 }
5227 }
5228 else
5229 {
5230 write_indent (indent);
5231 printf ("default:\n");
5232 }
5233
d7c665bf 5234 /* See what we have to do to output this value. */
41299f41
TW
5235 must_extract = must_constrain = address_used = 0;
5236 walk_attr_value (av->value);
5237
d90ffc8d 5238 if (must_constrain)
41299f41
TW
5239 {
5240 write_indent (indent + 2);
d90ffc8d 5241 printf ("extract_constrain_insn_cached (insn);\n");
41299f41 5242 }
d90ffc8d 5243 else if (must_extract)
41299f41 5244 {
41299f41 5245 write_indent (indent + 2);
d90ffc8d 5246 printf ("extract_insn_cached (insn);\n");
41299f41
TW
5247 }
5248
5249 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5250 known_true, av->first_insn->insn_code,
5251 av->first_insn->insn_index);
5252
5253 if (strncmp (prefix, "return", 6))
5254 {
5255 write_indent (indent + 2);
5256 printf ("break;\n");
5257 }
5258 printf ("\n");
5259}
5260\f
71d9b493
RH
5261/* Search for uses of non-const attributes and write code to cache them. */
5262
5263static int
5264write_expr_attr_cache (p, attr)
5265 rtx p;
5266 struct attr_desc *attr;
5267{
6f7d635c 5268 const char *fmt;
71d9b493
RH
5269 int i, ie, j, je;
5270
5271 if (GET_CODE (p) == EQ_ATTR)
5272 {
5273 if (XSTR (p, 0) != attr->name)
5274 return 0;
5275
5276 if (!attr->is_numeric)
5277 printf (" register enum attr_%s ", attr->name);
5278 else if (attr->unsigned_p)
5279 printf (" register unsigned int ");
5280 else
5281 printf (" register int ");
5282
5283 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5284 return 1;
5285 }
5286
5287 fmt = GET_RTX_FORMAT (GET_CODE (p));
5288 ie = GET_RTX_LENGTH (GET_CODE (p));
5289 for (i = 0; i < ie; i++)
5290 {
5291 switch (*fmt++)
5292 {
5293 case 'e':
5294 if (write_expr_attr_cache (XEXP (p, i), attr))
5295 return 1;
5296 break;
5297
5298 case 'E':
5299 je = XVECLEN (p, i);
5300 for (j = 0; j < je; ++j)
5301 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5302 return 1;
5303 break;
5304 }
5305 }
5306
5307 return 0;
5308}
5309
5310/* Evaluate an expression at top level. A front end to write_test_expr,
5311 in which we cache attribute values and break up excessively large
5312 expressions to cater to older compilers. */
5313
5314static void
5315write_toplevel_expr (p)
5316 rtx p;
5317{
5318 struct attr_desc *attr;
5319 int i;
5320
5321 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
c9541287 5322 for (attr = attrs[i]; attr; attr = attr->next)
71d9b493
RH
5323 if (!attr->is_const)
5324 write_expr_attr_cache (p, attr);
5325
c9541287 5326 printf (" register unsigned long accum = 0;\n\n");
71d9b493
RH
5327
5328 while (GET_CODE (p) == IOR)
5329 {
5330 rtx e;
5331 if (GET_CODE (XEXP (p, 0)) == IOR)
5332 e = XEXP (p, 1), p = XEXP (p, 0);
5333 else
5334 e = XEXP (p, 0), p = XEXP (p, 1);
5335
5336 printf (" accum |= ");
5337 write_test_expr (e, 3);
5338 printf (";\n");
5339 }
5340 printf (" accum |= ");
5341 write_test_expr (p, 3);
5342 printf (";\n");
5343}
5344\f
41299f41
TW
5345/* Utilities to write names in various forms. */
5346
6f6074ea
MM
5347static void
5348write_unit_name (prefix, num, suffix)
85fda1eb 5349 const char *prefix;
6f6074ea 5350 int num;
85fda1eb 5351 const char *suffix;
6f6074ea
MM
5352{
5353 struct function_unit *unit;
5354
5355 for (unit = units; unit; unit = unit->next)
5356 if (unit->num == num)
5357 {
5358 printf ("%s%s%s", prefix, unit->name, suffix);
5359 return;
5360 }
5361
5362 printf ("%s<unknown>%s", prefix, suffix);
5363}
5364
41299f41
TW
5365static void
5366write_attr_valueq (attr, s)
5367 struct attr_desc *attr;
3cce094d 5368 const char *s;
41299f41
TW
5369{
5370 if (attr->is_numeric)
bee757e1 5371 {
6f6074ea
MM
5372 int num = atoi (s);
5373
5374 printf ("%d", num);
5375
5376 /* Make the blockage range values and function units used values easier
5377 to read. */
5378 if (attr->func_units_p)
5379 {
5380 if (num == -1)
5381 printf (" /* units: none */");
5382 else if (num >= 0)
5383 write_unit_name (" /* units: ", num, " */");
5384 else
5385 {
5386 int i;
85fda1eb 5387 const char *sep = " /* units: ";
6f6074ea
MM
5388 for (i = 0, num = ~num; num; i++, num >>= 1)
5389 if (num & 1)
5390 {
5391 write_unit_name (sep, i, (num == 1) ? " */" : "");
5392 sep = ", ";
5393 }
5394 }
5395 }
5396
5397 else if (attr->blockage_p)
5398 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5399 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5400
5401 else if (num > 9 || num < 0)
5402 printf (" /* 0x%x */", num);
bee757e1 5403 }
41299f41
TW
5404 else
5405 {
5406 write_upcase (attr->name);
5407 printf ("_");
5408 write_upcase (s);
5409 }
5410}
5411
5412static void
5413write_attr_value (attr, value)
5414 struct attr_desc *attr;
5415 rtx value;
5416{
7ee37ba4
RH
5417 int op;
5418
5419 switch (GET_CODE (value))
5420 {
5421 case CONST_STRING:
5422 write_attr_valueq (attr, XSTR (value, 0));
5423 break;
5424
6ef67412
JH
5425 case CONST_INT:
5426 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
5427 break;
5428
7ee37ba4
RH
5429 case SYMBOL_REF:
5430 fputs (XSTR (value, 0), stdout);
5431 break;
5432
5433 case ATTR:
5434 {
5435 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
c9541287 5436 printf ("get_attr_%s (%s)", attr2->name,
7ee37ba4
RH
5437 (attr2->is_const ? "" : "insn"));
5438 }
5439 break;
41299f41 5440
7ee37ba4
RH
5441 case PLUS:
5442 op = '+';
5443 goto do_operator;
5444 case MINUS:
5445 op = '-';
5446 goto do_operator;
5447 case MULT:
5448 op = '*';
5449 goto do_operator;
5450 case DIV:
5451 op = '/';
5452 goto do_operator;
5453 case MOD:
5454 op = '%';
5455 goto do_operator;
5456
5457 do_operator:
5458 write_attr_value (attr, XEXP (value, 0));
5459 putchar (' ');
5460 putchar (op);
5461 putchar (' ');
5462 write_attr_value (attr, XEXP (value, 1));
5463 break;
5464
5465 default:
5466 abort ();
5467 }
41299f41
TW
5468}
5469
5470static void
5471write_upcase (str)
92a438d1 5472 const char *str;
41299f41
TW
5473{
5474 while (*str)
c9541287
KH
5475 {
5476 /* The argument of TOUPPER should not have side effects. */
5477 putchar (TOUPPER(*str));
5478 str++;
5479 }
41299f41
TW
5480}
5481
5482static void
5483write_indent (indent)
5484 int indent;
5485{
5486 for (; indent > 8; indent -= 8)
5487 printf ("\t");
5488
5489 for (; indent; indent--)
5490 printf (" ");
5491}
5492\f
5493/* Write a subroutine that is given an insn that requires a delay slot, a
5494 delay slot ordinal, and a candidate insn. It returns non-zero if the
5495 candidate can be placed in the specified delay slot of the insn.
5496
5497 We can write as many as three subroutines. `eligible_for_delay'
5498 handles normal delay slots, `eligible_for_annul_true' indicates that
5499 the specified insn can be annulled if the branch is true, and likewise
5500 for `eligible_for_annul_false'.
5501
6dc42e49 5502 KIND is a string distinguishing these three cases ("delay", "annul_true",
41299f41
TW
5503 or "annul_false"). */
5504
5505static void
5506write_eligible_delay (kind)
c9541287 5507 const char *kind;
41299f41
TW
5508{
5509 struct delay_desc *delay;
5510 int max_slots;
5511 char str[50];
5512 struct attr_desc *attr;
5513 struct attr_value *av, *common_av;
5514 int i;
5515
5516 /* Compute the maximum number of delay slots required. We use the delay
5517 ordinal times this number plus one, plus the slot number as an index into
5518 the appropriate predicate to test. */
5519
5520 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5521 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5522 max_slots = XVECLEN (delay->def, 1) / 3;
5523
5524 /* Write function prelude. */
5525
5526 printf ("int\n");
c9541287
KH
5527 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5528 kind);
41299f41
TW
5529 printf (" rtx delay_insn;\n");
5530 printf (" int slot;\n");
5531 printf (" rtx candidate_insn;\n");
69277eec 5532 printf (" int flags ATTRIBUTE_UNUSED;\n");
41299f41
TW
5533 printf ("{\n");
5534 printf (" rtx insn;\n");
5535 printf ("\n");
5536 printf (" if (slot >= %d)\n", max_slots);
5537 printf (" abort ();\n");
5538 printf ("\n");
5539
5540 /* If more than one delay type, find out which type the delay insn is. */
5541
5542 if (num_delays > 1)
5543 {
412dc348 5544 attr = find_attr ("*delay_type", 0);
c9541287
KH
5545 if (! attr)
5546 abort ();
41299f41
TW
5547 common_av = find_most_used (attr);
5548
5549 printf (" insn = delay_insn;\n");
5550 printf (" switch (recog_memoized (insn))\n");
5551 printf (" {\n");
5552
5553 sprintf (str, " * %d;\n break;", max_slots);
5554 for (av = attr->first_value; av; av = av->next)
5555 if (av != common_av)
5556 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5557
5558 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5559 printf (" }\n\n");
5560
5561 /* Ensure matched. Otherwise, shouldn't have been called. */
5562 printf (" if (slot < %d)\n", max_slots);
5563 printf (" abort ();\n\n");
5564 }
5565
5566 /* If just one type of delay slot, write simple switch. */
5567 if (num_delays == 1 && max_slots == 1)
5568 {
5569 printf (" insn = candidate_insn;\n");
5570 printf (" switch (recog_memoized (insn))\n");
5571 printf (" {\n");
5572
5573 attr = find_attr ("*delay_1_0", 0);
c9541287
KH
5574 if (! attr)
5575 abort ();
41299f41
TW
5576 common_av = find_most_used (attr);
5577
5578 for (av = attr->first_value; av; av = av->next)
5579 if (av != common_av)
5580 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5581
5582 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5583 printf (" }\n");
5584 }
5585
5586 else
5587 {
5588 /* Write a nested CASE. The first indicates which condition we need to
5589 test, and the inner CASE tests the condition. */
5590 printf (" insn = candidate_insn;\n");
5591 printf (" switch (slot)\n");
5592 printf (" {\n");
5593
5594 for (delay = delays; delay; delay = delay->next)
5595 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5596 {
5597 printf (" case %d:\n",
5598 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5599 printf (" switch (recog_memoized (insn))\n");
5600 printf ("\t{\n");
5601
5602 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5603 attr = find_attr (str, 0);
c9541287
KH
5604 if (! attr)
5605 abort ();
41299f41
TW
5606 common_av = find_most_used (attr);
5607
5608 for (av = attr->first_value; av; av = av->next)
5609 if (av != common_av)
5610 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5611
5612 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5613 printf (" }\n");
5614 }
5615
5616 printf (" default:\n");
c9541287 5617 printf (" abort ();\n");
41299f41
TW
5618 printf (" }\n");
5619 }
5620
5621 printf ("}\n\n");
5622}
5623\f
5624/* Write routines to compute conflict cost for function units. Then write a
5625 table describing the available function units. */
5626
5627static void
5628write_function_unit_info ()
5629{
5630 struct function_unit *unit;
41299f41
TW
5631 int i;
5632
5633 /* Write out conflict routines for function units. Don't bother writing
bee757e1 5634 one if there is only one issue delay value. */
41299f41
TW
5635
5636 for (unit = units; unit; unit = unit->next)
5637 {
bee757e1
TW
5638 if (unit->needs_blockage_function)
5639 write_complex_function (unit, "blockage", "block");
72f1215c
TW
5640
5641 /* If the minimum and maximum conflict costs are the same, there
5642 is only one value, so we don't need a function. */
bee757e1 5643 if (! unit->needs_conflict_function)
41299f41 5644 {
bee757e1 5645 unit->default_cost = make_numeric_value (unit->issue_delay.max);
72f1215c 5646 continue;
41299f41
TW
5647 }
5648
5649 /* The function first computes the case from the candidate insn. */
41299f41 5650 unit->default_cost = make_numeric_value (0);
bee757e1 5651 write_complex_function (unit, "conflict_cost", "cost");
41299f41
TW
5652 }
5653
5654 /* Now that all functions have been written, write the table describing
6dc42e49 5655 the function units. The name is included for documentation purposes
41299f41
TW
5656 only. */
5657
5658 printf ("struct function_unit_desc function_units[] = {\n");
5659
72f1215c
TW
5660 /* Write out the descriptions in numeric order, but don't force that order
5661 on the list. Doing so increases the runtime of genattrtab.c. */
5662 for (i = 0; i < num_units; i++)
41299f41 5663 {
72f1215c
TW
5664 for (unit = units; unit; unit = unit->next)
5665 if (unit->num == i)
5666 break;
5667
bee757e1 5668 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
41299f41 5669 unit->name, 1 << unit->num, unit->multiplicity,
72f1215c 5670 unit->simultaneity, XSTR (unit->default_cost, 0),
bee757e1 5671 unit->issue_delay.max, unit->name);
41299f41
TW
5672
5673 if (unit->needs_conflict_function)
bee757e1
TW
5674 printf ("%s_unit_conflict_cost, ", unit->name);
5675 else
5676 printf ("0, ");
5677
5678 printf ("%d, ", unit->max_blockage);
5679
5680 if (unit->needs_range_function)
5681 printf ("%s_unit_blockage_range, ", unit->name);
5682 else
5683 printf ("0, ");
5684
5685 if (unit->needs_blockage_function)
5686 printf ("%s_unit_blockage", unit->name);
41299f41
TW
5687 else
5688 printf ("0");
5689
5690 printf ("}, \n");
5691 }
5692
5693 printf ("};\n\n");
5694}
bee757e1
TW
5695
5696static void
5697write_complex_function (unit, name, connection)
5698 struct function_unit *unit;
85fda1eb 5699 const char *name, *connection;
bee757e1
TW
5700{
5701 struct attr_desc *case_attr, *attr;
5702 struct attr_value *av, *common_av;
5703 rtx value;
b548dffb 5704 char str[256];
bee757e1
TW
5705 int using_case;
5706 int i;
5707
a94ae8f5 5708 printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
bee757e1 5709 printf ("static int\n");
c9541287 5710 printf ("%s_unit_%s (executing_insn, candidate_insn)\n", unit->name, name);
bee757e1
TW
5711 printf (" rtx executing_insn;\n");
5712 printf (" rtx candidate_insn;\n");
5713 printf ("{\n");
5714 printf (" rtx insn;\n");
5715 printf (" int casenum;\n\n");
cb1520bc 5716 printf (" insn = executing_insn;\n");
bee757e1
TW
5717 printf (" switch (recog_memoized (insn))\n");
5718 printf (" {\n");
5719
5720 /* Write the `switch' statement to get the case value. */
b548dffb
ZW
5721 if (strlen (unit->name) + sizeof "*_cases" > 256)
5722 abort ();
bee757e1
TW
5723 sprintf (str, "*%s_cases", unit->name);
5724 case_attr = find_attr (str, 0);
c9541287
KH
5725 if (! case_attr)
5726 abort ();
bee757e1
TW
5727 common_av = find_most_used (case_attr);
5728
5729 for (av = case_attr->first_value; av; av = av->next)
5730 if (av != common_av)
5731 write_attr_case (case_attr, av, 1,
5732 "casenum =", ";", 4, unit->condexp);
5733
5734 write_attr_case (case_attr, common_av, 0,
5735 "casenum =", ";", 4, unit->condexp);
5736 printf (" }\n\n");
5737
5738 /* Now write an outer switch statement on each case. Then write
5739 the tests on the executing function within each. */
cb1520bc 5740 printf (" insn = candidate_insn;\n");
bee757e1
TW
5741 printf (" switch (casenum)\n");
5742 printf (" {\n");
5743
5744 for (i = 0; i < unit->num_opclasses; i++)
5745 {
5746 /* Ensure using this case. */
5747 using_case = 0;
5748 for (av = case_attr->first_value; av; av = av->next)
5749 if (av->num_insns
5750 && contained_in_p (make_numeric_value (i), av->value))
5751 using_case = 1;
5752
5753 if (! using_case)
5754 continue;
5755
5756 printf (" case %d:\n", i);
5757 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5758 attr = find_attr (str, 0);
c9541287
KH
5759 if (! attr)
5760 abort ();
bee757e1
TW
5761
5762 /* If single value, just write it. */
5763 value = find_single_value (attr);
5764 if (value)
f75d38a7 5765 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
bee757e1
TW
5766 else
5767 {
5768 common_av = find_most_used (attr);
5769 printf (" switch (recog_memoized (insn))\n");
5770 printf ("\t{\n");
5771
5772 for (av = attr->first_value; av; av = av->next)
5773 if (av != common_av)
5774 write_attr_case (attr, av, 1,
5775 "return", ";", 8, unit->condexp);
5776
5777 write_attr_case (attr, common_av, 0,
5778 "return", ";", 8, unit->condexp);
5779 printf (" }\n\n");
5780 }
5781 }
5782
2e61a5a5
JL
5783 /* This default case should not be needed, but gcc's analysis is not
5784 good enough to realize that the default case is not needed for the
5785 second switch statement. */
5786 printf (" default:\n abort ();\n");
bee757e1
TW
5787 printf (" }\n}\n\n");
5788}
41299f41
TW
5789\f
5790/* This page contains miscellaneous utility routines. */
5791
5792/* Given a string, return the number of comma-separated elements in it.
5793 Return 0 for the null string. */
5794
5795static int
5796n_comma_elts (s)
3cce094d 5797 const char *s;
41299f41
TW
5798{
5799 int n;
5800
5801 if (*s == '\0')
5802 return 0;
5803
5804 for (n = 1; *s; s++)
5805 if (*s == ',')
5806 n++;
5807
5808 return n;
5809}
5810
5811/* Given a pointer to a (char *), return a malloc'ed string containing the
5812 next comma-separated element. Advance the pointer to after the string
5813 scanned, or the end-of-string. Return NULL if at end of string. */
5814
5815static char *
5816next_comma_elt (pstr)
3cce094d 5817 const char **pstr;
41299f41
TW
5818{
5819 char *out_str;
3cce094d 5820 const char *p;
41299f41
TW
5821
5822 if (**pstr == '\0')
5823 return NULL;
5824
5825 /* Find end of string to compute length. */
5826 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5827 ;
5828
3e7b5313
TW
5829 out_str = attr_string (*pstr, p - *pstr);
5830 *pstr = p;
41299f41 5831
41299f41
TW
5832 if (**pstr == ',')
5833 (*pstr)++;
5834
5835 return out_str;
5836}
5837
5838/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5839 is non-zero, build a new attribute, if one does not exist. */
5840
5841static struct attr_desc *
5842find_attr (name, create)
85fda1eb 5843 const char *name;
41299f41
TW
5844 int create;
5845{
5846 struct attr_desc *attr;
3715a518 5847 int index;
41299f41
TW
5848
5849 /* Before we resort to using `strcmp', see if the string address matches
5850 anywhere. In most cases, it should have been canonicalized to do so. */
5851 if (name == alternative_name)
5852 return NULL;
5853
3715a518
RS
5854 index = name[0] & (MAX_ATTRS_INDEX - 1);
5855 for (attr = attrs[index]; attr; attr = attr->next)
41299f41
TW
5856 if (name == attr->name)
5857 return attr;
5858
5859 /* Otherwise, do it the slow way. */
3715a518 5860 for (attr = attrs[index]; attr; attr = attr->next)
81fd4c6e 5861 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
41299f41
TW
5862 return attr;
5863
5864 if (! create)
5865 return NULL;
5866
0e9414fd 5867 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
3715a518 5868 attr->name = attr_string (name, strlen (name));
41299f41 5869 attr->first_value = attr->default_val = NULL;
72f1215c 5870 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
605fba2b 5871 attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
3715a518
RS
5872 attr->next = attrs[index];
5873 attrs[index] = attr;
41299f41
TW
5874
5875 return attr;
5876}
5877
5878/* Create internal attribute with the given default value. */
5879
b8ec5764 5880static void
41299f41 5881make_internal_attr (name, value, special)
85fda1eb 5882 const char *name;
41299f41
TW
5883 rtx value;
5884 int special;
5885{
5886 struct attr_desc *attr;
5887
5888 attr = find_attr (name, 1);
5889 if (attr->default_val)
5890 abort ();
5891
5892 attr->is_numeric = 1;
3e7b5313 5893 attr->is_const = 0;
72f1215c
TW
5894 attr->is_special = (special & 1) != 0;
5895 attr->negative_ok = (special & 2) != 0;
bee757e1 5896 attr->unsigned_p = (special & 4) != 0;
6f6074ea
MM
5897 attr->func_units_p = (special & 8) != 0;
5898 attr->blockage_p = (special & 16) != 0;
41299f41
TW
5899 attr->default_val = get_attr_value (value, attr, -2);
5900}
5901
5902/* Find the most used value of an attribute. */
5903
5904static struct attr_value *
5905find_most_used (attr)
5906 struct attr_desc *attr;
5907{
5908 struct attr_value *av;
5909 struct attr_value *most_used;
5910 int nuses;
5911
5912 most_used = NULL;
5913 nuses = -1;
5914
5915 for (av = attr->first_value; av; av = av->next)
5916 if (av->num_insns > nuses)
5917 nuses = av->num_insns, most_used = av;
5918
5919 return most_used;
5920}
5921
5922/* If an attribute only has a single value used, return it. Otherwise
5923 return NULL. */
5924
5925static rtx
5926find_single_value (attr)
5927 struct attr_desc *attr;
5928{
5929 struct attr_value *av;
5930 rtx unique_value;
5931
5932 unique_value = NULL;
5933 for (av = attr->first_value; av; av = av->next)
5934 if (av->num_insns)
5935 {
5936 if (unique_value)
5937 return NULL;
5938 else
5939 unique_value = av->value;
5940 }
5941
5942 return unique_value;
5943}
5944
5945/* Return (attr_value "n") */
5946
b8ec5764 5947static rtx
41299f41
TW
5948make_numeric_value (n)
5949 int n;
5950{
5951 static rtx int_values[20];
5952 rtx exp;
3e7b5313 5953 char *p;
41299f41
TW
5954
5955 if (n < 0)
5956 abort ();
5957
5958 if (n < 20 && int_values[n])
5959 return int_values[n];
5960
0e9414fd 5961 p = attr_printf (MAX_DIGITS, "%d", n);
3e7b5313 5962 exp = attr_rtx (CONST_STRING, p);
41299f41
TW
5963
5964 if (n < 20)
5965 int_values[n] = exp;
5966
5967 return exp;
5968}
5969\f
bee757e1
TW
5970static void
5971extend_range (range, min, max)
5972 struct range *range;
5973 int min;
5974 int max;
5975{
c9541287
KH
5976 if (range->min > min)
5977 range->min = min;
5978 if (range->max < max)
5979 range->max = max;
bee757e1
TW
5980}
5981
7339c88d
RS
5982static rtx
5983copy_rtx_unchanging (orig)
5984 register rtx orig;
5985{
b5b6ad46 5986#if 0
7339c88d
RS
5987 register rtx copy;
5988 register RTX_CODE code;
b5b6ad46 5989#endif
7339c88d 5990
85093b9c 5991 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
81fd4c6e
RS
5992 return orig;
5993
85093b9c
RS
5994 MEM_IN_STRUCT_P (orig) = 1;
5995 return orig;
7339c88d 5996
85093b9c
RS
5997#if 0
5998 code = GET_CODE (orig);
7339c88d
RS
5999 switch (code)
6000 {
6001 case CONST_INT:
6002 case CONST_DOUBLE:
6003 case SYMBOL_REF:
6004 case CODE_LABEL:
6005 return orig;
c9541287 6006
e9a25f70
JL
6007 default:
6008 break;
7339c88d
RS
6009 }
6010
6011 copy = rtx_alloc (code);
6012 PUT_MODE (copy, GET_MODE (orig));
6013 RTX_UNCHANGING_P (copy) = 1;
c9541287 6014
4e135bdd
KG
6015 memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
6016 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
7339c88d 6017 return copy;
85093b9c 6018#endif
7339c88d
RS
6019}
6020
d7c665bf
RK
6021/* Determine if an insn has a constant number of delay slots, i.e., the
6022 number of delay slots is not a function of the length of the insn. */
6023
69277eec 6024static void
a9ab5e00
TM
6025write_const_num_delay_slots ()
6026{
6027 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
6028 struct attr_value *av;
6029 struct insn_ent *ie;
a9ab5e00
TM
6030
6031 if (attr)
6032 {
6033 printf ("int\nconst_num_delay_slots (insn)\n");
dea2643c 6034 printf (" rtx insn;\n");
a9ab5e00
TM
6035 printf ("{\n");
6036 printf (" switch (recog_memoized (insn))\n");
6037 printf (" {\n");
6038
6039 for (av = attr->first_value; av; av = av->next)
d7c665bf
RK
6040 {
6041 length_used = 0;
6042 walk_attr_value (av->value);
6043 if (length_used)
6044 {
6045 for (ie = av->first_insn; ie; ie = ie->next)
c9541287
KH
6046 if (ie->insn_code != -1)
6047 printf (" case %d:\n", ie->insn_code);
d7c665bf
RK
6048 printf (" return 0;\n");
6049 }
6050 }
6051
a9ab5e00
TM
6052 printf (" default:\n");
6053 printf (" return 1;\n");
fc470718 6054 printf (" }\n}\n\n");
a9ab5e00
TM
6055 }
6056}
41299f41 6057\f
a94ae8f5 6058extern int main PARAMS ((int, char **));
c1b59dce 6059
41299f41
TW
6060int
6061main (argc, argv)
6062 int argc;
6063 char **argv;
6064{
6065 rtx desc;
41299f41 6066 struct attr_desc *attr;
41299f41
TW
6067 struct insn_def *id;
6068 rtx tem;
3715a518 6069 int i;
41299f41 6070
ef178af3
ZW
6071 progname = "genattrtab";
6072
c88c0d42
CP
6073 if (argc <= 1)
6074 fatal ("No input file name.");
6075
3916d6d8
RH
6076 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
6077 return (FATAL_EXIT_CODE);
6078
7339c88d 6079 obstack_init (hash_obstack);
81fd4c6e 6080 obstack_init (temp_obstack);
41299f41 6081
41299f41 6082 /* Set up true and false rtx's */
81fd4c6e 6083 true_rtx = rtx_alloc (CONST_INT);
3d678dca 6084 XWINT (true_rtx, 0) = 1;
81fd4c6e 6085 false_rtx = rtx_alloc (CONST_INT);
3d678dca 6086 XWINT (false_rtx, 0) = 0;
41299f41 6087 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
81fd4c6e
RS
6088 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
6089
6090 alternative_name = attr_string ("alternative", strlen ("alternative"));
41299f41
TW
6091
6092 printf ("/* Generated automatically by the program `genattrtab'\n\
6093from the machine description file `md'. */\n\n");
6094
6095 /* Read the machine description. */
6096
6097 while (1)
6098 {
a4cad544 6099 int lineno;
41299f41 6100
a4cad544 6101 desc = read_md_rtx (&lineno, &insn_code_number);
c88c0d42
CP
6102 if (desc == NULL)
6103 break;
ede7cd44 6104
c88c0d42 6105 switch (GET_CODE (desc))
41299f41 6106 {
c9541287
KH
6107 case DEFINE_INSN:
6108 case DEFINE_PEEPHOLE:
6109 case DEFINE_ASM_ATTRIBUTES:
6110 gen_insn (desc, lineno);
6111 break;
41299f41 6112
c9541287
KH
6113 case DEFINE_ATTR:
6114 gen_attr (desc, lineno);
6115 break;
41299f41 6116
c9541287
KH
6117 case DEFINE_DELAY:
6118 gen_delay (desc, lineno);
6119 break;
6120
6121 case DEFINE_FUNCTION_UNIT:
6122 gen_unit (desc, lineno);
6123 break;
6124
6125 default:
6126 break;
41299f41 6127 }
c88c0d42 6128 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
c9541287 6129 insn_index_number++;
41299f41
TW
6130 }
6131
a4cad544
RH
6132 if (have_error)
6133 return FATAL_EXIT_CODE;
6134
c88c0d42
CP
6135 insn_code_number++;
6136
41299f41
TW
6137 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6138 if (! got_define_asm_attributes)
6139 {
6140 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6141 XVEC (tem, 0) = rtvec_alloc (0);
a4cad544 6142 gen_insn (tem, 0);
41299f41
TW
6143 }
6144
6145 /* Expand DEFINE_DELAY information into new attribute. */
6146 if (num_delays)
6147 expand_delays ();
6148
b8ec5764
VM
6149 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6150 if (num_units)
6151 expand_units ();
41299f41
TW
6152
6153 printf ("#include \"config.h\"\n");
729da3f5 6154 printf ("#include \"system.h\"\n");
41299f41 6155 printf ("#include \"rtl.h\"\n");
6baf1cc8 6156 printf ("#include \"tm_p.h\"\n");
41299f41
TW
6157 printf ("#include \"insn-config.h\"\n");
6158 printf ("#include \"recog.h\"\n");
6159 printf ("#include \"regs.h\"\n");
6160 printf ("#include \"real.h\"\n");
6161 printf ("#include \"output.h\"\n");
6162 printf ("#include \"insn-attr.h\"\n");
114791ea 6163 printf ("#include \"toplev.h\"\n");
2840aebf 6164 printf ("#include \"flags.h\"\n");
c9541287 6165 printf ("\n");
1ccbefce 6166 printf ("#define operands recog_data.operand\n\n");
41299f41
TW
6167
6168 /* Make `insn_alternatives'. */
0e9414fd 6169 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
41299f41
TW
6170 for (id = defs; id; id = id->next)
6171 if (id->insn_code >= 0)
6172 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6173
3715a518 6174 /* Make `insn_n_alternatives'. */
0e9414fd 6175 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
3715a518
RS
6176 for (id = defs; id; id = id->next)
6177 if (id->insn_code >= 0)
6178 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6179
41299f41
TW
6180 /* Prepare to write out attribute subroutines by checking everything stored
6181 away and building the attribute cases. */
6182
6183 check_defs ();
a4cad544 6184
3715a518
RS
6185 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6186 for (attr = attrs[i]; attr; attr = attr->next)
a4cad544
RH
6187 attr->default_val->value
6188 = check_attr_value (attr->default_val->value, attr);
6189
6190 if (have_error)
6191 return FATAL_EXIT_CODE;
6192
6193 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6194 for (attr = attrs[i]; attr; attr = attr->next)
6195 fill_attr (attr);
41299f41
TW
6196
6197 /* Construct extra attributes for `length'. */
6198 make_length_attrs ();
6199
0f41302f 6200 /* Perform any possible optimizations to speed up compilation. */
41299f41
TW
6201 optimize_attrs ();
6202
6203 /* Now write out all the `gen_attr_...' routines. Do these before the
6204 special routines (specifically before write_function_unit_info), so
6205 that they get defined before they are used. */
6206
3715a518
RS
6207 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6208 for (attr = attrs[i]; attr; attr = attr->next)
6209 {
71d9b493 6210 if (! attr->is_special && ! attr->is_const)
3715a518
RS
6211 write_attr_get (attr);
6212 }
41299f41
TW
6213
6214 /* Write out delay eligibility information, if DEFINE_DELAY present.
6215 (The function to compute the number of delay slots will be written
6216 below.) */
6217 if (num_delays)
6218 {
6219 write_eligible_delay ("delay");
6220 if (have_annul_true)
6221 write_eligible_delay ("annul_true");
6222 if (have_annul_false)
6223 write_eligible_delay ("annul_false");
6224 }
6225
b8ec5764
VM
6226 /* Write out information about function units. */
6227 if (num_units)
6228 write_function_unit_info ();
41299f41 6229
a9ab5e00
TM
6230 /* Write out constant delay slot info */
6231 write_const_num_delay_slots ();
6232
fc470718
R
6233 write_length_unit_log ();
6234
41299f41 6235 fflush (stdout);
c1b59dce 6236 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
41299f41 6237}
a995e389
RH
6238
6239/* Define this so we can link with print-rtl.o to get debug_rtx function. */
6240const char *
6241get_insn_name (code)
c1b59dce 6242 int code ATTRIBUTE_UNUSED;
a995e389
RH
6243{
6244 return NULL;
6245}