define NO_IMPLICIT_EXTERN_C
[official-gcc.git] / gcc / genattrtab.c
blobdd16a132c8a075747326450c28d5eec7e8ca2cd3
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 93-98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This program handles insn attributes and the DEFINE_DELAY and
23 DEFINE_FUNCTION_UNIT definitions.
25 It produces a series of functions named `get_attr_...', one for each insn
26 attribute. Each of these is given the rtx for an insn and returns a member
27 of the enum for the attribute.
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).
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, `extract_insn' is called.
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'.
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.
55 Internal attributes are defined to handle DEFINE_DELAY and
56 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
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.
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.
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.
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.
76 Once optimization is complete, any required routines and definitions
77 will be written.
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
85 definitions (each would be accessed through a pointer).
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
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. */
98 #include "hconfig.h"
99 #include "system.h"
100 #include "rtl.h"
101 #include "insn-config.h" /* For REGISTER_CONSTRAINTS */
102 #include "ggc.h"
104 #ifdef HAVE_SYS_RESOURCE_H
105 # include <sys/resource.h>
106 #endif
108 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
109 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
110 #include "obstack.h"
111 #include "errors.h"
113 static struct obstack obstack, obstack1, obstack2;
114 struct obstack *rtl_obstack = &obstack;
115 struct obstack *hash_obstack = &obstack1;
116 struct obstack *temp_obstack = &obstack2;
118 #define obstack_chunk_alloc xmalloc
119 #define obstack_chunk_free free
121 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
122 char **insn_name_ptr = 0;
124 /* enough space to reserve for printing out ints */
125 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
127 /* Define structures used to record attributes and values. */
129 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
130 encountered, we store all the relevant information into a
131 `struct insn_def'. This is done to allow attribute definitions to occur
132 anywhere in the file. */
134 struct insn_def
136 int insn_code; /* Instruction number. */
137 int insn_index; /* Expression numer in file, for errors. */
138 struct insn_def *next; /* Next insn in chain. */
139 rtx def; /* The DEFINE_... */
140 int num_alternatives; /* Number of alternatives. */
141 int vec_idx; /* Index of attribute vector in `def'. */
144 /* Once everything has been read in, we store in each attribute value a list
145 of insn codes that have that value. Here is the structure used for the
146 list. */
148 struct insn_ent
150 int insn_code; /* Instruction number. */
151 int insn_index; /* Index of definition in file */
152 struct insn_ent *next; /* Next in chain. */
155 /* Each value of an attribute (either constant or computed) is assigned a
156 structure which is used as the listhead of the insns that have that
157 value. */
159 struct attr_value
161 rtx value; /* Value of attribute. */
162 struct attr_value *next; /* Next attribute value in chain. */
163 struct insn_ent *first_insn; /* First insn with this value. */
164 int num_insns; /* Number of insns with this value. */
165 int has_asm_insn; /* True if this value used for `asm' insns */
168 /* Structure for each attribute. */
170 struct attr_desc
172 char *name; /* Name of attribute. */
173 struct attr_desc *next; /* Next attribute. */
174 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
175 unsigned negative_ok : 1; /* Allow negative numeric values. */
176 unsigned unsigned_p : 1; /* Make the output function unsigned int. */
177 unsigned is_const : 1; /* Attribute value constant for each run. */
178 unsigned is_special : 1; /* Don't call `write_attr_set'. */
179 unsigned func_units_p : 1; /* this is the function_units attribute */
180 unsigned blockage_p : 1; /* this is the blockage range function */
181 struct attr_value *first_value; /* First value of this attribute. */
182 struct attr_value *default_val; /* Default value for this attribute. */
185 #define NULL_ATTR (struct attr_desc *) NULL
187 /* A range of values. */
189 struct range
191 int min;
192 int max;
195 /* Structure for each DEFINE_DELAY. */
197 struct delay_desc
199 rtx def; /* DEFINE_DELAY expression. */
200 struct delay_desc *next; /* Next DEFINE_DELAY. */
201 int num; /* Number of DEFINE_DELAY, starting at 1. */
204 /* Record information about each DEFINE_FUNCTION_UNIT. */
206 struct function_unit_op
208 rtx condexp; /* Expression TRUE for applicable insn. */
209 struct function_unit_op *next; /* Next operation for this function unit. */
210 int num; /* Ordinal for this operation type in unit. */
211 int ready; /* Cost until data is ready. */
212 int issue_delay; /* Cost until unit can accept another insn. */
213 rtx conflict_exp; /* Expression TRUE for insns incurring issue delay. */
214 rtx issue_exp; /* Expression computing issue delay. */
217 /* Record information about each function unit mentioned in a
218 DEFINE_FUNCTION_UNIT. */
220 struct function_unit
222 char *name; /* Function unit name. */
223 struct function_unit *next; /* Next function unit. */
224 int num; /* Ordinal of this unit type. */
225 int multiplicity; /* Number of units of this type. */
226 int simultaneity; /* Maximum number of simultaneous insns
227 on this function unit or 0 if unlimited. */
228 rtx condexp; /* Expression TRUE for insn needing unit. */
229 int num_opclasses; /* Number of different operation types. */
230 struct function_unit_op *ops; /* Pointer to first operation type. */
231 int needs_conflict_function; /* Nonzero if a conflict function required. */
232 int needs_blockage_function; /* Nonzero if a blockage function required. */
233 int needs_range_function; /* Nonzero if blockage range function needed.*/
234 rtx default_cost; /* Conflict cost, if constant. */
235 struct range issue_delay; /* Range of issue delay values. */
236 int max_blockage; /* Maximum time an insn blocks the unit. */
239 /* Listheads of above structures. */
241 /* This one is indexed by the first character of the attribute name. */
242 #define MAX_ATTRS_INDEX 256
243 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
244 static struct insn_def *defs;
245 static struct delay_desc *delays;
246 static struct function_unit *units;
248 /* An expression where all the unknown terms are EQ_ATTR tests can be
249 rearranged into a COND provided we can enumerate all possible
250 combinations of the unknown values. The set of combinations become the
251 tests of the COND; the value of the expression given that combination is
252 computed and becomes the corresponding value. To do this, we must be
253 able to enumerate all values for each attribute used in the expression
254 (currently, we give up if we find a numeric attribute).
256 If the set of EQ_ATTR tests used in an expression tests the value of N
257 different attributes, the list of all possible combinations can be made
258 by walking the N-dimensional attribute space defined by those
259 attributes. We record each of these as a struct dimension.
261 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
262 expression are the same, the will also have the same address. We find
263 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
264 represents the value of an EQ_ATTR node, so once all nodes are marked,
265 they are also given an initial value of FALSE.
267 We then separate the set of EQ_ATTR nodes into dimensions for each
268 attribute and put them on the VALUES list. Terms are added as needed by
269 `add_values_to_cover' so that all possible values of the attribute are
270 tested.
272 Each dimension also has a current value. This is the node that is
273 currently considered to be TRUE. If this is one of the nodes added by
274 `add_values_to_cover', all the EQ_ATTR tests in the original expression
275 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
277 NUM_VALUES is simply the length of the VALUES list and is there for
278 convenience.
280 Once the dimensions are created, the algorithm enumerates all possible
281 values and computes the current value of the given expression. */
283 struct dimension
285 struct attr_desc *attr; /* Attribute for this dimension. */
286 rtx values; /* List of attribute values used. */
287 rtx current_value; /* Position in the list for the TRUE value. */
288 int num_values; /* Length of the values list. */
291 /* Other variables. */
293 static int insn_code_number;
294 static int insn_index_number;
295 static int got_define_asm_attributes;
296 static int must_extract;
297 static int must_constrain;
298 static int address_used;
299 static int length_used;
300 static int num_delays;
301 static int have_annul_true, have_annul_false;
302 static int num_units, num_unit_opclasses;
303 static int num_insn_ents;
305 /* Used as operand to `operate_exp': */
307 enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
309 /* Stores, for each insn code, the number of constraint alternatives. */
311 static int *insn_n_alternatives;
313 /* Stores, for each insn code, a bitmap that has bits on for each possible
314 alternative. */
316 static int *insn_alternatives;
318 /* If nonzero, assume that the `alternative' attr has this value.
319 This is the hashed, unique string for the numeral
320 whose value is chosen alternative. */
322 static char *current_alternative_string;
324 /* Used to simplify expressions. */
326 static rtx true_rtx, false_rtx;
328 /* Used to reduce calls to `strcmp' */
330 static char *alternative_name;
332 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
333 called. */
335 int reload_completed = 0;
337 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
338 to define it here. */
340 int optimize = 0;
342 /* Simplify an expression. Only call the routine if there is something to
343 simplify. */
344 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
345 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
346 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
348 /* Simplify (eq_attr ("alternative") ...)
349 when we are working with a particular alternative. */
350 #define SIMPLIFY_ALTERNATIVE(EXP) \
351 if (current_alternative_string \
352 && GET_CODE ((EXP)) == EQ_ATTR \
353 && XSTR ((EXP), 0) == alternative_name) \
354 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
355 ? true_rtx : false_rtx);
357 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
358 They won't actually be used. */
360 struct _global_rtl global_rtl;
361 rtx pic_offset_table_rtx;
363 static void attr_hash_add_rtx PROTO((int, rtx));
364 static void attr_hash_add_string PROTO((int, char *));
365 static rtx attr_rtx PVPROTO((enum rtx_code, ...));
366 static char *attr_printf PVPROTO((int, const char *, ...))
367 ATTRIBUTE_PRINTF_2;
368 static char *attr_string PROTO((const char *, int));
369 static rtx check_attr_test PROTO((rtx, int));
370 static rtx check_attr_value PROTO((rtx, struct attr_desc *));
371 static rtx convert_set_attr_alternative PROTO((rtx, int, int));
372 static rtx convert_set_attr PROTO((rtx, int, int));
373 static void check_defs PROTO((void));
374 #if 0
375 static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *));
376 #endif
377 static rtx make_canonical PROTO((struct attr_desc *, rtx));
378 static struct attr_value *get_attr_value PROTO((rtx, struct attr_desc *, int));
379 static rtx copy_rtx_unchanging PROTO((rtx));
380 static rtx copy_boolean PROTO((rtx));
381 static void expand_delays PROTO((void));
382 static rtx operate_exp PROTO((enum operator, rtx, rtx));
383 static void expand_units PROTO((void));
384 static rtx simplify_knowing PROTO((rtx, rtx));
385 static rtx encode_units_mask PROTO((rtx));
386 static void fill_attr PROTO((struct attr_desc *));
387 /* dpx2 compiler chokes if we specify the arg types of the args. */
388 static rtx substitute_address PROTO((rtx, rtx (*) (rtx), rtx (*) (rtx)));
389 static void make_length_attrs PROTO((void));
390 static rtx identity_fn PROTO((rtx));
391 static rtx zero_fn PROTO((rtx));
392 static rtx one_fn PROTO((rtx));
393 static rtx max_fn PROTO((rtx));
394 static void write_length_unit_log PROTO ((void));
395 static rtx simplify_cond PROTO((rtx, int, int));
396 #if 0
397 static rtx simplify_by_alternatives PROTO((rtx, int, int));
398 #endif
399 static rtx simplify_by_exploding PROTO((rtx));
400 static int find_and_mark_used_attributes PROTO((rtx, rtx *, int *));
401 static void unmark_used_attributes PROTO((rtx, struct dimension *, int));
402 static int add_values_to_cover PROTO((struct dimension *));
403 static int increment_current_value PROTO((struct dimension *, int));
404 static rtx test_for_current_value PROTO((struct dimension *, int));
405 static rtx simplify_with_current_value PROTO((rtx, struct dimension *, int));
406 static rtx simplify_with_current_value_aux PROTO((rtx));
407 static void clear_struct_flag PROTO((rtx));
408 static int count_sub_rtxs PROTO((rtx, int));
409 static void remove_insn_ent PROTO((struct attr_value *, struct insn_ent *));
410 static void insert_insn_ent PROTO((struct attr_value *, struct insn_ent *));
411 static rtx insert_right_side PROTO((enum rtx_code, rtx, rtx, int, int));
412 static rtx make_alternative_compare PROTO((int));
413 static int compute_alternative_mask PROTO((rtx, enum rtx_code));
414 static rtx evaluate_eq_attr PROTO((rtx, rtx, int, int));
415 static rtx simplify_and_tree PROTO((rtx, rtx *, int, int));
416 static rtx simplify_or_tree PROTO((rtx, rtx *, int, int));
417 static rtx simplify_test_exp PROTO((rtx, int, int));
418 static void optimize_attrs PROTO((void));
419 static void gen_attr PROTO((rtx));
420 static int count_alternatives PROTO((rtx));
421 static int compares_alternatives_p PROTO((rtx));
422 static int contained_in_p PROTO((rtx, rtx));
423 static void gen_insn PROTO((rtx));
424 static void gen_delay PROTO((rtx));
425 static void gen_unit PROTO((rtx));
426 static void write_test_expr PROTO((rtx, int));
427 static int max_attr_value PROTO((rtx, int*));
428 static int or_attr_value PROTO((rtx, int*));
429 static void walk_attr_value PROTO((rtx));
430 static void write_attr_get PROTO((struct attr_desc *));
431 static rtx eliminate_known_true PROTO((rtx, rtx, int, int));
432 static void write_attr_set PROTO((struct attr_desc *, int, rtx,
433 const char *, const char *, rtx,
434 int, int));
435 static void write_attr_case PROTO((struct attr_desc *, struct attr_value *,
436 int, const char *, const char *, int, rtx));
437 static void write_unit_name PROTO((const char *, int, const char *));
438 static void write_attr_valueq PROTO((struct attr_desc *, char *));
439 static void write_attr_value PROTO((struct attr_desc *, rtx));
440 static void write_upcase PROTO((char *));
441 static void write_indent PROTO((int));
442 static void write_eligible_delay PROTO((const char *));
443 static void write_function_unit_info PROTO((void));
444 static void write_complex_function PROTO((struct function_unit *, const char *,
445 const char *));
446 static int write_expr_attr_cache PROTO((rtx, struct attr_desc *));
447 static void write_toplevel_expr PROTO((rtx));
448 static void write_const_num_delay_slots PROTO ((void));
449 static int n_comma_elts PROTO((char *));
450 static char *next_comma_elt PROTO((char **));
451 static struct attr_desc *find_attr PROTO((const char *, int));
452 static void make_internal_attr PROTO((const char *, rtx, int));
453 static struct attr_value *find_most_used PROTO((struct attr_desc *));
454 static rtx find_single_value PROTO((struct attr_desc *));
455 static rtx make_numeric_value PROTO((int));
456 static void extend_range PROTO((struct range *, int, int));
457 static rtx attr_eq PROTO((char *, char *));
458 static char *attr_numeral PROTO((int));
459 static int attr_equal_p PROTO((rtx, rtx));
460 static rtx attr_copy_rtx PROTO((rtx));
462 #define oballoc(size) obstack_alloc (hash_obstack, size)
465 /* Hash table for sharing RTL and strings. */
467 /* Each hash table slot is a bucket containing a chain of these structures.
468 Strings are given negative hash codes; RTL expressions are given positive
469 hash codes. */
471 struct attr_hash
473 struct attr_hash *next; /* Next structure in the bucket. */
474 int hashcode; /* Hash code of this rtx or string. */
475 union
477 char *str; /* The string (negative hash codes) */
478 rtx rtl; /* or the RTL recorded here. */
479 } u;
482 /* Now here is the hash table. When recording an RTL, it is added to
483 the slot whose index is the hash code mod the table size. Note
484 that the hash table is used for several kinds of RTL (see attr_rtx)
485 and for strings. While all these live in the same table, they are
486 completely independent, and the hash code is computed differently
487 for each. */
489 #define RTL_HASH_SIZE 4093
490 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
492 /* Here is how primitive or already-shared RTL's hash
493 codes are made. */
494 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
496 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
498 static void
499 attr_hash_add_rtx (hashcode, rtl)
500 int hashcode;
501 rtx rtl;
503 register struct attr_hash *h;
505 h = (struct attr_hash *) obstack_alloc (hash_obstack,
506 sizeof (struct attr_hash));
507 h->hashcode = hashcode;
508 h->u.rtl = rtl;
509 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
510 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
513 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
515 static void
516 attr_hash_add_string (hashcode, str)
517 int hashcode;
518 char *str;
520 register struct attr_hash *h;
522 h = (struct attr_hash *) obstack_alloc (hash_obstack,
523 sizeof (struct attr_hash));
524 h->hashcode = -hashcode;
525 h->u.str = str;
526 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
527 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
530 /* Generate an RTL expression, but avoid duplicates.
531 Set the RTX_INTEGRATED_P flag for these permanent objects.
533 In some cases we cannot uniquify; then we return an ordinary
534 impermanent rtx with RTX_INTEGRATED_P clear.
536 Args are like gen_rtx, but without the mode:
538 rtx attr_rtx (code, [element1, ..., elementn]) */
540 /*VARARGS1*/
541 static rtx
542 attr_rtx VPROTO((enum rtx_code code, ...))
544 #ifndef ANSI_PROTOTYPES
545 enum rtx_code code;
546 #endif
547 va_list p;
548 register int i; /* Array indices... */
549 register const char *fmt; /* Current rtx's format... */
550 register rtx rt_val; /* RTX to return to caller... */
551 int hashcode;
552 register struct attr_hash *h;
553 struct obstack *old_obstack = rtl_obstack;
555 VA_START (p, code);
557 #ifndef ANSI_PROTOTYPES
558 code = va_arg (p, enum rtx_code);
559 #endif
561 /* For each of several cases, search the hash table for an existing entry.
562 Use that entry if one is found; otherwise create a new RTL and add it
563 to the table. */
565 if (GET_RTX_CLASS (code) == '1')
567 rtx arg0 = va_arg (p, rtx);
569 /* A permanent object cannot point to impermanent ones. */
570 if (! RTX_INTEGRATED_P (arg0))
572 rt_val = rtx_alloc (code);
573 XEXP (rt_val, 0) = arg0;
574 va_end (p);
575 return rt_val;
578 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
579 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
580 if (h->hashcode == hashcode
581 && GET_CODE (h->u.rtl) == code
582 && XEXP (h->u.rtl, 0) == arg0)
583 goto found;
585 if (h == 0)
587 rtl_obstack = hash_obstack;
588 rt_val = rtx_alloc (code);
589 XEXP (rt_val, 0) = arg0;
592 else if (GET_RTX_CLASS (code) == 'c'
593 || GET_RTX_CLASS (code) == '2'
594 || GET_RTX_CLASS (code) == '<')
596 rtx arg0 = va_arg (p, rtx);
597 rtx arg1 = va_arg (p, rtx);
599 /* A permanent object cannot point to impermanent ones. */
600 if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
602 rt_val = rtx_alloc (code);
603 XEXP (rt_val, 0) = arg0;
604 XEXP (rt_val, 1) = arg1;
605 va_end (p);
606 return rt_val;
609 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
610 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
611 if (h->hashcode == hashcode
612 && GET_CODE (h->u.rtl) == code
613 && XEXP (h->u.rtl, 0) == arg0
614 && XEXP (h->u.rtl, 1) == arg1)
615 goto found;
617 if (h == 0)
619 rtl_obstack = hash_obstack;
620 rt_val = rtx_alloc (code);
621 XEXP (rt_val, 0) = arg0;
622 XEXP (rt_val, 1) = arg1;
625 else if (GET_RTX_LENGTH (code) == 1
626 && GET_RTX_FORMAT (code)[0] == 's')
628 char * arg0 = va_arg (p, char *);
630 if (code == SYMBOL_REF)
631 arg0 = attr_string (arg0, strlen (arg0));
633 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
634 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
635 if (h->hashcode == hashcode
636 && GET_CODE (h->u.rtl) == code
637 && XSTR (h->u.rtl, 0) == arg0)
638 goto found;
640 if (h == 0)
642 rtl_obstack = hash_obstack;
643 rt_val = rtx_alloc (code);
644 XSTR (rt_val, 0) = arg0;
647 else if (GET_RTX_LENGTH (code) == 2
648 && GET_RTX_FORMAT (code)[0] == 's'
649 && GET_RTX_FORMAT (code)[1] == 's')
651 char *arg0 = va_arg (p, char *);
652 char *arg1 = va_arg (p, char *);
654 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
655 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
656 if (h->hashcode == hashcode
657 && GET_CODE (h->u.rtl) == code
658 && XSTR (h->u.rtl, 0) == arg0
659 && XSTR (h->u.rtl, 1) == arg1)
660 goto found;
662 if (h == 0)
664 rtl_obstack = hash_obstack;
665 rt_val = rtx_alloc (code);
666 XSTR (rt_val, 0) = arg0;
667 XSTR (rt_val, 1) = arg1;
670 else if (code == CONST_INT)
672 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
673 if (arg0 == 0)
674 return false_rtx;
675 if (arg0 == 1)
676 return true_rtx;
677 goto nohash;
679 else
681 nohash:
682 rt_val = rtx_alloc (code); /* Allocate the storage space. */
684 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
685 for (i = 0; i < GET_RTX_LENGTH (code); i++)
687 switch (*fmt++)
689 case '0': /* Unused field. */
690 break;
692 case 'i': /* An integer? */
693 XINT (rt_val, i) = va_arg (p, int);
694 break;
696 case 'w': /* A wide integer? */
697 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
698 break;
700 case 's': /* A string? */
701 XSTR (rt_val, i) = va_arg (p, char *);
702 break;
704 case 'e': /* An expression? */
705 case 'u': /* An insn? Same except when printing. */
706 XEXP (rt_val, i) = va_arg (p, rtx);
707 break;
709 case 'E': /* An RTX vector? */
710 XVEC (rt_val, i) = va_arg (p, rtvec);
711 break;
713 default:
714 abort();
717 va_end (p);
718 return rt_val;
721 rtl_obstack = old_obstack;
722 va_end (p);
723 attr_hash_add_rtx (hashcode, rt_val);
724 RTX_INTEGRATED_P (rt_val) = 1;
725 return rt_val;
727 found:
728 va_end (p);
729 return h->u.rtl;
732 /* Create a new string printed with the printf line arguments into a space
733 of at most LEN bytes:
735 rtx attr_printf (len, format, [arg1, ..., argn]) */
737 /*VARARGS2*/
738 static char *
739 attr_printf VPROTO((register int len, const char *fmt, ...))
741 #ifndef ANSI_PROTOTYPES
742 register int len;
743 const char *fmt;
744 #endif
745 va_list p;
746 register char *str;
748 VA_START (p, fmt);
750 #ifndef ANSI_PROTOTYPES
751 len = va_arg (p, int);
752 fmt = va_arg (p, const char *);
753 #endif
755 /* Print the string into a temporary location. */
756 str = (char *) alloca (len);
757 vsprintf (str, fmt, p);
758 va_end (p);
760 return attr_string (str, strlen (str));
763 static rtx
764 attr_eq (name, value)
765 char *name, *value;
767 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
768 attr_string (value, strlen (value)));
771 static char *
772 attr_numeral (n)
773 int n;
775 return XSTR (make_numeric_value (n), 0);
778 /* Return a permanent (possibly shared) copy of a string STR (not assumed
779 to be null terminated) with LEN bytes. */
781 static char *
782 attr_string (str, len)
783 const char *str;
784 int len;
786 register struct attr_hash *h;
787 int hashcode;
788 int i;
789 register char *new_str;
791 /* Compute the hash code. */
792 hashcode = (len + 1) * 613 + (unsigned)str[0];
793 for (i = 1; i <= len; i += 2)
794 hashcode = ((hashcode * 613) + (unsigned)str[i]);
795 if (hashcode < 0)
796 hashcode = -hashcode;
798 /* Search the table for the string. */
799 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
800 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
801 && !strncmp (h->u.str, str, len))
802 return h->u.str; /* <-- return if found. */
804 /* Not found; create a permanent copy and add it to the hash table. */
805 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
806 bcopy (str, new_str, len);
807 new_str[len] = '\0';
808 attr_hash_add_string (hashcode, new_str);
810 return new_str; /* Return the new string. */
813 /* Check two rtx's for equality of contents,
814 taking advantage of the fact that if both are hashed
815 then they can't be equal unless they are the same object. */
817 static int
818 attr_equal_p (x, y)
819 rtx x, y;
821 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
822 && rtx_equal_p (x, y)));
825 /* Copy an attribute value expression,
826 descending to all depths, but not copying any
827 permanent hashed subexpressions. */
829 static rtx
830 attr_copy_rtx (orig)
831 register rtx orig;
833 register rtx copy;
834 register int i, j;
835 register RTX_CODE code;
836 register const char *format_ptr;
838 /* No need to copy a permanent object. */
839 if (RTX_INTEGRATED_P (orig))
840 return orig;
842 code = GET_CODE (orig);
844 switch (code)
846 case REG:
847 case QUEUED:
848 case CONST_INT:
849 case CONST_DOUBLE:
850 case SYMBOL_REF:
851 case CODE_LABEL:
852 case PC:
853 case CC0:
854 return orig;
856 default:
857 break;
860 copy = rtx_alloc (code);
861 PUT_MODE (copy, GET_MODE (orig));
862 copy->in_struct = orig->in_struct;
863 copy->volatil = orig->volatil;
864 copy->unchanging = orig->unchanging;
865 copy->integrated = orig->integrated;
867 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
869 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
871 switch (*format_ptr++)
873 case 'e':
874 XEXP (copy, i) = XEXP (orig, i);
875 if (XEXP (orig, i) != NULL)
876 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
877 break;
879 case 'E':
880 case 'V':
881 XVEC (copy, i) = XVEC (orig, i);
882 if (XVEC (orig, i) != NULL)
884 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
885 for (j = 0; j < XVECLEN (copy, i); j++)
886 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
888 break;
890 case 'n':
891 case 'i':
892 XINT (copy, i) = XINT (orig, i);
893 break;
895 case 'w':
896 XWINT (copy, i) = XWINT (orig, i);
897 break;
899 case 's':
900 case 'S':
901 XSTR (copy, i) = XSTR (orig, i);
902 break;
904 default:
905 abort ();
908 return copy;
911 /* Given a test expression for an attribute, ensure it is validly formed.
912 IS_CONST indicates whether the expression is constant for each compiler
913 run (a constant expression may not test any particular insn).
915 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
916 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
917 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
919 Update the string address in EQ_ATTR expression to be the same used
920 in the attribute (or `alternative_name') to speed up subsequent
921 `find_attr' calls and eliminate most `strcmp' calls.
923 Return the new expression, if any. */
925 static rtx
926 check_attr_test (exp, is_const)
927 rtx exp;
928 int is_const;
930 struct attr_desc *attr;
931 struct attr_value *av;
932 char *name_ptr, *p;
933 rtx orexp, newexp;
935 switch (GET_CODE (exp))
937 case EQ_ATTR:
938 /* Handle negation test. */
939 if (XSTR (exp, 1)[0] == '!')
940 return check_attr_test (attr_rtx (NOT,
941 attr_eq (XSTR (exp, 0),
942 &XSTR (exp, 1)[1])),
943 is_const);
945 else if (n_comma_elts (XSTR (exp, 1)) == 1)
947 attr = find_attr (XSTR (exp, 0), 0);
948 if (attr == NULL)
950 if (! strcmp (XSTR (exp, 0), "alternative"))
952 XSTR (exp, 0) = alternative_name;
953 /* This can't be simplified any further. */
954 RTX_UNCHANGING_P (exp) = 1;
955 return exp;
957 else
958 fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
961 if (is_const && ! attr->is_const)
962 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
963 XSTR (exp, 0));
965 /* Copy this just to make it permanent,
966 so expressions using it can be permanent too. */
967 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
969 /* It shouldn't be possible to simplify the value given to a
970 constant attribute, so don't expand this until it's time to
971 write the test expression. */
972 if (attr->is_const)
973 RTX_UNCHANGING_P (exp) = 1;
975 if (attr->is_numeric)
977 for (p = XSTR (exp, 1); *p; p++)
978 if (*p < '0' || *p > '9')
979 fatal ("Attribute `%s' takes only numeric values",
980 XSTR (exp, 0));
982 else
984 for (av = attr->first_value; av; av = av->next)
985 if (GET_CODE (av->value) == CONST_STRING
986 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
987 break;
989 if (av == NULL)
990 fatal ("Unknown value `%s' for `%s' attribute",
991 XSTR (exp, 1), XSTR (exp, 0));
994 else
996 /* Make an IOR tree of the possible values. */
997 orexp = false_rtx;
998 name_ptr = XSTR (exp, 1);
999 while ((p = next_comma_elt (&name_ptr)) != NULL)
1001 newexp = attr_eq (XSTR (exp, 0), p);
1002 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
1005 return check_attr_test (orexp, is_const);
1007 break;
1009 case ATTR_FLAG:
1010 break;
1012 case CONST_INT:
1013 /* Either TRUE or FALSE. */
1014 if (XWINT (exp, 0))
1015 return true_rtx;
1016 else
1017 return false_rtx;
1019 case IOR:
1020 case AND:
1021 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
1022 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const);
1023 break;
1025 case NOT:
1026 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
1027 break;
1029 case MATCH_INSN:
1030 case MATCH_OPERAND:
1031 if (is_const)
1032 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1033 GET_RTX_NAME (GET_CODE (exp)));
1034 /* These cases can't be simplified. */
1035 RTX_UNCHANGING_P (exp) = 1;
1036 break;
1038 case LE: case LT: case GT: case GE:
1039 case LEU: case LTU: case GTU: case GEU:
1040 case NE: case EQ:
1041 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1042 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1043 exp = attr_rtx (GET_CODE (exp),
1044 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1045 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
1046 /* These cases can't be simplified. */
1047 RTX_UNCHANGING_P (exp) = 1;
1048 break;
1050 case SYMBOL_REF:
1051 if (is_const)
1053 /* These cases are valid for constant attributes, but can't be
1054 simplified. */
1055 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1056 RTX_UNCHANGING_P (exp) = 1;
1057 break;
1059 default:
1060 fatal ("RTL operator \"%s\" not valid in attribute test",
1061 GET_RTX_NAME (GET_CODE (exp)));
1064 return exp;
1067 /* Given an expression, ensure that it is validly formed and that all named
1068 attribute values are valid for the given attribute. Issue a fatal error
1069 if not. If no attribute is specified, assume a numeric attribute.
1071 Return a perhaps modified replacement expression for the value. */
1073 static rtx
1074 check_attr_value (exp, attr)
1075 rtx exp;
1076 struct attr_desc *attr;
1078 struct attr_value *av;
1079 char *p;
1080 int i;
1082 switch (GET_CODE (exp))
1084 case CONST_INT:
1085 if (attr && ! attr->is_numeric)
1086 fatal ("CONST_INT not valid for non-numeric `%s' attribute",
1087 attr->name);
1089 if (INTVAL (exp) < 0 && ! attr->negative_ok)
1090 fatal ("Negative numeric value specified for `%s' attribute",
1091 attr->name);
1093 break;
1095 case CONST_STRING:
1096 if (! strcmp (XSTR (exp, 0), "*"))
1097 break;
1099 if (attr == 0 || attr->is_numeric)
1101 p = XSTR (exp, 0);
1102 if (attr && attr->negative_ok && *p == '-')
1103 p++;
1104 for (; *p; p++)
1105 if (*p > '9' || *p < '0')
1106 fatal ("Non-numeric value for numeric `%s' attribute",
1107 attr ? attr->name : "internal");
1108 break;
1111 for (av = attr->first_value; av; av = av->next)
1112 if (GET_CODE (av->value) == CONST_STRING
1113 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1114 break;
1116 if (av == NULL)
1117 fatal ("Unknown value `%s' for `%s' attribute",
1118 XSTR (exp, 0), attr ? attr->name : "internal");
1120 break;
1122 case IF_THEN_ELSE:
1123 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1124 attr ? attr->is_const : 0);
1125 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1126 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1127 break;
1129 case PLUS:
1130 case MINUS:
1131 case MULT:
1132 case DIV:
1133 case MOD:
1134 if (attr && !attr->is_numeric)
1135 fatal ("Invalid operation `%s' for non-numeric attribute value",
1136 GET_RTX_NAME (GET_CODE (exp)));
1137 /* FALLTHRU */
1139 case IOR:
1140 case AND:
1141 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1142 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1143 break;
1145 case FFS:
1146 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1147 break;
1149 case COND:
1150 if (XVECLEN (exp, 0) % 2 != 0)
1151 fatal ("First operand of COND must have even length");
1153 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1155 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1156 attr ? attr->is_const : 0);
1157 XVECEXP (exp, 0, i + 1)
1158 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1161 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1162 break;
1164 case ATTR:
1166 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
1167 if (attr2 == NULL)
1168 fatal ("Unknown attribute `%s' in ATTR", XSTR (exp, 0));
1169 else if ((attr && attr->is_const) && ! attr2->is_const)
1170 fatal ("Non-constant attribute `%s' referenced from `%s'",
1171 XSTR (exp, 0), attr->name);
1172 else if (attr
1173 && (attr->is_numeric != attr2->is_numeric
1174 || (! attr->negative_ok && attr2->negative_ok)))
1175 fatal ("Numeric attribute mismatch calling `%s' from `%s'",
1176 XSTR (exp, 0), attr->name);
1178 break;
1180 case SYMBOL_REF:
1181 /* A constant SYMBOL_REF is valid as a constant attribute test and
1182 is expanded later by make_canonical into a COND. In a non-constant
1183 attribute test, it is left be. */
1184 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1186 default:
1187 fatal ("Invalid operation `%s' for attribute value",
1188 GET_RTX_NAME (GET_CODE (exp)));
1191 return exp;
1194 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1195 It becomes a COND with each test being (eq_attr "alternative "n") */
1197 static rtx
1198 convert_set_attr_alternative (exp, num_alt, insn_index)
1199 rtx exp;
1200 int num_alt;
1201 int insn_index;
1203 rtx condexp;
1204 int i;
1206 if (XVECLEN (exp, 1) != num_alt)
1207 fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
1208 insn_index);
1210 /* Make a COND with all tests but the last. Select the last value via the
1211 default. */
1212 condexp = rtx_alloc (COND);
1213 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1215 for (i = 0; i < num_alt - 1; i++)
1217 char *p;
1218 p = attr_numeral (i);
1220 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1221 #if 0
1222 /* Sharing this EQ_ATTR rtl causes trouble. */
1223 XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
1224 XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
1225 XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p;
1226 #endif
1227 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1230 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1232 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1235 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1236 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1238 static rtx
1239 convert_set_attr (exp, num_alt, insn_index)
1240 rtx exp;
1241 int num_alt;
1242 int insn_index;
1244 rtx newexp;
1245 char *name_ptr;
1246 char *p;
1247 int n;
1249 /* See how many alternative specified. */
1250 n = n_comma_elts (XSTR (exp, 1));
1251 if (n == 1)
1252 return attr_rtx (SET,
1253 attr_rtx (ATTR, XSTR (exp, 0)),
1254 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1256 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1257 XSTR (newexp, 0) = XSTR (exp, 0);
1258 XVEC (newexp, 1) = rtvec_alloc (n);
1260 /* Process each comma-separated name. */
1261 name_ptr = XSTR (exp, 1);
1262 n = 0;
1263 while ((p = next_comma_elt (&name_ptr)) != NULL)
1264 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1266 return convert_set_attr_alternative (newexp, num_alt, insn_index);
1269 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1270 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1271 expressions. */
1273 static void
1274 check_defs ()
1276 struct insn_def *id;
1277 struct attr_desc *attr;
1278 int i;
1279 rtx value;
1281 for (id = defs; id; id = id->next)
1283 if (XVEC (id->def, id->vec_idx) == NULL)
1284 continue;
1286 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1288 value = XVECEXP (id->def, id->vec_idx, i);
1289 switch (GET_CODE (value))
1291 case SET:
1292 if (GET_CODE (XEXP (value, 0)) != ATTR)
1293 fatal ("Bad attribute set in pattern %d", id->insn_index);
1294 break;
1296 case SET_ATTR_ALTERNATIVE:
1297 value = convert_set_attr_alternative (value,
1298 id->num_alternatives,
1299 id->insn_index);
1300 break;
1302 case SET_ATTR:
1303 value = convert_set_attr (value, id->num_alternatives,
1304 id->insn_index);
1305 break;
1307 default:
1308 fatal ("Invalid attribute code `%s' for pattern %d",
1309 GET_RTX_NAME (GET_CODE (value)), id->insn_index);
1312 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1313 fatal ("Unknown attribute `%s' for pattern number %d",
1314 XSTR (XEXP (value, 0), 0), id->insn_index);
1316 XVECEXP (id->def, id->vec_idx, i) = value;
1317 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1322 #if 0
1323 /* Given a constant SYMBOL_REF expression, convert to a COND that
1324 explicitly tests each enumerated value. */
1326 static rtx
1327 convert_const_symbol_ref (exp, attr)
1328 rtx exp;
1329 struct attr_desc *attr;
1331 rtx condexp;
1332 struct attr_value *av;
1333 int i;
1334 int num_alt = 0;
1336 for (av = attr->first_value; av; av = av->next)
1337 num_alt++;
1339 /* Make a COND with all tests but the last, and in the original order.
1340 Select the last value via the default. Note that the attr values
1341 are constructed in reverse order. */
1343 condexp = rtx_alloc (COND);
1344 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1345 av = attr->first_value;
1346 XEXP (condexp, 1) = av->value;
1348 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1350 char *p, *string;
1351 rtx value;
1353 string = p = (char *) oballoc (2
1354 + strlen (attr->name)
1355 + strlen (XSTR (av->value, 0)));
1356 strcpy (p, attr->name);
1357 strcat (p, "_");
1358 strcat (p, XSTR (av->value, 0));
1359 for (; *p != '\0'; p++)
1360 if (ISLOWER(*p))
1361 *p = toupper (*p);
1363 value = attr_rtx (SYMBOL_REF, string);
1364 RTX_UNCHANGING_P (value) = 1;
1366 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1368 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1371 return condexp;
1373 #endif
1375 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1376 expressions by converting them into a COND. This removes cases from this
1377 program. Also, replace an attribute value of "*" with the default attribute
1378 value. */
1380 static rtx
1381 make_canonical (attr, exp)
1382 struct attr_desc *attr;
1383 rtx exp;
1385 int i;
1386 rtx newexp;
1388 switch (GET_CODE (exp))
1390 case CONST_INT:
1391 exp = make_numeric_value (INTVAL (exp));
1392 break;
1394 case CONST_STRING:
1395 if (! strcmp (XSTR (exp, 0), "*"))
1397 if (attr == 0 || attr->default_val == 0)
1398 fatal ("(attr_value \"*\") used in invalid context.");
1399 exp = attr->default_val->value;
1402 break;
1404 case SYMBOL_REF:
1405 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1406 break;
1407 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1408 This makes the COND something that won't be considered an arbitrary
1409 expression by walk_attr_value. */
1410 RTX_UNCHANGING_P (exp) = 1;
1411 #if 0
1412 /* ??? Why do we do this? With attribute values { A B C D E }, this
1413 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1414 than (x==E). */
1415 exp = convert_const_symbol_ref (exp, attr);
1416 RTX_UNCHANGING_P (exp) = 1;
1417 exp = check_attr_value (exp, attr);
1418 /* Goto COND case since this is now a COND. Note that while the
1419 new expression is rescanned, all symbol_ref notes are marked as
1420 unchanging. */
1421 goto cond;
1422 #else
1423 exp = check_attr_value (exp, attr);
1424 break;
1425 #endif
1427 case IF_THEN_ELSE:
1428 newexp = rtx_alloc (COND);
1429 XVEC (newexp, 0) = rtvec_alloc (2);
1430 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1431 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1433 XEXP (newexp, 1) = XEXP (exp, 2);
1435 exp = newexp;
1436 /* Fall through to COND case since this is now a COND. */
1438 case COND:
1440 int allsame = 1;
1441 rtx defval;
1443 /* First, check for degenerate COND. */
1444 if (XVECLEN (exp, 0) == 0)
1445 return make_canonical (attr, XEXP (exp, 1));
1446 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1448 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1450 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1451 XVECEXP (exp, 0, i + 1)
1452 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1453 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1454 allsame = 0;
1456 if (allsame)
1457 return defval;
1459 break;
1461 default:
1462 break;
1465 return exp;
1468 static rtx
1469 copy_boolean (exp)
1470 rtx exp;
1472 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1473 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1474 copy_boolean (XEXP (exp, 1)));
1475 return exp;
1478 /* Given a value and an attribute description, return a `struct attr_value *'
1479 that represents that value. This is either an existing structure, if the
1480 value has been previously encountered, or a newly-created structure.
1482 `insn_code' is the code of an insn whose attribute has the specified
1483 value (-2 if not processing an insn). We ensure that all insns for
1484 a given value have the same number of alternatives if the value checks
1485 alternatives. */
1487 static struct attr_value *
1488 get_attr_value (value, attr, insn_code)
1489 rtx value;
1490 struct attr_desc *attr;
1491 int insn_code;
1493 struct attr_value *av;
1494 int num_alt = 0;
1496 value = make_canonical (attr, value);
1497 if (compares_alternatives_p (value))
1499 if (insn_code < 0 || insn_alternatives == NULL)
1500 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1501 else
1502 num_alt = insn_alternatives[insn_code];
1505 for (av = attr->first_value; av; av = av->next)
1506 if (rtx_equal_p (value, av->value)
1507 && (num_alt == 0 || av->first_insn == NULL
1508 || insn_alternatives[av->first_insn->insn_code]))
1509 return av;
1511 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1512 av->value = value;
1513 av->next = attr->first_value;
1514 attr->first_value = av;
1515 av->first_insn = NULL;
1516 av->num_insns = 0;
1517 av->has_asm_insn = 0;
1519 return av;
1522 /* After all DEFINE_DELAYs have been read in, create internal attributes
1523 to generate the required routines.
1525 First, we compute the number of delay slots for each insn (as a COND of
1526 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1527 delay type is specified, we compute a similar function giving the
1528 DEFINE_DELAY ordinal for each insn.
1530 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1531 tells whether a given insn can be in that delay slot.
1533 Normal attribute filling and optimization expands these to contain the
1534 information needed to handle delay slots. */
1536 static void
1537 expand_delays ()
1539 struct delay_desc *delay;
1540 rtx condexp;
1541 rtx newexp;
1542 int i;
1543 char *p;
1545 /* First, generate data for `num_delay_slots' function. */
1547 condexp = rtx_alloc (COND);
1548 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1549 XEXP (condexp, 1) = make_numeric_value (0);
1551 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1553 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1554 XVECEXP (condexp, 0, i + 1)
1555 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1558 make_internal_attr ("*num_delay_slots", condexp, 0);
1560 /* If more than one delay type, do the same for computing the delay type. */
1561 if (num_delays > 1)
1563 condexp = rtx_alloc (COND);
1564 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1565 XEXP (condexp, 1) = make_numeric_value (0);
1567 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1569 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1570 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1573 make_internal_attr ("*delay_type", condexp, 1);
1576 /* For each delay possibility and delay slot, compute an eligibility
1577 attribute for non-annulled insns and for each type of annulled (annul
1578 if true and annul if false). */
1579 for (delay = delays; delay; delay = delay->next)
1581 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1583 condexp = XVECEXP (delay->def, 1, i);
1584 if (condexp == 0) condexp = false_rtx;
1585 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1586 make_numeric_value (1), make_numeric_value (0));
1588 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS*2, "*delay_%d_%d",
1589 delay->num, i / 3);
1590 make_internal_attr (p, newexp, 1);
1592 if (have_annul_true)
1594 condexp = XVECEXP (delay->def, 1, i + 1);
1595 if (condexp == 0) condexp = false_rtx;
1596 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1597 make_numeric_value (1),
1598 make_numeric_value (0));
1599 p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS*2,
1600 "*annul_true_%d_%d", delay->num, i / 3);
1601 make_internal_attr (p, newexp, 1);
1604 if (have_annul_false)
1606 condexp = XVECEXP (delay->def, 1, i + 2);
1607 if (condexp == 0) condexp = false_rtx;
1608 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1609 make_numeric_value (1),
1610 make_numeric_value (0));
1611 p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS*2,
1612 "*annul_false_%d_%d", delay->num, i / 3);
1613 make_internal_attr (p, newexp, 1);
1619 /* This function is given a left and right side expression and an operator.
1620 Each side is a conditional expression, each alternative of which has a
1621 numerical value. The function returns another conditional expression
1622 which, for every possible set of condition values, returns a value that is
1623 the operator applied to the values of the two sides.
1625 Since this is called early, it must also support IF_THEN_ELSE. */
1627 static rtx
1628 operate_exp (op, left, right)
1629 enum operator op;
1630 rtx left, right;
1632 int left_value, right_value;
1633 rtx newexp;
1634 int i;
1636 /* If left is a string, apply operator to it and the right side. */
1637 if (GET_CODE (left) == CONST_STRING)
1639 /* If right is also a string, just perform the operation. */
1640 if (GET_CODE (right) == CONST_STRING)
1642 left_value = atoi (XSTR (left, 0));
1643 right_value = atoi (XSTR (right, 0));
1644 switch (op)
1646 case PLUS_OP:
1647 i = left_value + right_value;
1648 break;
1650 case MINUS_OP:
1651 i = left_value - right_value;
1652 break;
1654 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1655 if (left_value > right_value)
1656 i = left_value - right_value;
1657 else
1658 i = 0;
1659 break;
1661 case OR_OP:
1662 case ORX_OP:
1663 i = left_value | right_value;
1664 break;
1666 case EQ_OP:
1667 i = left_value == right_value;
1668 break;
1670 case RANGE_OP:
1671 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1672 break;
1674 case MAX_OP:
1675 if (left_value > right_value)
1676 i = left_value;
1677 else
1678 i = right_value;
1679 break;
1681 case MIN_OP:
1682 if (left_value < right_value)
1683 i = left_value;
1684 else
1685 i = right_value;
1686 break;
1688 default:
1689 abort ();
1692 if (i == left_value)
1693 return left;
1694 if (i == right_value)
1695 return right;
1696 return make_numeric_value (i);
1698 else if (GET_CODE (right) == IF_THEN_ELSE)
1700 /* Apply recursively to all values within. */
1701 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1702 rtx newright = operate_exp (op, left, XEXP (right, 2));
1703 if (rtx_equal_p (newleft, newright))
1704 return newleft;
1705 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1707 else if (GET_CODE (right) == COND)
1709 int allsame = 1;
1710 rtx defval;
1712 newexp = rtx_alloc (COND);
1713 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1714 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1716 for (i = 0; i < XVECLEN (right, 0); i += 2)
1718 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1719 XVECEXP (newexp, 0, i + 1)
1720 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1721 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1722 defval))
1723 allsame = 0;
1726 /* If the resulting cond is trivial (all alternatives
1727 give the same value), optimize it away. */
1728 if (allsame)
1730 if (!ggc_p)
1731 obstack_free (rtl_obstack, newexp);
1732 return operate_exp (op, left, XEXP (right, 1));
1735 /* If the result is the same as the RIGHT operand,
1736 just use that. */
1737 if (rtx_equal_p (newexp, right))
1739 if (!ggc_p)
1740 obstack_free (rtl_obstack, newexp);
1741 return right;
1744 return newexp;
1746 else
1747 fatal ("Badly formed attribute value");
1750 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1751 not associate through IF_THEN_ELSE. */
1752 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1754 return attr_rtx (IOR, left, right);
1757 /* Otherwise, do recursion the other way. */
1758 else if (GET_CODE (left) == IF_THEN_ELSE)
1760 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1761 rtx newright = operate_exp (op, XEXP (left, 2), right);
1762 if (rtx_equal_p (newleft, newright))
1763 return newleft;
1764 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1766 else if (GET_CODE (left) == COND)
1768 int allsame = 1;
1769 rtx defval;
1771 newexp = rtx_alloc (COND);
1772 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1773 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1775 for (i = 0; i < XVECLEN (left, 0); i += 2)
1777 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1778 XVECEXP (newexp, 0, i + 1)
1779 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1780 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1781 defval))
1782 allsame = 0;
1785 /* If the cond is trivial (all alternatives give the same value),
1786 optimize it away. */
1787 if (allsame)
1789 if (!ggc_p)
1790 obstack_free (rtl_obstack, newexp);
1791 return operate_exp (op, XEXP (left, 1), right);
1794 /* If the result is the same as the LEFT operand,
1795 just use that. */
1796 if (rtx_equal_p (newexp, left))
1798 if (!ggc_p)
1799 obstack_free (rtl_obstack, newexp);
1800 return left;
1803 return newexp;
1806 else
1807 fatal ("Badly formed attribute value.");
1808 /* NOTREACHED */
1809 return NULL;
1812 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1813 construct a number of attributes.
1815 The first produces a function `function_units_used' which is given an
1816 insn and produces an encoding showing which function units are required
1817 for the execution of that insn. If the value is non-negative, the insn
1818 uses that unit; otherwise, the value is a one's compliment mask of units
1819 used.
1821 The second produces a function `result_ready_cost' which is used to
1822 determine the time that the result of an insn will be ready and hence
1823 a worst-case schedule.
1825 Both of these produce quite complex expressions which are then set as the
1826 default value of internal attributes. Normal attribute simplification
1827 should produce reasonable expressions.
1829 For each unit, a `<name>_unit_ready_cost' function will take an
1830 insn and give the delay until that unit will be ready with the result
1831 and a `<name>_unit_conflict_cost' function is given an insn already
1832 executing on the unit and a candidate to execute and will give the
1833 cost from the time the executing insn started until the candidate
1834 can start (ignore limitations on the number of simultaneous insns).
1836 For each unit, a `<name>_unit_blockage' function is given an insn
1837 already executing on the unit and a candidate to execute and will
1838 give the delay incurred due to function unit conflicts. The range of
1839 blockage cost values for a given executing insn is given by the
1840 `<name>_unit_blockage_range' function. These values are encoded in
1841 an int where the upper half gives the minimum value and the lower
1842 half gives the maximum value. */
1844 static void
1845 expand_units ()
1847 struct function_unit *unit, **unit_num;
1848 struct function_unit_op *op, **op_array, ***unit_ops;
1849 rtx unitsmask;
1850 rtx readycost;
1851 rtx newexp;
1852 const char *str;
1853 int i, j, u, num, nvalues;
1855 /* Rebuild the condition for the unit to share the RTL expressions.
1856 Sharing is required by simplify_by_exploding. Build the issue delay
1857 expressions. Validate the expressions we were given for the conditions
1858 and conflict vector. Then make attributes for use in the conflict
1859 function. */
1861 for (unit = units; unit; unit = unit->next)
1863 unit->condexp = check_attr_test (unit->condexp, 0);
1865 for (op = unit->ops; op; op = op->next)
1867 rtx issue_delay = make_numeric_value (op->issue_delay);
1868 rtx issue_exp = issue_delay;
1870 /* Build, validate, and simplify the issue delay expression. */
1871 if (op->conflict_exp != true_rtx)
1872 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1873 issue_exp, make_numeric_value (0));
1874 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1875 issue_exp),
1876 NULL_ATTR);
1877 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1878 op->issue_exp = issue_exp;
1880 /* Make an attribute for use in the conflict function if needed. */
1881 unit->needs_conflict_function = (unit->issue_delay.min
1882 != unit->issue_delay.max);
1883 if (unit->needs_conflict_function)
1885 str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1886 "*%s_cost_%d", unit->name, op->num);
1887 make_internal_attr (str, issue_exp, 1);
1890 /* Validate the condition. */
1891 op->condexp = check_attr_test (op->condexp, 0);
1895 /* Compute the mask of function units used. Initially, the unitsmask is
1896 zero. Set up a conditional to compute each unit's contribution. */
1897 unitsmask = make_numeric_value (0);
1898 newexp = rtx_alloc (IF_THEN_ELSE);
1899 XEXP (newexp, 2) = make_numeric_value (0);
1901 /* If we have just a few units, we may be all right expanding the whole
1902 thing. But the expansion is 2**N in space on the number of opclasses,
1903 so we can't do this for very long -- Alpha and MIPS in particular have
1904 problems with this. So in that situation, we fall back on an alternate
1905 implementation method. */
1906 #define NUM_UNITOP_CUTOFF 20
1908 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1910 /* Merge each function unit into the unit mask attributes. */
1911 for (unit = units; unit; unit = unit->next)
1913 XEXP (newexp, 0) = unit->condexp;
1914 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1915 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1918 else
1920 /* Merge each function unit into the unit mask attributes. */
1921 for (unit = units; unit; unit = unit->next)
1923 XEXP (newexp, 0) = unit->condexp;
1924 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1925 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1929 /* Simplify the unit mask expression, encode it, and make an attribute
1930 for the function_units_used function. */
1931 unitsmask = simplify_by_exploding (unitsmask);
1933 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1934 unitsmask = encode_units_mask (unitsmask);
1935 else
1937 /* We can no longer encode unitsmask at compile time, so emit code to
1938 calculate it at runtime. Rather, put a marker for where we'd do
1939 the code, and actually output it in write_attr_get(). */
1940 unitsmask = attr_rtx (FFS, unitsmask);
1943 make_internal_attr ("*function_units_used", unitsmask, 10);
1945 /* Create an array of ops for each unit. Add an extra unit for the
1946 result_ready_cost function that has the ops of all other units. */
1947 unit_ops = (struct function_unit_op ***)
1948 alloca ((num_units + 1) * sizeof (struct function_unit_op **));
1949 unit_num = (struct function_unit **)
1950 alloca ((num_units + 1) * sizeof (struct function_unit *));
1952 unit_num[num_units] = unit = (struct function_unit *)
1953 alloca (sizeof (struct function_unit));
1954 unit->num = num_units;
1955 unit->num_opclasses = 0;
1957 for (unit = units; unit; unit = unit->next)
1959 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1960 unit_num[unit->num] = unit;
1961 unit_ops[unit->num] = op_array = (struct function_unit_op **)
1962 alloca (unit->num_opclasses * sizeof (struct function_unit_op *));
1964 for (op = unit->ops; op; op = op->next)
1965 op_array[op->num] = op;
1968 /* Compose the array of ops for the extra unit. */
1969 unit_ops[num_units] = op_array = (struct function_unit_op **)
1970 alloca (unit_num[num_units]->num_opclasses
1971 * sizeof (struct function_unit_op *));
1973 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
1974 bcopy ((char *) unit_ops[unit->num], (char *) &op_array[i],
1975 unit->num_opclasses * sizeof (struct function_unit_op *));
1977 /* Compute the ready cost function for each unit by computing the
1978 condition for each non-default value. */
1979 for (u = 0; u <= num_units; u++)
1981 rtx orexp;
1982 int value;
1984 unit = unit_num[u];
1985 op_array = unit_ops[unit->num];
1986 num = unit->num_opclasses;
1988 /* Sort the array of ops into increasing ready cost order. */
1989 for (i = 0; i < num; i++)
1990 for (j = num - 1; j > i; j--)
1991 if (op_array[j-1]->ready < op_array[j]->ready)
1993 op = op_array[j];
1994 op_array[j] = op_array[j-1];
1995 op_array[j-1] = op;
1998 /* Determine how many distinct non-default ready cost values there
1999 are. We use a default ready cost value of 1. */
2000 nvalues = 0; value = 1;
2001 for (i = num - 1; i >= 0; i--)
2002 if (op_array[i]->ready > value)
2004 value = op_array[i]->ready;
2005 nvalues++;
2008 if (nvalues == 0)
2009 readycost = make_numeric_value (1);
2010 else
2012 /* Construct the ready cost expression as a COND of each value from
2013 the largest to the smallest. */
2014 readycost = rtx_alloc (COND);
2015 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2016 XEXP (readycost, 1) = make_numeric_value (1);
2018 nvalues = 0; orexp = false_rtx; value = op_array[0]->ready;
2019 for (i = 0; i < num; i++)
2021 op = op_array[i];
2022 if (op->ready <= 1)
2023 break;
2024 else if (op->ready == value)
2025 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
2026 else
2028 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2029 XVECEXP (readycost, 0, nvalues * 2 + 1)
2030 = make_numeric_value (value);
2031 nvalues++;
2032 value = op->ready;
2033 orexp = op->condexp;
2036 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2037 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2040 if (u < num_units)
2042 rtx max_blockage = 0, min_blockage = 0;
2044 /* Simplify the readycost expression by only considering insns
2045 that use the unit. */
2046 readycost = simplify_knowing (readycost, unit->condexp);
2048 /* Determine the blockage cost the executing insn (E) given
2049 the candidate insn (C). This is the maximum of the issue
2050 delay, the pipeline delay, and the simultaneity constraint.
2051 Each function_unit_op represents the characteristics of the
2052 candidate insn, so in the expressions below, C is a known
2053 term and E is an unknown term.
2055 We compute the blockage cost for each E for every possible C.
2056 Thus OP represents E, and READYCOST is a list of values for
2057 every possible C.
2059 The issue delay function for C is op->issue_exp and is used to
2060 write the `<name>_unit_conflict_cost' function. Symbolicly
2061 this is "ISSUE-DELAY (E,C)".
2063 The pipeline delay results form the FIFO constraint on the
2064 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2066 The simultaneity constraint is based on how long it takes to
2067 fill the unit given the minimum issue delay. FILL-TIME is the
2068 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2069 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2070 if SIMULTANEITY is non-zero and zero otherwise.
2072 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2074 MAX (ISSUE-DELAY (E,C),
2075 READY-COST (E) - (READY-COST (C) - 1))
2077 and otherwise
2079 MAX (ISSUE-DELAY (E,C),
2080 READY-COST (E) - (READY-COST (C) - 1),
2081 READY-COST (E) - FILL-TIME)
2083 The `<name>_unit_blockage' function is computed by determining
2084 this value for each candidate insn. As these values are
2085 computed, we also compute the upper and lower bounds for
2086 BLOCKAGE (E,*). These are combined to form the function
2087 `<name>_unit_blockage_range'. Finally, the maximum blockage
2088 cost, MAX (BLOCKAGE (*,*)), is computed. */
2090 for (op = unit->ops; op; op = op->next)
2092 rtx blockage = op->issue_exp;
2093 blockage = simplify_knowing (blockage, unit->condexp);
2095 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2096 MIN (BLOCKAGE (E,*)). */
2097 if (max_blockage == 0)
2098 max_blockage = min_blockage = blockage;
2099 else
2101 max_blockage
2102 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2103 blockage),
2104 unit->condexp);
2105 min_blockage
2106 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2107 blockage),
2108 unit->condexp);
2111 /* Make an attribute for use in the blockage function. */
2112 str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2113 "*%s_block_%d", unit->name, op->num);
2114 make_internal_attr (str, blockage, 1);
2117 /* Record MAX (BLOCKAGE (*,*)). */
2119 int unknown;
2120 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2123 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2124 same. If so, the blockage function carries no additional
2125 information and is not written. */
2126 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2127 newexp = simplify_knowing (newexp, unit->condexp);
2128 unit->needs_blockage_function
2129 = (GET_CODE (newexp) != CONST_STRING
2130 || atoi (XSTR (newexp, 0)) != 1);
2132 /* If the all values of BLOCKAGE (E,C) have the same value,
2133 neither blockage function is written. */
2134 unit->needs_range_function
2135 = (unit->needs_blockage_function
2136 || GET_CODE (max_blockage) != CONST_STRING);
2138 if (unit->needs_range_function)
2140 /* Compute the blockage range function and make an attribute
2141 for writing its value. */
2142 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2143 newexp = simplify_knowing (newexp, unit->condexp);
2145 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
2146 "*%s_unit_blockage_range", unit->name);
2147 make_internal_attr (str, newexp, 20);
2150 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2151 "*%s_unit_ready_cost", unit->name);
2153 else
2154 str = "*result_ready_cost";
2156 /* Make an attribute for the ready_cost function. Simplifying
2157 further with simplify_by_exploding doesn't win. */
2158 make_internal_attr (str, readycost, 0);
2161 /* For each unit that requires a conflict cost function, make an attribute
2162 that maps insns to the operation number. */
2163 for (unit = units; unit; unit = unit->next)
2165 rtx caseexp;
2167 if (! unit->needs_conflict_function
2168 && ! unit->needs_blockage_function)
2169 continue;
2171 caseexp = rtx_alloc (COND);
2172 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2174 for (op = unit->ops; op; op = op->next)
2176 /* Make our adjustment to the COND being computed. If we are the
2177 last operation class, place our values into the default of the
2178 COND. */
2179 if (op->num == unit->num_opclasses - 1)
2181 XEXP (caseexp, 1) = make_numeric_value (op->num);
2183 else
2185 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2186 XVECEXP (caseexp, 0, op->num * 2 + 1)
2187 = make_numeric_value (op->num);
2191 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2192 str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2193 "*%s_cases", unit->name);
2194 make_internal_attr (str, caseexp, 1);
2198 /* Simplify EXP given KNOWN_TRUE. */
2200 static rtx
2201 simplify_knowing (exp, known_true)
2202 rtx exp, known_true;
2204 if (GET_CODE (exp) != CONST_STRING)
2206 int unknown = 0, max;
2207 max = max_attr_value (exp, &unknown);
2208 if (! unknown)
2210 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2211 make_numeric_value (max));
2212 exp = simplify_by_exploding (exp);
2215 return exp;
2218 /* Translate the CONST_STRING expressions in X to change the encoding of
2219 value. On input, the value is a bitmask with a one bit for each unit
2220 used; on output, the value is the unit number (zero based) if one
2221 and only one unit is used or the one's compliment of the bitmask. */
2223 static rtx
2224 encode_units_mask (x)
2225 rtx x;
2227 register int i;
2228 register int j;
2229 register enum rtx_code code;
2230 register const char *fmt;
2232 code = GET_CODE (x);
2234 switch (code)
2236 case CONST_STRING:
2237 i = atoi (XSTR (x, 0));
2238 if (i < 0)
2239 abort (); /* The sign bit encodes a one's compliment mask. */
2240 else if (i != 0 && i == (i & -i))
2241 /* Only one bit is set, so yield that unit number. */
2242 for (j = 0; (i >>= 1) != 0; j++)
2244 else
2245 j = ~i;
2246 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2248 case REG:
2249 case QUEUED:
2250 case CONST_INT:
2251 case CONST_DOUBLE:
2252 case SYMBOL_REF:
2253 case CODE_LABEL:
2254 case PC:
2255 case CC0:
2256 case EQ_ATTR:
2257 return x;
2259 default:
2260 break;
2263 /* Compare the elements. If any pair of corresponding elements
2264 fail to match, return 0 for the whole things. */
2266 fmt = GET_RTX_FORMAT (code);
2267 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2269 switch (fmt[i])
2271 case 'V':
2272 case 'E':
2273 for (j = 0; j < XVECLEN (x, i); j++)
2274 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2275 break;
2277 case 'e':
2278 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2279 break;
2282 return x;
2285 /* Once all attributes and insns have been read and checked, we construct for
2286 each attribute value a list of all the insns that have that value for
2287 the attribute. */
2289 static void
2290 fill_attr (attr)
2291 struct attr_desc *attr;
2293 struct attr_value *av;
2294 struct insn_ent *ie;
2295 struct insn_def *id;
2296 int i;
2297 rtx value;
2299 /* Don't fill constant attributes. The value is independent of
2300 any particular insn. */
2301 if (attr->is_const)
2302 return;
2304 for (id = defs; id; id = id->next)
2306 /* If no value is specified for this insn for this attribute, use the
2307 default. */
2308 value = NULL;
2309 if (XVEC (id->def, id->vec_idx))
2310 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2311 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2312 attr->name))
2313 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2315 if (value == NULL)
2316 av = attr->default_val;
2317 else
2318 av = get_attr_value (value, attr, id->insn_code);
2320 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2321 ie->insn_code = id->insn_code;
2322 ie->insn_index = id->insn_code;
2323 insert_insn_ent (av, ie);
2327 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2328 test that checks relative positions of insns (uses MATCH_DUP or PC).
2329 If so, replace it with what is obtained by passing the expression to
2330 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2331 recursively on each value (including the default value). Otherwise,
2332 return the value returned by NO_ADDRESS_FN applied to EXP. */
2334 static rtx
2335 substitute_address (exp, no_address_fn, address_fn)
2336 rtx exp;
2337 rtx (*no_address_fn) PROTO ((rtx));
2338 rtx (*address_fn) PROTO ((rtx));
2340 int i;
2341 rtx newexp;
2343 if (GET_CODE (exp) == COND)
2345 /* See if any tests use addresses. */
2346 address_used = 0;
2347 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2348 walk_attr_value (XVECEXP (exp, 0, i));
2350 if (address_used)
2351 return (*address_fn) (exp);
2353 /* Make a new copy of this COND, replacing each element. */
2354 newexp = rtx_alloc (COND);
2355 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2356 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2358 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2359 XVECEXP (newexp, 0, i + 1)
2360 = substitute_address (XVECEXP (exp, 0, i + 1),
2361 no_address_fn, address_fn);
2364 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2365 no_address_fn, address_fn);
2367 return newexp;
2370 else if (GET_CODE (exp) == IF_THEN_ELSE)
2372 address_used = 0;
2373 walk_attr_value (XEXP (exp, 0));
2374 if (address_used)
2375 return (*address_fn) (exp);
2377 return attr_rtx (IF_THEN_ELSE,
2378 substitute_address (XEXP (exp, 0),
2379 no_address_fn, address_fn),
2380 substitute_address (XEXP (exp, 1),
2381 no_address_fn, address_fn),
2382 substitute_address (XEXP (exp, 2),
2383 no_address_fn, address_fn));
2386 return (*no_address_fn) (exp);
2389 /* Make new attributes from the `length' attribute. The following are made,
2390 each corresponding to a function called from `shorten_branches' or
2391 `get_attr_length':
2393 *insn_default_length This is the length of the insn to be returned
2394 by `get_attr_length' before `shorten_branches'
2395 has been called. In each case where the length
2396 depends on relative addresses, the largest
2397 possible is used. This routine is also used
2398 to compute the initial size of the insn.
2400 *insn_variable_length_p This returns 1 if the insn's length depends
2401 on relative addresses, zero otherwise.
2403 *insn_current_length This is only called when it is known that the
2404 insn has a variable length and returns the
2405 current length, based on relative addresses.
2408 static void
2409 make_length_attrs ()
2411 static const char *new_names[] = {"*insn_default_length",
2412 "*insn_variable_length_p",
2413 "*insn_current_length"};
2414 static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
2415 static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
2416 size_t i;
2417 struct attr_desc *length_attr, *new_attr;
2418 struct attr_value *av, *new_av;
2419 struct insn_ent *ie, *new_ie;
2421 /* See if length attribute is defined. If so, it must be numeric. Make
2422 it special so we don't output anything for it. */
2423 length_attr = find_attr ("length", 0);
2424 if (length_attr == 0)
2425 return;
2427 if (! length_attr->is_numeric)
2428 fatal ("length attribute must be numeric.");
2430 length_attr->is_const = 0;
2431 length_attr->is_special = 1;
2433 /* Make each new attribute, in turn. */
2434 for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
2436 make_internal_attr (new_names[i],
2437 substitute_address (length_attr->default_val->value,
2438 no_address_fn[i], address_fn[i]),
2440 new_attr = find_attr (new_names[i], 0);
2441 for (av = length_attr->first_value; av; av = av->next)
2442 for (ie = av->first_insn; ie; ie = ie->next)
2444 new_av = get_attr_value (substitute_address (av->value,
2445 no_address_fn[i],
2446 address_fn[i]),
2447 new_attr, ie->insn_code);
2448 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2449 new_ie->insn_code = ie->insn_code;
2450 new_ie->insn_index = ie->insn_index;
2451 insert_insn_ent (new_av, new_ie);
2456 /* Utility functions called from above routine. */
2458 static rtx
2459 identity_fn (exp)
2460 rtx exp;
2462 return exp;
2465 static rtx
2466 zero_fn (exp)
2467 rtx exp ATTRIBUTE_UNUSED;
2469 return make_numeric_value (0);
2472 static rtx
2473 one_fn (exp)
2474 rtx exp ATTRIBUTE_UNUSED;
2476 return make_numeric_value (1);
2479 static rtx
2480 max_fn (exp)
2481 rtx exp;
2483 int unknown;
2484 return make_numeric_value (max_attr_value (exp, &unknown));
2487 static void
2488 write_length_unit_log ()
2490 struct attr_desc *length_attr = find_attr ("length", 0);
2491 struct attr_value *av;
2492 struct insn_ent *ie;
2493 unsigned int length_unit_log, length_or;
2494 int unknown = 0;
2496 if (length_attr == 0)
2497 return;
2498 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2499 for (av = length_attr->first_value; av; av = av->next)
2500 for (ie = av->first_insn; ie; ie = ie->next)
2501 length_or |= or_attr_value (av->value, &unknown);
2503 if (unknown)
2504 length_unit_log = 0;
2505 else
2507 length_or = ~length_or;
2508 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
2509 length_unit_log++;
2511 printf ("int length_unit_log = %u;\n", length_unit_log);
2514 /* Take a COND expression and see if any of the conditions in it can be
2515 simplified. If any are known true or known false for the particular insn
2516 code, the COND can be further simplified.
2518 Also call ourselves on any COND operations that are values of this COND.
2520 We do not modify EXP; rather, we make and return a new rtx. */
2522 static rtx
2523 simplify_cond (exp, insn_code, insn_index)
2524 rtx exp;
2525 int insn_code, insn_index;
2527 int i, j;
2528 /* We store the desired contents here,
2529 then build a new expression if they don't match EXP. */
2530 rtx defval = XEXP (exp, 1);
2531 rtx new_defval = XEXP (exp, 1);
2532 int len = XVECLEN (exp, 0);
2533 rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion));
2534 int allsame = 1;
2535 char *first_spacer;
2537 /* This lets us free all storage allocated below, if appropriate. */
2538 first_spacer = (char *) obstack_finish (rtl_obstack);
2540 bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion));
2542 /* See if default value needs simplification. */
2543 if (GET_CODE (defval) == COND)
2544 new_defval = simplify_cond (defval, insn_code, insn_index);
2546 /* Simplify the subexpressions, and see what tests we can get rid of. */
2548 for (i = 0; i < len; i += 2)
2550 rtx newtest, newval;
2552 /* Simplify this test. */
2553 newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index);
2554 tests[i].rtx = newtest;
2556 newval = tests[i + 1].rtx;
2557 /* See if this value may need simplification. */
2558 if (GET_CODE (newval) == COND)
2559 newval = simplify_cond (newval, insn_code, insn_index);
2561 /* Look for ways to delete or combine this test. */
2562 if (newtest == true_rtx)
2564 /* If test is true, make this value the default
2565 and discard this + any following tests. */
2566 len = i;
2567 defval = tests[i + 1].rtx;
2568 new_defval = newval;
2571 else if (newtest == false_rtx)
2573 /* If test is false, discard it and its value. */
2574 for (j = i; j < len - 2; j++)
2575 tests[j].rtx = tests[j + 2].rtx;
2576 len -= 2;
2579 else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx))
2581 /* If this value and the value for the prev test are the same,
2582 merge the tests. */
2584 tests[i - 2].rtx
2585 = insert_right_side (IOR, tests[i - 2].rtx, newtest,
2586 insn_code, insn_index);
2588 /* Delete this test/value. */
2589 for (j = i; j < len - 2; j++)
2590 tests[j].rtx = tests[j + 2].rtx;
2591 len -= 2;
2594 else
2595 tests[i + 1].rtx = newval;
2598 /* If the last test in a COND has the same value
2599 as the default value, that test isn't needed. */
2601 while (len > 0 && attr_equal_p (tests[len - 1].rtx, new_defval))
2602 len -= 2;
2604 /* See if we changed anything. */
2605 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2606 allsame = 0;
2607 else
2608 for (i = 0; i < len; i++)
2609 if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i)))
2611 allsame = 0;
2612 break;
2615 if (len == 0)
2617 if (!ggc_p)
2618 obstack_free (rtl_obstack, first_spacer);
2619 if (GET_CODE (defval) == COND)
2620 return simplify_cond (defval, insn_code, insn_index);
2621 return defval;
2623 else if (allsame)
2625 if (!ggc_p)
2626 obstack_free (rtl_obstack, first_spacer);
2627 return exp;
2629 else
2631 rtx newexp = rtx_alloc (COND);
2633 XVEC (newexp, 0) = rtvec_alloc (len);
2634 bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem,
2635 len * sizeof (rtunion));
2636 XEXP (newexp, 1) = new_defval;
2637 return newexp;
2641 /* Remove an insn entry from an attribute value. */
2643 static void
2644 remove_insn_ent (av, ie)
2645 struct attr_value *av;
2646 struct insn_ent *ie;
2648 struct insn_ent *previe;
2650 if (av->first_insn == ie)
2651 av->first_insn = ie->next;
2652 else
2654 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2656 previe->next = ie->next;
2659 av->num_insns--;
2660 if (ie->insn_code == -1)
2661 av->has_asm_insn = 0;
2663 num_insn_ents--;
2666 /* Insert an insn entry in an attribute value list. */
2668 static void
2669 insert_insn_ent (av, ie)
2670 struct attr_value *av;
2671 struct insn_ent *ie;
2673 ie->next = av->first_insn;
2674 av->first_insn = ie;
2675 av->num_insns++;
2676 if (ie->insn_code == -1)
2677 av->has_asm_insn = 1;
2679 num_insn_ents++;
2682 /* This is a utility routine to take an expression that is a tree of either
2683 AND or IOR expressions and insert a new term. The new term will be
2684 inserted at the right side of the first node whose code does not match
2685 the root. A new node will be created with the root's code. Its left
2686 side will be the old right side and its right side will be the new
2687 term.
2689 If the `term' is itself a tree, all its leaves will be inserted. */
2691 static rtx
2692 insert_right_side (code, exp, term, insn_code, insn_index)
2693 enum rtx_code code;
2694 rtx exp;
2695 rtx term;
2696 int insn_code, insn_index;
2698 rtx newexp;
2700 /* Avoid consing in some special cases. */
2701 if (code == AND && term == true_rtx)
2702 return exp;
2703 if (code == AND && term == false_rtx)
2704 return false_rtx;
2705 if (code == AND && exp == true_rtx)
2706 return term;
2707 if (code == AND && exp == false_rtx)
2708 return false_rtx;
2709 if (code == IOR && term == true_rtx)
2710 return true_rtx;
2711 if (code == IOR && term == false_rtx)
2712 return exp;
2713 if (code == IOR && exp == true_rtx)
2714 return true_rtx;
2715 if (code == IOR && exp == false_rtx)
2716 return term;
2717 if (attr_equal_p (exp, term))
2718 return exp;
2720 if (GET_CODE (term) == code)
2722 exp = insert_right_side (code, exp, XEXP (term, 0),
2723 insn_code, insn_index);
2724 exp = insert_right_side (code, exp, XEXP (term, 1),
2725 insn_code, insn_index);
2727 return exp;
2730 if (GET_CODE (exp) == code)
2732 rtx new = insert_right_side (code, XEXP (exp, 1),
2733 term, insn_code, insn_index);
2734 if (new != XEXP (exp, 1))
2735 /* Make a copy of this expression and call recursively. */
2736 newexp = attr_rtx (code, XEXP (exp, 0), new);
2737 else
2738 newexp = exp;
2740 else
2742 /* Insert the new term. */
2743 newexp = attr_rtx (code, exp, term);
2746 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2749 /* If we have an expression which AND's a bunch of
2750 (not (eq_attrq "alternative" "n"))
2751 terms, we may have covered all or all but one of the possible alternatives.
2752 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2754 This routine is passed an expression and either AND or IOR. It returns a
2755 bitmask indicating which alternatives are mentioned within EXP. */
2757 static int
2758 compute_alternative_mask (exp, code)
2759 rtx exp;
2760 enum rtx_code code;
2762 char *string;
2763 if (GET_CODE (exp) == code)
2764 return compute_alternative_mask (XEXP (exp, 0), code)
2765 | compute_alternative_mask (XEXP (exp, 1), code);
2767 else if (code == AND && GET_CODE (exp) == NOT
2768 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2769 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2770 string = XSTR (XEXP (exp, 0), 1);
2772 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2773 && XSTR (exp, 0) == alternative_name)
2774 string = XSTR (exp, 1);
2776 else
2777 return 0;
2779 if (string[1] == 0)
2780 return 1 << (string[0] - '0');
2781 return 1 << atoi (string);
2784 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2785 attribute with the value represented by that bit. */
2787 static rtx
2788 make_alternative_compare (mask)
2789 int mask;
2791 rtx newexp;
2792 int i;
2794 /* Find the bit. */
2795 for (i = 0; (mask & (1 << i)) == 0; i++)
2798 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2799 RTX_UNCHANGING_P (newexp) = 1;
2801 return newexp;
2804 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2805 of "attr" for this insn code. From that value, we can compute a test
2806 showing when the EQ_ATTR will be true. This routine performs that
2807 computation. If a test condition involves an address, we leave the EQ_ATTR
2808 intact because addresses are only valid for the `length' attribute.
2810 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2811 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2813 static rtx
2814 evaluate_eq_attr (exp, value, insn_code, insn_index)
2815 rtx exp;
2816 rtx value;
2817 int insn_code, insn_index;
2819 rtx orexp, andexp;
2820 rtx right;
2821 rtx newexp;
2822 int i;
2824 if (GET_CODE (value) == CONST_STRING)
2826 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2827 newexp = true_rtx;
2828 else
2829 newexp = false_rtx;
2831 else if (GET_CODE (value) == SYMBOL_REF)
2833 char *p, *string;
2835 if (GET_CODE (exp) != EQ_ATTR)
2836 abort();
2838 string = (char *) alloca (2 + strlen (XSTR (exp, 0))
2839 + strlen (XSTR (exp, 1)));
2840 strcpy (string, XSTR (exp, 0));
2841 strcat (string, "_");
2842 strcat (string, XSTR (exp, 1));
2843 for (p = string; *p ; p++)
2844 if (ISLOWER(*p))
2845 *p = toupper (*p);
2847 newexp = attr_rtx (EQ, value,
2848 attr_rtx (SYMBOL_REF,
2849 attr_string(string, strlen(string))));
2851 else if (GET_CODE (value) == COND)
2853 /* We construct an IOR of all the cases for which the requested attribute
2854 value is present. Since we start with FALSE, if it is not present,
2855 FALSE will be returned.
2857 Each case is the AND of the NOT's of the previous conditions with the
2858 current condition; in the default case the current condition is TRUE.
2860 For each possible COND value, call ourselves recursively.
2862 The extra TRUE and FALSE expressions will be eliminated by another
2863 call to the simplification routine. */
2865 orexp = false_rtx;
2866 andexp = true_rtx;
2868 if (current_alternative_string)
2869 clear_struct_flag (value);
2871 for (i = 0; i < XVECLEN (value, 0); i += 2)
2873 rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
2874 insn_code, insn_index);
2876 SIMPLIFY_ALTERNATIVE (this);
2878 right = insert_right_side (AND, andexp, this,
2879 insn_code, insn_index);
2880 right = insert_right_side (AND, right,
2881 evaluate_eq_attr (exp,
2882 XVECEXP (value, 0,
2883 i + 1),
2884 insn_code, insn_index),
2885 insn_code, insn_index);
2886 orexp = insert_right_side (IOR, orexp, right,
2887 insn_code, insn_index);
2889 /* Add this condition into the AND expression. */
2890 newexp = attr_rtx (NOT, this);
2891 andexp = insert_right_side (AND, andexp, newexp,
2892 insn_code, insn_index);
2895 /* Handle the default case. */
2896 right = insert_right_side (AND, andexp,
2897 evaluate_eq_attr (exp, XEXP (value, 1),
2898 insn_code, insn_index),
2899 insn_code, insn_index);
2900 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2902 else
2903 abort ();
2905 /* If uses an address, must return original expression. But set the
2906 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2908 address_used = 0;
2909 walk_attr_value (newexp);
2911 if (address_used)
2913 /* This had `&& current_alternative_string', which seems to be wrong. */
2914 if (! RTX_UNCHANGING_P (exp))
2915 return copy_rtx_unchanging (exp);
2916 return exp;
2918 else
2919 return newexp;
2922 /* This routine is called when an AND of a term with a tree of AND's is
2923 encountered. If the term or its complement is present in the tree, it
2924 can be replaced with TRUE or FALSE, respectively.
2926 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2927 be true and hence are complementary.
2929 There is one special case: If we see
2930 (and (not (eq_attr "att" "v1"))
2931 (eq_attr "att" "v2"))
2932 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2933 replace the term, not anything in the AND tree. So we pass a pointer to
2934 the term. */
2936 static rtx
2937 simplify_and_tree (exp, pterm, insn_code, insn_index)
2938 rtx exp;
2939 rtx *pterm;
2940 int insn_code, insn_index;
2942 rtx left, right;
2943 rtx newexp;
2944 rtx temp;
2945 int left_eliminates_term, right_eliminates_term;
2947 if (GET_CODE (exp) == AND)
2949 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2950 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2951 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2953 newexp = attr_rtx (GET_CODE (exp), left, right);
2955 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2959 else if (GET_CODE (exp) == IOR)
2961 /* For the IOR case, we do the same as above, except that we can
2962 only eliminate `term' if both sides of the IOR would do so. */
2963 temp = *pterm;
2964 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2965 left_eliminates_term = (temp == true_rtx);
2967 temp = *pterm;
2968 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2969 right_eliminates_term = (temp == true_rtx);
2971 if (left_eliminates_term && right_eliminates_term)
2972 *pterm = true_rtx;
2974 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2976 newexp = attr_rtx (GET_CODE (exp), left, right);
2978 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2982 /* Check for simplifications. Do some extra checking here since this
2983 routine is called so many times. */
2985 if (exp == *pterm)
2986 return true_rtx;
2988 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2989 return false_rtx;
2991 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2992 return false_rtx;
2994 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2996 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2997 return exp;
2999 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
3000 return true_rtx;
3001 else
3002 return false_rtx;
3005 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3006 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3008 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3009 return exp;
3011 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3012 return false_rtx;
3013 else
3014 return true_rtx;
3017 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3018 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3020 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3021 return exp;
3023 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3024 return false_rtx;
3025 else
3026 *pterm = true_rtx;
3029 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3031 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
3032 return true_rtx;
3035 else if (GET_CODE (exp) == NOT)
3037 if (attr_equal_p (XEXP (exp, 0), *pterm))
3038 return false_rtx;
3041 else if (GET_CODE (*pterm) == NOT)
3043 if (attr_equal_p (XEXP (*pterm, 0), exp))
3044 return false_rtx;
3047 else if (attr_equal_p (exp, *pterm))
3048 return true_rtx;
3050 return exp;
3053 /* Similar to `simplify_and_tree', but for IOR trees. */
3055 static rtx
3056 simplify_or_tree (exp, pterm, insn_code, insn_index)
3057 rtx exp;
3058 rtx *pterm;
3059 int insn_code, insn_index;
3061 rtx left, right;
3062 rtx newexp;
3063 rtx temp;
3064 int left_eliminates_term, right_eliminates_term;
3066 if (GET_CODE (exp) == IOR)
3068 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
3069 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3070 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3072 newexp = attr_rtx (GET_CODE (exp), left, right);
3074 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3078 else if (GET_CODE (exp) == AND)
3080 /* For the AND case, we do the same as above, except that we can
3081 only eliminate `term' if both sides of the AND would do so. */
3082 temp = *pterm;
3083 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3084 left_eliminates_term = (temp == false_rtx);
3086 temp = *pterm;
3087 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3088 right_eliminates_term = (temp == false_rtx);
3090 if (left_eliminates_term && right_eliminates_term)
3091 *pterm = false_rtx;
3093 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3095 newexp = attr_rtx (GET_CODE (exp), left, right);
3097 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3101 if (attr_equal_p (exp, *pterm))
3102 return false_rtx;
3104 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
3105 return true_rtx;
3107 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
3108 return true_rtx;
3110 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3111 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3112 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3113 *pterm = false_rtx;
3115 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3116 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3117 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3118 return false_rtx;
3120 return exp;
3123 /* Given an expression, see if it can be simplified for a particular insn
3124 code based on the values of other attributes being tested. This can
3125 eliminate nested get_attr_... calls.
3127 Note that if an endless recursion is specified in the patterns, the
3128 optimization will loop. However, it will do so in precisely the cases where
3129 an infinite recursion loop could occur during compilation. It's better that
3130 it occurs here! */
3132 static rtx
3133 simplify_test_exp (exp, insn_code, insn_index)
3134 rtx exp;
3135 int insn_code, insn_index;
3137 rtx left, right;
3138 struct attr_desc *attr;
3139 struct attr_value *av;
3140 struct insn_ent *ie;
3141 int i;
3142 rtx newexp = exp;
3143 char *spacer = (char *) obstack_finish (rtl_obstack);
3145 /* Don't re-simplify something we already simplified. */
3146 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3147 return exp;
3149 switch (GET_CODE (exp))
3151 case AND:
3152 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3153 SIMPLIFY_ALTERNATIVE (left);
3154 if (left == false_rtx)
3156 if (!ggc_p)
3157 obstack_free (rtl_obstack, spacer);
3158 return false_rtx;
3160 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3161 SIMPLIFY_ALTERNATIVE (right);
3162 if (left == false_rtx)
3164 if (!ggc_p)
3165 obstack_free (rtl_obstack, spacer);
3166 return false_rtx;
3169 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3170 present on both sides, apply the distributive law since this will
3171 yield simplifications. */
3172 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3173 && compute_alternative_mask (left, IOR)
3174 && compute_alternative_mask (right, IOR))
3176 if (GET_CODE (left) == IOR)
3178 rtx tem = left;
3179 left = right;
3180 right = tem;
3183 newexp = attr_rtx (IOR,
3184 attr_rtx (AND, left, XEXP (right, 0)),
3185 attr_rtx (AND, left, XEXP (right, 1)));
3187 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3190 /* Try with the term on both sides. */
3191 right = simplify_and_tree (right, &left, insn_code, insn_index);
3192 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3193 left = simplify_and_tree (left, &right, insn_code, insn_index);
3195 if (left == false_rtx || right == false_rtx)
3197 if (!ggc_p)
3198 obstack_free (rtl_obstack, spacer);
3199 return false_rtx;
3201 else if (left == true_rtx)
3203 return right;
3205 else if (right == true_rtx)
3207 return left;
3209 /* See if all or all but one of the insn's alternatives are specified
3210 in this tree. Optimize if so. */
3212 else if (insn_code >= 0
3213 && (GET_CODE (left) == AND
3214 || (GET_CODE (left) == NOT
3215 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3216 && XSTR (XEXP (left, 0), 0) == alternative_name)
3217 || GET_CODE (right) == AND
3218 || (GET_CODE (right) == NOT
3219 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3220 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3222 i = compute_alternative_mask (exp, AND);
3223 if (i & ~insn_alternatives[insn_code])
3224 fatal ("Invalid alternative specified for pattern number %d",
3225 insn_index);
3227 /* If all alternatives are excluded, this is false. */
3228 i ^= insn_alternatives[insn_code];
3229 if (i == 0)
3230 return false_rtx;
3231 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3233 /* If just one excluded, AND a comparison with that one to the
3234 front of the tree. The others will be eliminated by
3235 optimization. We do not want to do this if the insn has one
3236 alternative and we have tested none of them! */
3237 left = make_alternative_compare (i);
3238 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3239 newexp = attr_rtx (AND, left, right);
3241 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3245 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3247 newexp = attr_rtx (AND, left, right);
3248 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3250 break;
3252 case IOR:
3253 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3254 SIMPLIFY_ALTERNATIVE (left);
3255 if (left == true_rtx)
3257 if (!ggc_p)
3258 obstack_free (rtl_obstack, spacer);
3259 return true_rtx;
3261 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3262 SIMPLIFY_ALTERNATIVE (right);
3263 if (right == true_rtx)
3265 if (!ggc_p)
3266 obstack_free (rtl_obstack, spacer);
3267 return true_rtx;
3270 right = simplify_or_tree (right, &left, insn_code, insn_index);
3271 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3272 left = simplify_or_tree (left, &right, insn_code, insn_index);
3274 if (right == true_rtx || left == true_rtx)
3276 if (!ggc_p)
3277 obstack_free (rtl_obstack, spacer);
3278 return true_rtx;
3280 else if (left == false_rtx)
3282 return right;
3284 else if (right == false_rtx)
3286 return left;
3289 /* Test for simple cases where the distributive law is useful. I.e.,
3290 convert (ior (and (x) (y))
3291 (and (x) (z)))
3292 to (and (x)
3293 (ior (y) (z)))
3296 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3297 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3299 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3301 left = XEXP (left, 0);
3302 right = newexp;
3303 newexp = attr_rtx (AND, left, right);
3304 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3307 /* See if all or all but one of the insn's alternatives are specified
3308 in this tree. Optimize if so. */
3310 else if (insn_code >= 0
3311 && (GET_CODE (left) == IOR
3312 || (GET_CODE (left) == EQ_ATTR
3313 && XSTR (left, 0) == alternative_name)
3314 || GET_CODE (right) == IOR
3315 || (GET_CODE (right) == EQ_ATTR
3316 && XSTR (right, 0) == alternative_name)))
3318 i = compute_alternative_mask (exp, IOR);
3319 if (i & ~insn_alternatives[insn_code])
3320 fatal ("Invalid alternative specified for pattern number %d",
3321 insn_index);
3323 /* If all alternatives are included, this is true. */
3324 i ^= insn_alternatives[insn_code];
3325 if (i == 0)
3326 return true_rtx;
3327 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3329 /* If just one excluded, IOR a comparison with that one to the
3330 front of the tree. The others will be eliminated by
3331 optimization. We do not want to do this if the insn has one
3332 alternative and we have tested none of them! */
3333 left = make_alternative_compare (i);
3334 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3335 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3337 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3341 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3343 newexp = attr_rtx (IOR, left, right);
3344 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3346 break;
3348 case NOT:
3349 if (GET_CODE (XEXP (exp, 0)) == NOT)
3351 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3352 insn_code, insn_index);
3353 SIMPLIFY_ALTERNATIVE (left);
3354 return left;
3357 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3358 SIMPLIFY_ALTERNATIVE (left);
3359 if (GET_CODE (left) == NOT)
3360 return XEXP (left, 0);
3362 if (left == false_rtx)
3364 if (!ggc_p)
3365 obstack_free (rtl_obstack, spacer);
3366 return true_rtx;
3368 else if (left == true_rtx)
3370 if (!ggc_p)
3371 obstack_free (rtl_obstack, spacer);
3372 return false_rtx;
3375 /* Try to apply De`Morgan's laws. */
3376 else if (GET_CODE (left) == IOR)
3378 newexp = attr_rtx (AND,
3379 attr_rtx (NOT, XEXP (left, 0)),
3380 attr_rtx (NOT, XEXP (left, 1)));
3382 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3384 else if (GET_CODE (left) == AND)
3386 newexp = attr_rtx (IOR,
3387 attr_rtx (NOT, XEXP (left, 0)),
3388 attr_rtx (NOT, XEXP (left, 1)));
3390 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3392 else if (left != XEXP (exp, 0))
3394 newexp = attr_rtx (NOT, left);
3396 break;
3398 case EQ_ATTR:
3399 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3400 return (XSTR (exp, 1) == current_alternative_string
3401 ? true_rtx : false_rtx);
3403 /* Look at the value for this insn code in the specified attribute.
3404 We normally can replace this comparison with the condition that
3405 would give this insn the values being tested for. */
3406 if (XSTR (exp, 0) != alternative_name
3407 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3408 for (av = attr->first_value; av; av = av->next)
3409 for (ie = av->first_insn; ie; ie = ie->next)
3410 if (ie->insn_code == insn_code)
3411 return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3412 break;
3414 default:
3415 break;
3418 /* We have already simplified this expression. Simplifying it again
3419 won't buy anything unless we weren't given a valid insn code
3420 to process (i.e., we are canonicalizing something.). */
3421 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3422 && ! RTX_UNCHANGING_P (newexp))
3423 return copy_rtx_unchanging (newexp);
3425 return newexp;
3428 /* Optimize the attribute lists by seeing if we can determine conditional
3429 values from the known values of other attributes. This will save subroutine
3430 calls during the compilation. */
3432 static void
3433 optimize_attrs ()
3435 struct attr_desc *attr;
3436 struct attr_value *av;
3437 struct insn_ent *ie;
3438 rtx newexp;
3439 int something_changed = 1;
3440 int i;
3441 struct attr_value_list { struct attr_value *av;
3442 struct insn_ent *ie;
3443 struct attr_desc * attr;
3444 struct attr_value_list *next; };
3445 struct attr_value_list **insn_code_values;
3446 struct attr_value_list *ivbuf;
3447 struct attr_value_list *iv;
3449 /* For each insn code, make a list of all the insn_ent's for it,
3450 for all values for all attributes. */
3452 if (num_insn_ents == 0)
3453 return;
3455 /* Make 2 extra elements, for "code" values -2 and -1. */
3456 insn_code_values
3457 = (struct attr_value_list **) alloca ((insn_code_number + 2)
3458 * sizeof (struct attr_value_list *));
3459 bzero ((char *) insn_code_values,
3460 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3462 /* Offset the table address so we can index by -2 or -1. */
3463 insn_code_values += 2;
3465 /* Allocate the attr_value_list structures using xmalloc rather than
3466 alloca, because using alloca can overflow the maximum permitted
3467 stack limit on SPARC Lynx. */
3468 iv = ivbuf = ((struct attr_value_list *)
3469 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3471 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3472 for (attr = attrs[i]; attr; attr = attr->next)
3473 for (av = attr->first_value; av; av = av->next)
3474 for (ie = av->first_insn; ie; ie = ie->next)
3476 iv->attr = attr;
3477 iv->av = av;
3478 iv->ie = ie;
3479 iv->next = insn_code_values[ie->insn_code];
3480 insn_code_values[ie->insn_code] = iv;
3481 iv++;
3484 /* Sanity check on num_insn_ents. */
3485 if (iv != ivbuf + num_insn_ents)
3486 abort ();
3488 /* Process one insn code at a time. */
3489 for (i = -2; i < insn_code_number; i++)
3491 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3492 We use it to mean "already simplified for this insn". */
3493 for (iv = insn_code_values[i]; iv; iv = iv->next)
3494 clear_struct_flag (iv->av->value);
3496 /* Loop until nothing changes for one iteration. */
3497 something_changed = 1;
3498 while (something_changed)
3500 something_changed = 0;
3501 for (iv = insn_code_values[i]; iv; iv = iv->next)
3503 struct obstack *old = rtl_obstack;
3504 char *spacer = (char *) obstack_finish (temp_obstack);
3506 attr = iv->attr;
3507 av = iv->av;
3508 ie = iv->ie;
3509 if (GET_CODE (av->value) != COND)
3510 continue;
3512 rtl_obstack = temp_obstack;
3513 #if 0 /* This was intended as a speed up, but it was slower. */
3514 if (insn_n_alternatives[ie->insn_code] > 6
3515 && count_sub_rtxs (av->value, 200) >= 200)
3516 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3517 ie->insn_index);
3518 else
3519 #endif
3520 newexp = simplify_cond (av->value, ie->insn_code,
3521 ie->insn_index);
3523 rtl_obstack = old;
3524 if (newexp != av->value)
3526 newexp = attr_copy_rtx (newexp);
3527 remove_insn_ent (av, ie);
3528 av = get_attr_value (newexp, attr, ie->insn_code);
3529 iv->av = av;
3530 insert_insn_ent (av, ie);
3531 something_changed = 1;
3533 if (!ggc_p)
3534 obstack_free (temp_obstack, spacer);
3539 free (ivbuf);
3542 #if 0
3543 static rtx
3544 simplify_by_alternatives (exp, insn_code, insn_index)
3545 rtx exp;
3546 int insn_code, insn_index;
3548 int i;
3549 int len = insn_n_alternatives[insn_code];
3550 rtx newexp = rtx_alloc (COND);
3551 rtx ultimate;
3554 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3556 /* It will not matter what value we use as the default value
3557 of the new COND, since that default will never be used.
3558 Choose something of the right type. */
3559 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3560 ultimate = XEXP (ultimate, 1);
3561 XEXP (newexp, 1) = ultimate;
3563 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3565 current_alternative_string = attr_numeral (i);
3566 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3567 XVECEXP (newexp, 0, i * 2 + 1)
3568 = simplify_cond (exp, insn_code, insn_index);
3571 current_alternative_string = 0;
3572 return simplify_cond (newexp, insn_code, insn_index);
3574 #endif
3576 /* If EXP is a suitable expression, reorganize it by constructing an
3577 equivalent expression that is a COND with the tests being all combinations
3578 of attribute values and the values being simple constants. */
3580 static rtx
3581 simplify_by_exploding (exp)
3582 rtx exp;
3584 rtx list = 0, link, condexp, defval = NULL_RTX;
3585 struct dimension *space;
3586 rtx *condtest, *condval;
3587 int i, j, total, ndim = 0;
3588 int most_tests, num_marks, new_marks;
3590 /* Locate all the EQ_ATTR expressions. */
3591 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3593 unmark_used_attributes (list, 0, 0);
3594 return exp;
3597 /* Create an attribute space from the list of used attributes. For each
3598 dimension in the attribute space, record the attribute, list of values
3599 used, and number of values used. Add members to the list of values to
3600 cover the domain of the attribute. This makes the expanded COND form
3601 order independent. */
3603 space = (struct dimension *) alloca (ndim * sizeof (struct dimension));
3605 total = 1;
3606 for (ndim = 0; list; ndim++)
3608 /* Pull the first attribute value from the list and record that
3609 attribute as another dimension in the attribute space. */
3610 char *name = XSTR (XEXP (list, 0), 0);
3611 rtx *prev;
3613 if ((space[ndim].attr = find_attr (name, 0)) == 0
3614 || space[ndim].attr->is_numeric)
3616 unmark_used_attributes (list, space, ndim);
3617 return exp;
3620 /* Add all remaining attribute values that refer to this attribute. */
3621 space[ndim].num_values = 0;
3622 space[ndim].values = 0;
3623 prev = &list;
3624 for (link = list; link; link = *prev)
3625 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3627 space[ndim].num_values++;
3628 *prev = XEXP (link, 1);
3629 XEXP (link, 1) = space[ndim].values;
3630 space[ndim].values = link;
3632 else
3633 prev = &XEXP (link, 1);
3635 /* Add sufficient members to the list of values to make the list
3636 mutually exclusive and record the total size of the attribute
3637 space. */
3638 total *= add_values_to_cover (&space[ndim]);
3641 /* Sort the attribute space so that the attributes go from non-constant
3642 to constant and from most values to least values. */
3643 for (i = 0; i < ndim; i++)
3644 for (j = ndim - 1; j > i; j--)
3645 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3646 || space[j-1].num_values < space[j].num_values)
3648 struct dimension tmp;
3649 tmp = space[j];
3650 space[j] = space[j-1];
3651 space[j-1] = tmp;
3654 /* Establish the initial current value. */
3655 for (i = 0; i < ndim; i++)
3656 space[i].current_value = space[i].values;
3658 condtest = (rtx *) alloca (total * sizeof (rtx));
3659 condval = (rtx *) alloca (total * sizeof (rtx));
3661 /* Expand the tests and values by iterating over all values in the
3662 attribute space. */
3663 for (i = 0;; i++)
3665 condtest[i] = test_for_current_value (space, ndim);
3666 condval[i] = simplify_with_current_value (exp, space, ndim);
3667 if (! increment_current_value (space, ndim))
3668 break;
3670 if (i != total - 1)
3671 abort ();
3673 /* We are now finished with the original expression. */
3674 unmark_used_attributes (0, space, ndim);
3676 /* Find the most used constant value and make that the default. */
3677 most_tests = -1;
3678 for (i = num_marks = 0; i < total; i++)
3679 if (GET_CODE (condval[i]) == CONST_STRING
3680 && ! MEM_VOLATILE_P (condval[i]))
3682 /* Mark the unmarked constant value and count how many are marked. */
3683 MEM_VOLATILE_P (condval[i]) = 1;
3684 for (j = new_marks = 0; j < total; j++)
3685 if (GET_CODE (condval[j]) == CONST_STRING
3686 && MEM_VOLATILE_P (condval[j]))
3687 new_marks++;
3688 if (new_marks - num_marks > most_tests)
3690 most_tests = new_marks - num_marks;
3691 defval = condval[i];
3693 num_marks = new_marks;
3695 /* Clear all the marks. */
3696 for (i = 0; i < total; i++)
3697 MEM_VOLATILE_P (condval[i]) = 0;
3699 /* Give up if nothing is constant. */
3700 if (num_marks == 0)
3701 return exp;
3703 /* If all values are the default, use that. */
3704 if (total == most_tests)
3705 return defval;
3707 /* Make a COND with the most common constant value the default. (A more
3708 complex method where tests with the same value were combined didn't
3709 seem to improve things.) */
3710 condexp = rtx_alloc (COND);
3711 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3712 XEXP (condexp, 1) = defval;
3713 for (i = j = 0; i < total; i++)
3714 if (condval[i] != defval)
3716 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3717 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3718 j++;
3721 return condexp;
3724 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3725 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3726 tests have known value. */
3728 static int
3729 find_and_mark_used_attributes (exp, terms, nterms)
3730 rtx exp, *terms;
3731 int *nterms;
3733 int i;
3735 switch (GET_CODE (exp))
3737 case EQ_ATTR:
3738 if (! MEM_VOLATILE_P (exp))
3740 rtx link = rtx_alloc (EXPR_LIST);
3741 XEXP (link, 0) = exp;
3742 XEXP (link, 1) = *terms;
3743 *terms = link;
3744 *nterms += 1;
3745 MEM_VOLATILE_P (exp) = 1;
3747 return 1;
3749 case CONST_STRING:
3750 case CONST_INT:
3751 return 1;
3753 case IF_THEN_ELSE:
3754 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3755 return 0;
3756 case IOR:
3757 case AND:
3758 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3759 return 0;
3760 case NOT:
3761 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3762 return 0;
3763 return 1;
3765 case COND:
3766 for (i = 0; i < XVECLEN (exp, 0); i++)
3767 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3768 return 0;
3769 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3770 return 0;
3771 return 1;
3773 default:
3774 return 0;
3778 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3779 in the values of the NDIM-dimensional attribute space SPACE. */
3781 static void
3782 unmark_used_attributes (list, space, ndim)
3783 rtx list;
3784 struct dimension *space;
3785 int ndim;
3787 rtx link, exp;
3788 int i;
3790 for (i = 0; i < ndim; i++)
3791 unmark_used_attributes (space[i].values, 0, 0);
3793 for (link = list; link; link = XEXP (link, 1))
3795 exp = XEXP (link, 0);
3796 if (GET_CODE (exp) == EQ_ATTR)
3797 MEM_VOLATILE_P (exp) = 0;
3801 /* Update the attribute dimension DIM so that all values of the attribute
3802 are tested. Return the updated number of values. */
3804 static int
3805 add_values_to_cover (dim)
3806 struct dimension *dim;
3808 struct attr_value *av;
3809 rtx exp, link, *prev;
3810 int nalt = 0;
3812 for (av = dim->attr->first_value; av; av = av->next)
3813 if (GET_CODE (av->value) == CONST_STRING)
3814 nalt++;
3816 if (nalt < dim->num_values)
3817 abort ();
3818 else if (nalt == dim->num_values)
3819 ; /* Ok. */
3820 else if (nalt * 2 < dim->num_values * 3)
3822 /* Most all the values of the attribute are used, so add all the unused
3823 values. */
3824 prev = &dim->values;
3825 for (link = dim->values; link; link = *prev)
3826 prev = &XEXP (link, 1);
3828 for (av = dim->attr->first_value; av; av = av->next)
3829 if (GET_CODE (av->value) == CONST_STRING)
3831 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3832 if (MEM_VOLATILE_P (exp))
3833 continue;
3835 link = rtx_alloc (EXPR_LIST);
3836 XEXP (link, 0) = exp;
3837 XEXP (link, 1) = 0;
3838 *prev = link;
3839 prev = &XEXP (link, 1);
3841 dim->num_values = nalt;
3843 else
3845 rtx orexp = false_rtx;
3847 /* Very few values are used, so compute a mutually exclusive
3848 expression. (We could do this for numeric values if that becomes
3849 important.) */
3850 prev = &dim->values;
3851 for (link = dim->values; link; link = *prev)
3853 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3854 prev = &XEXP (link, 1);
3856 link = rtx_alloc (EXPR_LIST);
3857 XEXP (link, 0) = attr_rtx (NOT, orexp);
3858 XEXP (link, 1) = 0;
3859 *prev = link;
3860 dim->num_values++;
3862 return dim->num_values;
3865 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3866 and return FALSE if the increment overflowed. */
3868 static int
3869 increment_current_value (space, ndim)
3870 struct dimension *space;
3871 int ndim;
3873 int i;
3875 for (i = ndim - 1; i >= 0; i--)
3877 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3878 space[i].current_value = space[i].values;
3879 else
3880 return 1;
3882 return 0;
3885 /* Construct an expression corresponding to the current value for the
3886 NDIM-dimensional attribute space SPACE. */
3888 static rtx
3889 test_for_current_value (space, ndim)
3890 struct dimension *space;
3891 int ndim;
3893 int i;
3894 rtx exp = true_rtx;
3896 for (i = 0; i < ndim; i++)
3897 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3898 -2, -2);
3900 return exp;
3903 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3904 set the corresponding EQ_ATTR expressions to that value and reduce
3905 the expression EXP as much as possible. On input [and output], all
3906 known EQ_ATTR expressions are set to FALSE. */
3908 static rtx
3909 simplify_with_current_value (exp, space, ndim)
3910 rtx exp;
3911 struct dimension *space;
3912 int ndim;
3914 int i;
3915 rtx x;
3917 /* Mark each current value as TRUE. */
3918 for (i = 0; i < ndim; i++)
3920 x = XEXP (space[i].current_value, 0);
3921 if (GET_CODE (x) == EQ_ATTR)
3922 MEM_VOLATILE_P (x) = 0;
3925 exp = simplify_with_current_value_aux (exp);
3927 /* Change each current value back to FALSE. */
3928 for (i = 0; i < ndim; i++)
3930 x = XEXP (space[i].current_value, 0);
3931 if (GET_CODE (x) == EQ_ATTR)
3932 MEM_VOLATILE_P (x) = 1;
3935 return exp;
3938 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
3939 all EQ_ATTR expressions. */
3941 static rtx
3942 simplify_with_current_value_aux (exp)
3943 rtx exp;
3945 register int i;
3946 rtx cond;
3948 switch (GET_CODE (exp))
3950 case EQ_ATTR:
3951 if (MEM_VOLATILE_P (exp))
3952 return false_rtx;
3953 else
3954 return true_rtx;
3955 case CONST_STRING:
3956 case CONST_INT:
3957 return exp;
3959 case IF_THEN_ELSE:
3960 cond = simplify_with_current_value_aux (XEXP (exp, 0));
3961 if (cond == true_rtx)
3962 return simplify_with_current_value_aux (XEXP (exp, 1));
3963 else if (cond == false_rtx)
3964 return simplify_with_current_value_aux (XEXP (exp, 2));
3965 else
3966 return attr_rtx (IF_THEN_ELSE, cond,
3967 simplify_with_current_value_aux (XEXP (exp, 1)),
3968 simplify_with_current_value_aux (XEXP (exp, 2)));
3970 case IOR:
3971 cond = simplify_with_current_value_aux (XEXP (exp, 1));
3972 if (cond == true_rtx)
3973 return cond;
3974 else if (cond == false_rtx)
3975 return simplify_with_current_value_aux (XEXP (exp, 0));
3976 else
3977 return attr_rtx (IOR, cond,
3978 simplify_with_current_value_aux (XEXP (exp, 0)));
3980 case AND:
3981 cond = simplify_with_current_value_aux (XEXP (exp, 1));
3982 if (cond == true_rtx)
3983 return simplify_with_current_value_aux (XEXP (exp, 0));
3984 else if (cond == false_rtx)
3985 return cond;
3986 else
3987 return attr_rtx (AND, cond,
3988 simplify_with_current_value_aux (XEXP (exp, 0)));
3990 case NOT:
3991 cond = simplify_with_current_value_aux (XEXP (exp, 0));
3992 if (cond == true_rtx)
3993 return false_rtx;
3994 else if (cond == false_rtx)
3995 return true_rtx;
3996 else
3997 return attr_rtx (NOT, cond);
3999 case COND:
4000 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4002 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
4003 if (cond == true_rtx)
4004 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4005 else if (cond == false_rtx)
4006 continue;
4007 else
4008 abort (); /* With all EQ_ATTR's of known value, a case should
4009 have been selected. */
4011 return simplify_with_current_value_aux (XEXP (exp, 1));
4013 default:
4014 abort ();
4018 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4020 static void
4021 clear_struct_flag (x)
4022 rtx x;
4024 register int i;
4025 register int j;
4026 register enum rtx_code code;
4027 register const char *fmt;
4029 MEM_IN_STRUCT_P (x) = 0;
4030 if (RTX_UNCHANGING_P (x))
4031 return;
4033 code = GET_CODE (x);
4035 switch (code)
4037 case REG:
4038 case QUEUED:
4039 case CONST_INT:
4040 case CONST_DOUBLE:
4041 case SYMBOL_REF:
4042 case CODE_LABEL:
4043 case PC:
4044 case CC0:
4045 case EQ_ATTR:
4046 case ATTR_FLAG:
4047 return;
4049 default:
4050 break;
4053 /* Compare the elements. If any pair of corresponding elements
4054 fail to match, return 0 for the whole things. */
4056 fmt = GET_RTX_FORMAT (code);
4057 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4059 switch (fmt[i])
4061 case 'V':
4062 case 'E':
4063 for (j = 0; j < XVECLEN (x, i); j++)
4064 clear_struct_flag (XVECEXP (x, i, j));
4065 break;
4067 case 'e':
4068 clear_struct_flag (XEXP (x, i));
4069 break;
4074 /* Return the number of RTX objects making up the expression X.
4075 But if we count more than MAX objects, stop counting. */
4077 static int
4078 count_sub_rtxs (x, max)
4079 rtx x;
4080 int max;
4082 register int i;
4083 register int j;
4084 register enum rtx_code code;
4085 register const char *fmt;
4086 int total = 0;
4088 code = GET_CODE (x);
4090 switch (code)
4092 case REG:
4093 case QUEUED:
4094 case CONST_INT:
4095 case CONST_DOUBLE:
4096 case SYMBOL_REF:
4097 case CODE_LABEL:
4098 case PC:
4099 case CC0:
4100 case EQ_ATTR:
4101 case ATTR_FLAG:
4102 return 1;
4104 default:
4105 break;
4108 /* Compare the elements. If any pair of corresponding elements
4109 fail to match, return 0 for the whole things. */
4111 fmt = GET_RTX_FORMAT (code);
4112 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4114 if (total >= max)
4115 return total;
4117 switch (fmt[i])
4119 case 'V':
4120 case 'E':
4121 for (j = 0; j < XVECLEN (x, i); j++)
4122 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4123 break;
4125 case 'e':
4126 total += count_sub_rtxs (XEXP (x, i), max);
4127 break;
4130 return total;
4134 /* Create table entries for DEFINE_ATTR. */
4136 static void
4137 gen_attr (exp)
4138 rtx exp;
4140 struct attr_desc *attr;
4141 struct attr_value *av;
4142 char *name_ptr;
4143 char *p;
4145 /* Make a new attribute structure. Check for duplicate by looking at
4146 attr->default_val, since it is initialized by this routine. */
4147 attr = find_attr (XSTR (exp, 0), 1);
4148 if (attr->default_val)
4149 fatal ("Duplicate definition for `%s' attribute", attr->name);
4151 if (*XSTR (exp, 1) == '\0')
4152 attr->is_numeric = 1;
4153 else
4155 name_ptr = XSTR (exp, 1);
4156 while ((p = next_comma_elt (&name_ptr)) != NULL)
4158 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4159 av->value = attr_rtx (CONST_STRING, p);
4160 av->next = attr->first_value;
4161 attr->first_value = av;
4162 av->first_insn = NULL;
4163 av->num_insns = 0;
4164 av->has_asm_insn = 0;
4168 if (GET_CODE (XEXP (exp, 2)) == CONST)
4170 attr->is_const = 1;
4171 if (attr->is_numeric)
4172 fatal ("Constant attributes may not take numeric values");
4173 /* Get rid of the CONST node. It is allowed only at top-level. */
4174 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4177 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4178 fatal ("`length' attribute must take numeric values");
4180 /* Set up the default value. */
4181 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4182 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4185 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4186 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4187 number of alternatives as this should be checked elsewhere. */
4189 static int
4190 count_alternatives (exp)
4191 rtx exp;
4193 int i, j, n;
4194 const char *fmt;
4196 if (GET_CODE (exp) == MATCH_OPERAND)
4197 return n_comma_elts (XSTR (exp, 2));
4199 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4200 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4201 switch (*fmt++)
4203 case 'e':
4204 case 'u':
4205 n = count_alternatives (XEXP (exp, i));
4206 if (n)
4207 return n;
4208 break;
4210 case 'E':
4211 case 'V':
4212 if (XVEC (exp, i) != NULL)
4213 for (j = 0; j < XVECLEN (exp, i); j++)
4215 n = count_alternatives (XVECEXP (exp, i, j));
4216 if (n)
4217 return n;
4221 return 0;
4224 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4225 `alternative' attribute. */
4227 static int
4228 compares_alternatives_p (exp)
4229 rtx exp;
4231 int i, j;
4232 const char *fmt;
4234 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4235 return 1;
4237 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4238 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4239 switch (*fmt++)
4241 case 'e':
4242 case 'u':
4243 if (compares_alternatives_p (XEXP (exp, i)))
4244 return 1;
4245 break;
4247 case 'E':
4248 for (j = 0; j < XVECLEN (exp, i); j++)
4249 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4250 return 1;
4251 break;
4254 return 0;
4257 /* Returns non-zero is INNER is contained in EXP. */
4259 static int
4260 contained_in_p (inner, exp)
4261 rtx inner;
4262 rtx exp;
4264 int i, j;
4265 const char *fmt;
4267 if (rtx_equal_p (inner, exp))
4268 return 1;
4270 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4271 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4272 switch (*fmt++)
4274 case 'e':
4275 case 'u':
4276 if (contained_in_p (inner, XEXP (exp, i)))
4277 return 1;
4278 break;
4280 case 'E':
4281 for (j = 0; j < XVECLEN (exp, i); j++)
4282 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4283 return 1;
4284 break;
4287 return 0;
4290 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4292 static void
4293 gen_insn (exp)
4294 rtx exp;
4296 struct insn_def *id;
4298 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4299 id->next = defs;
4300 defs = id;
4301 id->def = exp;
4303 switch (GET_CODE (exp))
4305 case DEFINE_INSN:
4306 id->insn_code = insn_code_number++;
4307 id->insn_index = insn_index_number++;
4308 id->num_alternatives = count_alternatives (exp);
4309 if (id->num_alternatives == 0)
4310 id->num_alternatives = 1;
4311 id->vec_idx = 4;
4312 break;
4314 case DEFINE_PEEPHOLE:
4315 id->insn_code = insn_code_number++;
4316 id->insn_index = insn_index_number++;
4317 id->num_alternatives = count_alternatives (exp);
4318 if (id->num_alternatives == 0)
4319 id->num_alternatives = 1;
4320 id->vec_idx = 3;
4321 break;
4323 case DEFINE_ASM_ATTRIBUTES:
4324 id->insn_code = -1;
4325 id->insn_index = -1;
4326 id->num_alternatives = 1;
4327 id->vec_idx = 0;
4328 got_define_asm_attributes = 1;
4329 break;
4331 default:
4332 abort ();
4336 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4337 true or annul false is specified, and make a `struct delay_desc'. */
4339 static void
4340 gen_delay (def)
4341 rtx def;
4343 struct delay_desc *delay;
4344 int i;
4346 if (XVECLEN (def, 1) % 3 != 0)
4347 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
4349 for (i = 0; i < XVECLEN (def, 1); i += 3)
4351 if (XVECEXP (def, 1, i + 1))
4352 have_annul_true = 1;
4353 if (XVECEXP (def, 1, i + 2))
4354 have_annul_false = 1;
4357 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4358 delay->def = def;
4359 delay->num = ++num_delays;
4360 delay->next = delays;
4361 delays = delay;
4364 /* Process a DEFINE_FUNCTION_UNIT.
4366 This gives information about a function unit contained in the CPU.
4367 We fill in a `struct function_unit_op' and a `struct function_unit'
4368 with information used later by `expand_unit'. */
4370 static void
4371 gen_unit (def)
4372 rtx def;
4374 struct function_unit *unit;
4375 struct function_unit_op *op;
4376 char *name = XSTR (def, 0);
4377 int multiplicity = XINT (def, 1);
4378 int simultaneity = XINT (def, 2);
4379 rtx condexp = XEXP (def, 3);
4380 int ready_cost = MAX (XINT (def, 4), 1);
4381 int issue_delay = MAX (XINT (def, 5), 1);
4383 /* See if we have already seen this function unit. If so, check that
4384 the multiplicity and simultaneity values are the same. If not, make
4385 a structure for this function unit. */
4386 for (unit = units; unit; unit = unit->next)
4387 if (! strcmp (unit->name, name))
4389 if (unit->multiplicity != multiplicity
4390 || unit->simultaneity != simultaneity)
4391 fatal ("Differing specifications given for `%s' function unit.",
4392 unit->name);
4393 break;
4396 if (unit == 0)
4398 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4399 unit->name = name;
4400 unit->multiplicity = multiplicity;
4401 unit->simultaneity = simultaneity;
4402 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4403 unit->num = num_units++;
4404 unit->num_opclasses = 0;
4405 unit->condexp = false_rtx;
4406 unit->ops = 0;
4407 unit->next = units;
4408 units = unit;
4411 /* Make a new operation class structure entry and initialize it. */
4412 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4413 op->condexp = condexp;
4414 op->num = unit->num_opclasses++;
4415 op->ready = ready_cost;
4416 op->issue_delay = issue_delay;
4417 op->next = unit->ops;
4418 unit->ops = op;
4419 num_unit_opclasses++;
4421 /* Set our issue expression based on whether or not an optional conflict
4422 vector was specified. */
4423 if (XVEC (def, 6))
4425 /* Compute the IOR of all the specified expressions. */
4426 rtx orexp = false_rtx;
4427 int i;
4429 for (i = 0; i < XVECLEN (def, 6); i++)
4430 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4432 op->conflict_exp = orexp;
4433 extend_range (&unit->issue_delay, 1, issue_delay);
4435 else
4437 op->conflict_exp = true_rtx;
4438 extend_range (&unit->issue_delay, issue_delay, issue_delay);
4441 /* Merge our conditional into that of the function unit so we can determine
4442 which insns are used by the function unit. */
4443 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4446 /* Given a piece of RTX, print a C expression to test its truth value.
4447 We use AND and IOR both for logical and bit-wise operations, so
4448 interpret them as logical unless they are inside a comparison expression.
4449 The first bit of FLAGS will be non-zero in that case.
4451 Set the second bit of FLAGS to make references to attribute values use
4452 a cached local variable instead of calling a function. */
4454 static void
4455 write_test_expr (exp, flags)
4456 rtx exp;
4457 int flags;
4459 int comparison_operator = 0;
4460 RTX_CODE code;
4461 struct attr_desc *attr;
4463 /* In order not to worry about operator precedence, surround our part of
4464 the expression with parentheses. */
4466 printf ("(");
4467 code = GET_CODE (exp);
4468 switch (code)
4470 /* Binary operators. */
4471 case EQ: case NE:
4472 case GE: case GT: case GEU: case GTU:
4473 case LE: case LT: case LEU: case LTU:
4474 comparison_operator = 1;
4476 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4477 case AND: case IOR: case XOR:
4478 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4479 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
4480 switch (code)
4482 case EQ:
4483 printf (" == ");
4484 break;
4485 case NE:
4486 printf (" != ");
4487 break;
4488 case GE:
4489 printf (" >= ");
4490 break;
4491 case GT:
4492 printf (" > ");
4493 break;
4494 case GEU:
4495 printf (" >= (unsigned) ");
4496 break;
4497 case GTU:
4498 printf (" > (unsigned) ");
4499 break;
4500 case LE:
4501 printf (" <= ");
4502 break;
4503 case LT:
4504 printf (" < ");
4505 break;
4506 case LEU:
4507 printf (" <= (unsigned) ");
4508 break;
4509 case LTU:
4510 printf (" < (unsigned) ");
4511 break;
4512 case PLUS:
4513 printf (" + ");
4514 break;
4515 case MINUS:
4516 printf (" - ");
4517 break;
4518 case MULT:
4519 printf (" * ");
4520 break;
4521 case DIV:
4522 printf (" / ");
4523 break;
4524 case MOD:
4525 printf (" %% ");
4526 break;
4527 case AND:
4528 if (flags & 1)
4529 printf (" & ");
4530 else
4531 printf (" && ");
4532 break;
4533 case IOR:
4534 if (flags & 1)
4535 printf (" | ");
4536 else
4537 printf (" || ");
4538 break;
4539 case XOR:
4540 printf (" ^ ");
4541 break;
4542 case ASHIFT:
4543 printf (" << ");
4544 break;
4545 case LSHIFTRT:
4546 case ASHIFTRT:
4547 printf (" >> ");
4548 break;
4549 default:
4550 abort ();
4553 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
4554 break;
4556 case NOT:
4557 /* Special-case (not (eq_attrq "alternative" "x")) */
4558 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4559 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4561 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4562 break;
4565 /* Otherwise, fall through to normal unary operator. */
4567 /* Unary operators. */
4568 case ABS: case NEG:
4569 switch (code)
4571 case NOT:
4572 if (flags & 1)
4573 printf ("~ ");
4574 else
4575 printf ("! ");
4576 break;
4577 case ABS:
4578 printf ("abs ");
4579 break;
4580 case NEG:
4581 printf ("-");
4582 break;
4583 default:
4584 abort ();
4587 write_test_expr (XEXP (exp, 0), flags);
4588 break;
4590 /* Comparison test of an attribute with a value. Most of these will
4591 have been removed by optimization. Handle "alternative"
4592 specially and give error if EQ_ATTR present inside a comparison. */
4593 case EQ_ATTR:
4594 if (flags & 1)
4595 fatal ("EQ_ATTR not valid inside comparison");
4597 if (XSTR (exp, 0) == alternative_name)
4599 printf ("which_alternative == %s", XSTR (exp, 1));
4600 break;
4603 attr = find_attr (XSTR (exp, 0), 0);
4604 if (! attr) abort ();
4606 /* Now is the time to expand the value of a constant attribute. */
4607 if (attr->is_const)
4609 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4610 -2, -2),
4611 flags);
4613 else
4615 if (flags & 2)
4616 printf ("attr_%s", attr->name);
4617 else
4618 printf ("get_attr_%s (insn)", attr->name);
4619 printf (" == ");
4620 write_attr_valueq (attr, XSTR (exp, 1));
4622 break;
4624 /* Comparison test of flags for define_delays. */
4625 case ATTR_FLAG:
4626 if (flags & 1)
4627 fatal ("ATTR_FLAG not valid inside comparison");
4628 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4629 break;
4631 /* See if an operand matches a predicate. */
4632 case MATCH_OPERAND:
4633 /* If only a mode is given, just ensure the mode matches the operand.
4634 If neither a mode nor predicate is given, error. */
4635 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4637 if (GET_MODE (exp) == VOIDmode)
4638 fatal ("Null MATCH_OPERAND specified as test");
4639 else
4640 printf ("GET_MODE (operands[%d]) == %smode",
4641 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4643 else
4644 printf ("%s (operands[%d], %smode)",
4645 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4646 break;
4648 case MATCH_INSN:
4649 printf ("%s (insn)", XSTR (exp, 0));
4650 break;
4652 /* Constant integer. */
4653 case CONST_INT:
4654 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
4655 break;
4657 /* A random C expression. */
4658 case SYMBOL_REF:
4659 printf ("%s", XSTR (exp, 0));
4660 break;
4662 /* The address of the branch target. */
4663 case MATCH_DUP:
4664 printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]",
4665 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4666 break;
4668 case PC:
4669 /* The address of the current insn. We implement this actually as the
4670 address of the current insn for backward branches, but the last
4671 address of the next insn for forward branches, and both with
4672 adjustments that account for the worst-case possible stretching of
4673 intervening alignments between this insn and its destination. */
4674 printf("insn_current_reference_address (insn)");
4675 break;
4677 case CONST_STRING:
4678 printf ("%s", XSTR (exp, 0));
4679 break;
4681 case IF_THEN_ELSE:
4682 write_test_expr (XEXP (exp, 0), flags & 2);
4683 printf (" ? ");
4684 write_test_expr (XEXP (exp, 1), flags | 1);
4685 printf (" : ");
4686 write_test_expr (XEXP (exp, 2), flags | 1);
4687 break;
4689 default:
4690 fatal ("bad RTX code `%s' in attribute calculation\n",
4691 GET_RTX_NAME (code));
4694 printf (")");
4697 /* Given an attribute value, return the maximum CONST_STRING argument
4698 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
4700 static int
4701 max_attr_value (exp, unknownp)
4702 rtx exp;
4703 int *unknownp;
4705 int current_max;
4706 int i, n;
4708 switch (GET_CODE (exp))
4710 case CONST_STRING:
4711 current_max = atoi (XSTR (exp, 0));
4712 break;
4714 case COND:
4715 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4716 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4718 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4719 if (n > current_max)
4720 current_max = n;
4722 break;
4724 case IF_THEN_ELSE:
4725 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4726 n = max_attr_value (XEXP (exp, 2), unknownp);
4727 if (n > current_max)
4728 current_max = n;
4729 break;
4731 default:
4732 *unknownp = 1;
4733 current_max = INT_MAX;
4734 break;
4737 return current_max;
4740 /* Given an attribute value, return the result of ORing together all
4741 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4742 if the numeric value is not known. */
4744 static int
4745 or_attr_value (exp, unknownp)
4746 rtx exp;
4747 int *unknownp;
4749 int current_or;
4750 int i;
4752 switch (GET_CODE (exp))
4754 case CONST_STRING:
4755 current_or = atoi (XSTR (exp, 0));
4756 break;
4758 case COND:
4759 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4760 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4761 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4762 break;
4764 case IF_THEN_ELSE:
4765 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4766 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4767 break;
4769 default:
4770 *unknownp = 1;
4771 current_or = -1;
4772 break;
4775 return current_or;
4778 /* Scan an attribute value, possibly a conditional, and record what actions
4779 will be required to do any conditional tests in it.
4781 Specifically, set
4782 `must_extract' if we need to extract the insn operands
4783 `must_constrain' if we must compute `which_alternative'
4784 `address_used' if an address expression was used
4785 `length_used' if an (eq_attr "length" ...) was used
4788 static void
4789 walk_attr_value (exp)
4790 rtx exp;
4792 register int i, j;
4793 register const char *fmt;
4794 RTX_CODE code;
4796 if (exp == NULL)
4797 return;
4799 code = GET_CODE (exp);
4800 switch (code)
4802 case SYMBOL_REF:
4803 if (! RTX_UNCHANGING_P (exp))
4804 /* Since this is an arbitrary expression, it can look at anything.
4805 However, constant expressions do not depend on any particular
4806 insn. */
4807 must_extract = must_constrain = 1;
4808 return;
4810 case MATCH_OPERAND:
4811 must_extract = 1;
4812 return;
4814 case EQ_ATTR:
4815 if (XSTR (exp, 0) == alternative_name)
4816 must_extract = must_constrain = 1;
4817 else if (strcmp (XSTR (exp, 0), "length") == 0)
4818 length_used = 1;
4819 return;
4821 case MATCH_DUP:
4822 must_extract = 1;
4823 address_used = 1;
4824 return;
4826 case PC:
4827 address_used = 1;
4828 return;
4830 case ATTR_FLAG:
4831 return;
4833 default:
4834 break;
4837 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4838 switch (*fmt++)
4840 case 'e':
4841 case 'u':
4842 walk_attr_value (XEXP (exp, i));
4843 break;
4845 case 'E':
4846 if (XVEC (exp, i) != NULL)
4847 for (j = 0; j < XVECLEN (exp, i); j++)
4848 walk_attr_value (XVECEXP (exp, i, j));
4849 break;
4853 /* Write out a function to obtain the attribute for a given INSN. */
4855 static void
4856 write_attr_get (attr)
4857 struct attr_desc *attr;
4859 struct attr_value *av, *common_av;
4861 /* Find the most used attribute value. Handle that as the `default' of the
4862 switch we will generate. */
4863 common_av = find_most_used (attr);
4865 /* Write out prototype of function. */
4866 if (!attr->is_numeric)
4867 printf ("extern enum attr_%s ", attr->name);
4868 else if (attr->unsigned_p)
4869 printf ("extern unsigned int ");
4870 else
4871 printf ("extern int ");
4872 /* If the attribute name starts with a star, the remainder is the name of
4873 the subroutine to use, instead of `get_attr_...'. */
4874 if (attr->name[0] == '*')
4875 printf ("%s PROTO ((rtx));\n", &attr->name[1]);
4876 else
4877 printf ("get_attr_%s PROTO ((%s));\n", attr->name,
4878 (attr->is_const ? "void" : "rtx"));
4880 /* Write out start of function, then all values with explicit `case' lines,
4881 then a `default', then the value with the most uses. */
4882 if (!attr->is_numeric)
4883 printf ("enum attr_%s\n", attr->name);
4884 else if (attr->unsigned_p)
4885 printf ("unsigned int\n");
4886 else
4887 printf ("int\n");
4889 /* If the attribute name starts with a star, the remainder is the name of
4890 the subroutine to use, instead of `get_attr_...'. */
4891 if (attr->name[0] == '*')
4892 printf ("%s (insn)\n", &attr->name[1]);
4893 else if (attr->is_const == 0)
4894 printf ("get_attr_%s (insn)\n", attr->name);
4895 else
4897 printf ("get_attr_%s ()\n", attr->name);
4898 printf ("{\n");
4900 for (av = attr->first_value; av; av = av->next)
4901 if (av->num_insns != 0)
4902 write_attr_set (attr, 2, av->value, "return", ";",
4903 true_rtx, av->first_insn->insn_code,
4904 av->first_insn->insn_index);
4906 printf ("}\n\n");
4907 return;
4910 printf (" rtx insn;\n");
4911 printf ("{\n");
4913 if (GET_CODE (common_av->value) == FFS)
4915 rtx p = XEXP (common_av->value, 0);
4917 /* No need to emit code to abort if the insn is unrecognized; the
4918 other get_attr_foo functions will do that when we call them. */
4920 write_toplevel_expr (p);
4922 printf ("\n if (accum && accum == (accum & -accum))\n");
4923 printf (" {\n");
4924 printf (" int i;\n");
4925 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
4926 printf (" accum = i;\n");
4927 printf (" }\n else\n");
4928 printf (" accum = ~accum;\n");
4929 printf (" return accum;\n}\n\n");
4931 else
4933 printf (" switch (recog_memoized (insn))\n");
4934 printf (" {\n");
4936 for (av = attr->first_value; av; av = av->next)
4937 if (av != common_av)
4938 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4940 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4941 printf (" }\n}\n\n");
4945 /* Given an AND tree of known true terms (because we are inside an `if' with
4946 that as the condition or are in an `else' clause) and an expression,
4947 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4948 the bulk of the work. */
4950 static rtx
4951 eliminate_known_true (known_true, exp, insn_code, insn_index)
4952 rtx known_true;
4953 rtx exp;
4954 int insn_code, insn_index;
4956 rtx term;
4958 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4960 if (GET_CODE (known_true) == AND)
4962 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4963 insn_code, insn_index);
4964 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4965 insn_code, insn_index);
4967 else
4969 term = known_true;
4970 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4973 return exp;
4976 /* Write out a series of tests and assignment statements to perform tests and
4977 sets of an attribute value. We are passed an indentation amount and prefix
4978 and suffix strings to write around each attribute value (e.g., "return"
4979 and ";"). */
4981 static void
4982 write_attr_set (attr, indent, value, prefix, suffix, known_true,
4983 insn_code, insn_index)
4984 struct attr_desc *attr;
4985 int indent;
4986 rtx value;
4987 const char *prefix;
4988 const char *suffix;
4989 rtx known_true;
4990 int insn_code, insn_index;
4992 if (GET_CODE (value) == COND)
4994 /* Assume the default value will be the default of the COND unless we
4995 find an always true expression. */
4996 rtx default_val = XEXP (value, 1);
4997 rtx our_known_true = known_true;
4998 rtx newexp;
4999 int first_if = 1;
5000 int i;
5002 for (i = 0; i < XVECLEN (value, 0); i += 2)
5004 rtx testexp;
5005 rtx inner_true;
5007 testexp = eliminate_known_true (our_known_true,
5008 XVECEXP (value, 0, i),
5009 insn_code, insn_index);
5010 newexp = attr_rtx (NOT, testexp);
5011 newexp = insert_right_side (AND, our_known_true, newexp,
5012 insn_code, insn_index);
5014 /* If the test expression is always true or if the next `known_true'
5015 expression is always false, this is the last case, so break
5016 out and let this value be the `else' case. */
5017 if (testexp == true_rtx || newexp == false_rtx)
5019 default_val = XVECEXP (value, 0, i + 1);
5020 break;
5023 /* Compute the expression to pass to our recursive call as being
5024 known true. */
5025 inner_true = insert_right_side (AND, our_known_true,
5026 testexp, insn_code, insn_index);
5028 /* If this is always false, skip it. */
5029 if (inner_true == false_rtx)
5030 continue;
5032 write_indent (indent);
5033 printf ("%sif ", first_if ? "" : "else ");
5034 first_if = 0;
5035 write_test_expr (testexp, 0);
5036 printf ("\n");
5037 write_indent (indent + 2);
5038 printf ("{\n");
5040 write_attr_set (attr, indent + 4,
5041 XVECEXP (value, 0, i + 1), prefix, suffix,
5042 inner_true, insn_code, insn_index);
5043 write_indent (indent + 2);
5044 printf ("}\n");
5045 our_known_true = newexp;
5048 if (! first_if)
5050 write_indent (indent);
5051 printf ("else\n");
5052 write_indent (indent + 2);
5053 printf ("{\n");
5056 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5057 prefix, suffix, our_known_true, insn_code, insn_index);
5059 if (! first_if)
5061 write_indent (indent + 2);
5062 printf ("}\n");
5065 else
5067 write_indent (indent);
5068 printf ("%s ", prefix);
5069 write_attr_value (attr, value);
5070 printf ("%s\n", suffix);
5074 /* Write out the computation for one attribute value. */
5076 static void
5077 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5078 known_true)
5079 struct attr_desc *attr;
5080 struct attr_value *av;
5081 int write_case_lines;
5082 const char *prefix, *suffix;
5083 int indent;
5084 rtx known_true;
5086 struct insn_ent *ie;
5088 if (av->num_insns == 0)
5089 return;
5091 if (av->has_asm_insn)
5093 write_indent (indent);
5094 printf ("case -1:\n");
5095 write_indent (indent + 2);
5096 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5097 write_indent (indent + 2);
5098 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5099 write_indent (indent + 2);
5100 printf (" fatal_insn_not_found (insn);\n");
5103 if (write_case_lines)
5105 for (ie = av->first_insn; ie; ie = ie->next)
5106 if (ie->insn_code != -1)
5108 write_indent (indent);
5109 printf ("case %d:\n", ie->insn_code);
5112 else
5114 write_indent (indent);
5115 printf ("default:\n");
5118 /* See what we have to do to output this value. */
5119 must_extract = must_constrain = address_used = 0;
5120 walk_attr_value (av->value);
5122 if (must_extract)
5124 write_indent (indent + 2);
5125 printf ("extract_insn (insn);\n");
5128 if (must_constrain)
5130 #ifdef REGISTER_CONSTRAINTS
5131 write_indent (indent + 2);
5132 printf ("if (! constrain_operands (reload_completed))\n");
5133 write_indent (indent + 2);
5134 printf (" fatal_insn_not_found (insn);\n");
5135 #endif
5138 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5139 known_true, av->first_insn->insn_code,
5140 av->first_insn->insn_index);
5142 if (strncmp (prefix, "return", 6))
5144 write_indent (indent + 2);
5145 printf ("break;\n");
5147 printf ("\n");
5150 /* Search for uses of non-const attributes and write code to cache them. */
5152 static int
5153 write_expr_attr_cache (p, attr)
5154 rtx p;
5155 struct attr_desc *attr;
5157 const char *fmt;
5158 int i, ie, j, je;
5160 if (GET_CODE (p) == EQ_ATTR)
5162 if (XSTR (p, 0) != attr->name)
5163 return 0;
5165 if (!attr->is_numeric)
5166 printf (" register enum attr_%s ", attr->name);
5167 else if (attr->unsigned_p)
5168 printf (" register unsigned int ");
5169 else
5170 printf (" register int ");
5172 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5173 return 1;
5176 fmt = GET_RTX_FORMAT (GET_CODE (p));
5177 ie = GET_RTX_LENGTH (GET_CODE (p));
5178 for (i = 0; i < ie; i++)
5180 switch (*fmt++)
5182 case 'e':
5183 if (write_expr_attr_cache (XEXP (p, i), attr))
5184 return 1;
5185 break;
5187 case 'E':
5188 je = XVECLEN (p, i);
5189 for (j = 0; j < je; ++j)
5190 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5191 return 1;
5192 break;
5196 return 0;
5199 /* Evaluate an expression at top level. A front end to write_test_expr,
5200 in which we cache attribute values and break up excessively large
5201 expressions to cater to older compilers. */
5203 static void
5204 write_toplevel_expr (p)
5205 rtx p;
5207 struct attr_desc *attr;
5208 int i;
5210 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
5211 for (attr = attrs[i]; attr ; attr = attr->next)
5212 if (!attr->is_const)
5213 write_expr_attr_cache (p, attr);
5215 printf(" register unsigned long accum = 0;\n\n");
5217 while (GET_CODE (p) == IOR)
5219 rtx e;
5220 if (GET_CODE (XEXP (p, 0)) == IOR)
5221 e = XEXP (p, 1), p = XEXP (p, 0);
5222 else
5223 e = XEXP (p, 0), p = XEXP (p, 1);
5225 printf (" accum |= ");
5226 write_test_expr (e, 3);
5227 printf (";\n");
5229 printf (" accum |= ");
5230 write_test_expr (p, 3);
5231 printf (";\n");
5234 /* Utilities to write names in various forms. */
5236 static void
5237 write_unit_name (prefix, num, suffix)
5238 const char *prefix;
5239 int num;
5240 const char *suffix;
5242 struct function_unit *unit;
5244 for (unit = units; unit; unit = unit->next)
5245 if (unit->num == num)
5247 printf ("%s%s%s", prefix, unit->name, suffix);
5248 return;
5251 printf ("%s<unknown>%s", prefix, suffix);
5254 static void
5255 write_attr_valueq (attr, s)
5256 struct attr_desc *attr;
5257 char *s;
5259 if (attr->is_numeric)
5261 int num = atoi (s);
5263 printf ("%d", num);
5265 /* Make the blockage range values and function units used values easier
5266 to read. */
5267 if (attr->func_units_p)
5269 if (num == -1)
5270 printf (" /* units: none */");
5271 else if (num >= 0)
5272 write_unit_name (" /* units: ", num, " */");
5273 else
5275 int i;
5276 const char *sep = " /* units: ";
5277 for (i = 0, num = ~num; num; i++, num >>= 1)
5278 if (num & 1)
5280 write_unit_name (sep, i, (num == 1) ? " */" : "");
5281 sep = ", ";
5286 else if (attr->blockage_p)
5287 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5288 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5290 else if (num > 9 || num < 0)
5291 printf (" /* 0x%x */", num);
5293 else
5295 write_upcase (attr->name);
5296 printf ("_");
5297 write_upcase (s);
5301 static void
5302 write_attr_value (attr, value)
5303 struct attr_desc *attr;
5304 rtx value;
5306 int op;
5308 switch (GET_CODE (value))
5310 case CONST_STRING:
5311 write_attr_valueq (attr, XSTR (value, 0));
5312 break;
5314 case SYMBOL_REF:
5315 fputs (XSTR (value, 0), stdout);
5316 break;
5318 case ATTR:
5320 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
5321 printf ("get_attr_%s (%s)", attr2->name,
5322 (attr2->is_const ? "" : "insn"));
5324 break;
5326 case PLUS:
5327 op = '+';
5328 goto do_operator;
5329 case MINUS:
5330 op = '-';
5331 goto do_operator;
5332 case MULT:
5333 op = '*';
5334 goto do_operator;
5335 case DIV:
5336 op = '/';
5337 goto do_operator;
5338 case MOD:
5339 op = '%';
5340 goto do_operator;
5342 do_operator:
5343 write_attr_value (attr, XEXP (value, 0));
5344 putchar (' ');
5345 putchar (op);
5346 putchar (' ');
5347 write_attr_value (attr, XEXP (value, 1));
5348 break;
5350 default:
5351 abort ();
5355 static void
5356 write_upcase (str)
5357 char *str;
5359 while (*str)
5360 if (ISLOWER(*str))
5361 printf ("%c", toupper(*str++));
5362 else
5363 printf ("%c", *str++);
5366 static void
5367 write_indent (indent)
5368 int indent;
5370 for (; indent > 8; indent -= 8)
5371 printf ("\t");
5373 for (; indent; indent--)
5374 printf (" ");
5377 /* Write a subroutine that is given an insn that requires a delay slot, a
5378 delay slot ordinal, and a candidate insn. It returns non-zero if the
5379 candidate can be placed in the specified delay slot of the insn.
5381 We can write as many as three subroutines. `eligible_for_delay'
5382 handles normal delay slots, `eligible_for_annul_true' indicates that
5383 the specified insn can be annulled if the branch is true, and likewise
5384 for `eligible_for_annul_false'.
5386 KIND is a string distinguishing these three cases ("delay", "annul_true",
5387 or "annul_false"). */
5389 static void
5390 write_eligible_delay (kind)
5391 const char *kind;
5393 struct delay_desc *delay;
5394 int max_slots;
5395 char str[50];
5396 struct attr_desc *attr;
5397 struct attr_value *av, *common_av;
5398 int i;
5400 /* Compute the maximum number of delay slots required. We use the delay
5401 ordinal times this number plus one, plus the slot number as an index into
5402 the appropriate predicate to test. */
5404 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5405 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5406 max_slots = XVECLEN (delay->def, 1) / 3;
5408 /* Write function prelude. */
5410 printf ("int\n");
5411 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5412 kind);
5413 printf (" rtx delay_insn;\n");
5414 printf (" int slot;\n");
5415 printf (" rtx candidate_insn;\n");
5416 printf (" int flags ATTRIBUTE_UNUSED;\n");
5417 printf ("{\n");
5418 printf (" rtx insn;\n");
5419 printf ("\n");
5420 printf (" if (slot >= %d)\n", max_slots);
5421 printf (" abort ();\n");
5422 printf ("\n");
5424 /* If more than one delay type, find out which type the delay insn is. */
5426 if (num_delays > 1)
5428 attr = find_attr ("*delay_type", 0);
5429 if (! attr) abort ();
5430 common_av = find_most_used (attr);
5432 printf (" insn = delay_insn;\n");
5433 printf (" switch (recog_memoized (insn))\n");
5434 printf (" {\n");
5436 sprintf (str, " * %d;\n break;", max_slots);
5437 for (av = attr->first_value; av; av = av->next)
5438 if (av != common_av)
5439 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5441 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5442 printf (" }\n\n");
5444 /* Ensure matched. Otherwise, shouldn't have been called. */
5445 printf (" if (slot < %d)\n", max_slots);
5446 printf (" abort ();\n\n");
5449 /* If just one type of delay slot, write simple switch. */
5450 if (num_delays == 1 && max_slots == 1)
5452 printf (" insn = candidate_insn;\n");
5453 printf (" switch (recog_memoized (insn))\n");
5454 printf (" {\n");
5456 attr = find_attr ("*delay_1_0", 0);
5457 if (! attr) abort ();
5458 common_av = find_most_used (attr);
5460 for (av = attr->first_value; av; av = av->next)
5461 if (av != common_av)
5462 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5464 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5465 printf (" }\n");
5468 else
5470 /* Write a nested CASE. The first indicates which condition we need to
5471 test, and the inner CASE tests the condition. */
5472 printf (" insn = candidate_insn;\n");
5473 printf (" switch (slot)\n");
5474 printf (" {\n");
5476 for (delay = delays; delay; delay = delay->next)
5477 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5479 printf (" case %d:\n",
5480 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5481 printf (" switch (recog_memoized (insn))\n");
5482 printf ("\t{\n");
5484 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5485 attr = find_attr (str, 0);
5486 if (! attr) abort ();
5487 common_av = find_most_used (attr);
5489 for (av = attr->first_value; av; av = av->next)
5490 if (av != common_av)
5491 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5493 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5494 printf (" }\n");
5497 printf (" default:\n");
5498 printf (" abort ();\n");
5499 printf (" }\n");
5502 printf ("}\n\n");
5505 /* Write routines to compute conflict cost for function units. Then write a
5506 table describing the available function units. */
5508 static void
5509 write_function_unit_info ()
5511 struct function_unit *unit;
5512 int i;
5514 /* Write out conflict routines for function units. Don't bother writing
5515 one if there is only one issue delay value. */
5517 for (unit = units; unit; unit = unit->next)
5519 if (unit->needs_blockage_function)
5520 write_complex_function (unit, "blockage", "block");
5522 /* If the minimum and maximum conflict costs are the same, there
5523 is only one value, so we don't need a function. */
5524 if (! unit->needs_conflict_function)
5526 unit->default_cost = make_numeric_value (unit->issue_delay.max);
5527 continue;
5530 /* The function first computes the case from the candidate insn. */
5531 unit->default_cost = make_numeric_value (0);
5532 write_complex_function (unit, "conflict_cost", "cost");
5535 /* Now that all functions have been written, write the table describing
5536 the function units. The name is included for documentation purposes
5537 only. */
5539 printf ("struct function_unit_desc function_units[] = {\n");
5541 /* Write out the descriptions in numeric order, but don't force that order
5542 on the list. Doing so increases the runtime of genattrtab.c. */
5543 for (i = 0; i < num_units; i++)
5545 for (unit = units; unit; unit = unit->next)
5546 if (unit->num == i)
5547 break;
5549 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5550 unit->name, 1 << unit->num, unit->multiplicity,
5551 unit->simultaneity, XSTR (unit->default_cost, 0),
5552 unit->issue_delay.max, unit->name);
5554 if (unit->needs_conflict_function)
5555 printf ("%s_unit_conflict_cost, ", unit->name);
5556 else
5557 printf ("0, ");
5559 printf ("%d, ", unit->max_blockage);
5561 if (unit->needs_range_function)
5562 printf ("%s_unit_blockage_range, ", unit->name);
5563 else
5564 printf ("0, ");
5566 if (unit->needs_blockage_function)
5567 printf ("%s_unit_blockage", unit->name);
5568 else
5569 printf ("0");
5571 printf ("}, \n");
5574 printf ("};\n\n");
5577 static void
5578 write_complex_function (unit, name, connection)
5579 struct function_unit *unit;
5580 const char *name, *connection;
5582 struct attr_desc *case_attr, *attr;
5583 struct attr_value *av, *common_av;
5584 rtx value;
5585 char *str;
5586 int using_case;
5587 int i;
5589 printf ("static int %s_unit_%s PROTO ((rtx, rtx));\n", unit->name, name);
5590 printf ("static int\n");
5591 printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
5592 unit->name, name);
5593 printf (" rtx executing_insn;\n");
5594 printf (" rtx candidate_insn;\n");
5595 printf ("{\n");
5596 printf (" rtx insn;\n");
5597 printf (" int casenum;\n\n");
5598 printf (" insn = executing_insn;\n");
5599 printf (" switch (recog_memoized (insn))\n");
5600 printf (" {\n");
5602 /* Write the `switch' statement to get the case value. */
5603 str = (char *) alloca (strlen (unit->name) + strlen (name) + strlen (connection) + 10);
5604 sprintf (str, "*%s_cases", unit->name);
5605 case_attr = find_attr (str, 0);
5606 if (! case_attr) abort ();
5607 common_av = find_most_used (case_attr);
5609 for (av = case_attr->first_value; av; av = av->next)
5610 if (av != common_av)
5611 write_attr_case (case_attr, av, 1,
5612 "casenum =", ";", 4, unit->condexp);
5614 write_attr_case (case_attr, common_av, 0,
5615 "casenum =", ";", 4, unit->condexp);
5616 printf (" }\n\n");
5618 /* Now write an outer switch statement on each case. Then write
5619 the tests on the executing function within each. */
5620 printf (" insn = candidate_insn;\n");
5621 printf (" switch (casenum)\n");
5622 printf (" {\n");
5624 for (i = 0; i < unit->num_opclasses; i++)
5626 /* Ensure using this case. */
5627 using_case = 0;
5628 for (av = case_attr->first_value; av; av = av->next)
5629 if (av->num_insns
5630 && contained_in_p (make_numeric_value (i), av->value))
5631 using_case = 1;
5633 if (! using_case)
5634 continue;
5636 printf (" case %d:\n", i);
5637 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5638 attr = find_attr (str, 0);
5639 if (! attr) abort ();
5641 /* If single value, just write it. */
5642 value = find_single_value (attr);
5643 if (value)
5644 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5645 else
5647 common_av = find_most_used (attr);
5648 printf (" switch (recog_memoized (insn))\n");
5649 printf ("\t{\n");
5651 for (av = attr->first_value; av; av = av->next)
5652 if (av != common_av)
5653 write_attr_case (attr, av, 1,
5654 "return", ";", 8, unit->condexp);
5656 write_attr_case (attr, common_av, 0,
5657 "return", ";", 8, unit->condexp);
5658 printf (" }\n\n");
5662 /* This default case should not be needed, but gcc's analysis is not
5663 good enough to realize that the default case is not needed for the
5664 second switch statement. */
5665 printf (" default:\n abort ();\n");
5666 printf (" }\n}\n\n");
5669 /* This page contains miscellaneous utility routines. */
5671 /* Given a string, return the number of comma-separated elements in it.
5672 Return 0 for the null string. */
5674 static int
5675 n_comma_elts (s)
5676 char *s;
5678 int n;
5680 if (*s == '\0')
5681 return 0;
5683 for (n = 1; *s; s++)
5684 if (*s == ',')
5685 n++;
5687 return n;
5690 /* Given a pointer to a (char *), return a malloc'ed string containing the
5691 next comma-separated element. Advance the pointer to after the string
5692 scanned, or the end-of-string. Return NULL if at end of string. */
5694 static char *
5695 next_comma_elt (pstr)
5696 char **pstr;
5698 char *out_str;
5699 char *p;
5701 if (**pstr == '\0')
5702 return NULL;
5704 /* Find end of string to compute length. */
5705 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5708 out_str = attr_string (*pstr, p - *pstr);
5709 *pstr = p;
5711 if (**pstr == ',')
5712 (*pstr)++;
5714 return out_str;
5717 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5718 is non-zero, build a new attribute, if one does not exist. */
5720 static struct attr_desc *
5721 find_attr (name, create)
5722 const char *name;
5723 int create;
5725 struct attr_desc *attr;
5726 int index;
5728 /* Before we resort to using `strcmp', see if the string address matches
5729 anywhere. In most cases, it should have been canonicalized to do so. */
5730 if (name == alternative_name)
5731 return NULL;
5733 index = name[0] & (MAX_ATTRS_INDEX - 1);
5734 for (attr = attrs[index]; attr; attr = attr->next)
5735 if (name == attr->name)
5736 return attr;
5738 /* Otherwise, do it the slow way. */
5739 for (attr = attrs[index]; attr; attr = attr->next)
5740 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5741 return attr;
5743 if (! create)
5744 return NULL;
5746 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5747 attr->name = attr_string (name, strlen (name));
5748 attr->first_value = attr->default_val = NULL;
5749 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5750 attr->next = attrs[index];
5751 attrs[index] = attr;
5753 return attr;
5756 /* Create internal attribute with the given default value. */
5758 static void
5759 make_internal_attr (name, value, special)
5760 const char *name;
5761 rtx value;
5762 int special;
5764 struct attr_desc *attr;
5766 attr = find_attr (name, 1);
5767 if (attr->default_val)
5768 abort ();
5770 attr->is_numeric = 1;
5771 attr->is_const = 0;
5772 attr->is_special = (special & 1) != 0;
5773 attr->negative_ok = (special & 2) != 0;
5774 attr->unsigned_p = (special & 4) != 0;
5775 attr->func_units_p = (special & 8) != 0;
5776 attr->blockage_p = (special & 16) != 0;
5777 attr->default_val = get_attr_value (value, attr, -2);
5780 /* Find the most used value of an attribute. */
5782 static struct attr_value *
5783 find_most_used (attr)
5784 struct attr_desc *attr;
5786 struct attr_value *av;
5787 struct attr_value *most_used;
5788 int nuses;
5790 most_used = NULL;
5791 nuses = -1;
5793 for (av = attr->first_value; av; av = av->next)
5794 if (av->num_insns > nuses)
5795 nuses = av->num_insns, most_used = av;
5797 return most_used;
5800 /* If an attribute only has a single value used, return it. Otherwise
5801 return NULL. */
5803 static rtx
5804 find_single_value (attr)
5805 struct attr_desc *attr;
5807 struct attr_value *av;
5808 rtx unique_value;
5810 unique_value = NULL;
5811 for (av = attr->first_value; av; av = av->next)
5812 if (av->num_insns)
5814 if (unique_value)
5815 return NULL;
5816 else
5817 unique_value = av->value;
5820 return unique_value;
5823 /* Return (attr_value "n") */
5825 static rtx
5826 make_numeric_value (n)
5827 int n;
5829 static rtx int_values[20];
5830 rtx exp;
5831 char *p;
5833 if (n < 0)
5834 abort ();
5836 if (n < 20 && int_values[n])
5837 return int_values[n];
5839 p = attr_printf (MAX_DIGITS, "%d", n);
5840 exp = attr_rtx (CONST_STRING, p);
5842 if (n < 20)
5843 int_values[n] = exp;
5845 return exp;
5848 static void
5849 extend_range (range, min, max)
5850 struct range *range;
5851 int min;
5852 int max;
5854 if (range->min > min) range->min = min;
5855 if (range->max < max) range->max = max;
5859 xrealloc (old, size)
5860 PTR old;
5861 size_t size;
5863 register PTR ptr;
5864 if (old)
5865 ptr = (PTR) realloc (old, size);
5866 else
5867 ptr = (PTR) malloc (size);
5868 if (!ptr)
5869 fatal ("virtual memory exhausted");
5870 return ptr;
5874 xmalloc (size)
5875 size_t size;
5877 register PTR val = (PTR) malloc (size);
5879 if (val == 0)
5880 fatal ("virtual memory exhausted");
5881 return val;
5884 static rtx
5885 copy_rtx_unchanging (orig)
5886 register rtx orig;
5888 #if 0
5889 register rtx copy;
5890 register RTX_CODE code;
5891 #endif
5893 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
5894 return orig;
5896 MEM_IN_STRUCT_P (orig) = 1;
5897 return orig;
5899 #if 0
5900 code = GET_CODE (orig);
5901 switch (code)
5903 case CONST_INT:
5904 case CONST_DOUBLE:
5905 case SYMBOL_REF:
5906 case CODE_LABEL:
5907 return orig;
5909 default:
5910 break;
5913 copy = rtx_alloc (code);
5914 PUT_MODE (copy, GET_MODE (orig));
5915 RTX_UNCHANGING_P (copy) = 1;
5917 bcopy ((char *) &XEXP (orig, 0), (char *) &XEXP (copy, 0),
5918 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
5919 return copy;
5920 #endif
5923 /* Determine if an insn has a constant number of delay slots, i.e., the
5924 number of delay slots is not a function of the length of the insn. */
5926 static void
5927 write_const_num_delay_slots ()
5929 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
5930 struct attr_value *av;
5931 struct insn_ent *ie;
5933 if (attr)
5935 printf ("int\nconst_num_delay_slots (insn)\n");
5936 printf (" rtx insn;\n");
5937 printf ("{\n");
5938 printf (" switch (recog_memoized (insn))\n");
5939 printf (" {\n");
5941 for (av = attr->first_value; av; av = av->next)
5943 length_used = 0;
5944 walk_attr_value (av->value);
5945 if (length_used)
5947 for (ie = av->first_insn; ie; ie = ie->next)
5948 if (ie->insn_code != -1)
5949 printf (" case %d:\n", ie->insn_code);
5950 printf (" return 0;\n");
5954 printf (" default:\n");
5955 printf (" return 1;\n");
5956 printf (" }\n}\n\n");
5962 main (argc, argv)
5963 int argc;
5964 char **argv;
5966 rtx desc;
5967 FILE *infile;
5968 register int c;
5969 struct attr_desc *attr;
5970 struct insn_def *id;
5971 rtx tem;
5972 int i;
5974 progname = "genattrtab";
5976 #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
5977 /* Get rid of any avoidable limit on stack size. */
5979 struct rlimit rlim;
5981 /* Set the stack limit huge so that alloca does not fail. */
5982 getrlimit (RLIMIT_STACK, &rlim);
5983 rlim.rlim_cur = rlim.rlim_max;
5984 setrlimit (RLIMIT_STACK, &rlim);
5986 #endif
5988 progname = "genattrtab";
5989 obstack_init (rtl_obstack);
5990 obstack_init (hash_obstack);
5991 obstack_init (temp_obstack);
5993 if (argc <= 1)
5994 fatal ("No input file name.");
5996 infile = fopen (argv[1], "r");
5997 if (infile == 0)
5999 perror (argv[1]);
6000 exit (FATAL_EXIT_CODE);
6003 /* Set up true and false rtx's */
6004 true_rtx = rtx_alloc (CONST_INT);
6005 XWINT (true_rtx, 0) = 1;
6006 false_rtx = rtx_alloc (CONST_INT);
6007 XWINT (false_rtx, 0) = 0;
6008 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
6009 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
6011 alternative_name = attr_string ("alternative", strlen ("alternative"));
6013 printf ("/* Generated automatically by the program `genattrtab'\n\
6014 from the machine description file `md'. */\n\n");
6016 /* Read the machine description. */
6018 while (1)
6020 c = read_skip_spaces (infile);
6021 if (c == EOF)
6022 break;
6023 ungetc (c, infile);
6025 desc = read_rtx (infile);
6026 if (GET_CODE (desc) == DEFINE_INSN
6027 || GET_CODE (desc) == DEFINE_PEEPHOLE
6028 || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
6029 gen_insn (desc);
6031 else if (GET_CODE (desc) == DEFINE_EXPAND)
6032 insn_code_number++, insn_index_number++;
6034 else if (GET_CODE (desc) == DEFINE_SPLIT)
6035 insn_code_number++, insn_index_number++;
6037 else if (GET_CODE (desc) == DEFINE_PEEPHOLE2)
6038 insn_code_number++, insn_index_number++;
6040 else if (GET_CODE (desc) == DEFINE_ATTR)
6042 gen_attr (desc);
6043 insn_index_number++;
6046 else if (GET_CODE (desc) == DEFINE_DELAY)
6048 gen_delay (desc);
6049 insn_index_number++;
6052 else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
6054 gen_unit (desc);
6055 insn_index_number++;
6059 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6060 if (! got_define_asm_attributes)
6062 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6063 XVEC (tem, 0) = rtvec_alloc (0);
6064 gen_insn (tem);
6067 /* Expand DEFINE_DELAY information into new attribute. */
6068 if (num_delays)
6069 expand_delays ();
6071 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6072 if (num_units)
6073 expand_units ();
6075 printf ("#include \"config.h\"\n");
6076 printf ("#include \"system.h\"\n");
6077 printf ("#include \"rtl.h\"\n");
6078 printf ("#include \"insn-config.h\"\n");
6079 printf ("#include \"recog.h\"\n");
6080 printf ("#include \"regs.h\"\n");
6081 printf ("#include \"real.h\"\n");
6082 printf ("#include \"output.h\"\n");
6083 printf ("#include \"insn-attr.h\"\n");
6084 printf ("#include \"toplev.h\"\n");
6085 printf ("\n");
6086 printf ("#define operands recog_operand\n\n");
6088 /* Make `insn_alternatives'. */
6089 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6090 for (id = defs; id; id = id->next)
6091 if (id->insn_code >= 0)
6092 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6094 /* Make `insn_n_alternatives'. */
6095 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6096 for (id = defs; id; id = id->next)
6097 if (id->insn_code >= 0)
6098 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6100 /* Prepare to write out attribute subroutines by checking everything stored
6101 away and building the attribute cases. */
6103 check_defs ();
6104 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6105 for (attr = attrs[i]; attr; attr = attr->next)
6107 attr->default_val->value
6108 = check_attr_value (attr->default_val->value, attr);
6109 fill_attr (attr);
6112 /* Construct extra attributes for `length'. */
6113 make_length_attrs ();
6115 /* Perform any possible optimizations to speed up compilation. */
6116 optimize_attrs ();
6118 /* Now write out all the `gen_attr_...' routines. Do these before the
6119 special routines (specifically before write_function_unit_info), so
6120 that they get defined before they are used. */
6122 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6123 for (attr = attrs[i]; attr; attr = attr->next)
6125 if (! attr->is_special && ! attr->is_const)
6126 write_attr_get (attr);
6129 /* Write out delay eligibility information, if DEFINE_DELAY present.
6130 (The function to compute the number of delay slots will be written
6131 below.) */
6132 if (num_delays)
6134 write_eligible_delay ("delay");
6135 if (have_annul_true)
6136 write_eligible_delay ("annul_true");
6137 if (have_annul_false)
6138 write_eligible_delay ("annul_false");
6141 /* Write out information about function units. */
6142 if (num_units)
6143 write_function_unit_info ();
6145 /* Write out constant delay slot info */
6146 write_const_num_delay_slots ();
6148 write_length_unit_log ();
6150 fflush (stdout);
6151 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6152 /* NOTREACHED */
6153 return 0;