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