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