* regclass.c (fix_register): Fix typo.
[official-gcc.git] / gcc / genattrtab.c
blob2894e686113b8f425a026b386fc67fdea64bc361
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GNU CC.
8 GNU CC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GNU CC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU CC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_FUNCTION_UNIT definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
34 expression).
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
47 `get_attr_length'.
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
54 used.
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
74 definitions is to create arbitrarily complex expressions and have the
75 optimization simplify them.
77 Once optimization is complete, any required routines and definitions
78 will be written.
80 An optimization that is not yet implemented is to hoist the constant
81 expressions entirely out of the routines and definitions that are written.
82 A way to do this is to iterate over all possible combinations of values
83 for constant attributes and generate a set of functions for that given
84 combination. An initialization function would be written that evaluates
85 the attributes and installs the corresponding set of routines and
86 definitions (each would be accessed through a pointer).
88 We use the flags in an RTX as follows:
89 `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified
90 independent of the insn code.
91 `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
92 for the insn code currently being processed (see optimize_attrs).
93 `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
94 (see attr_rtx).
95 `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
96 EQ_ATTR rtx is true if !volatil and false if volatil. */
98 #include "hconfig.h"
99 #include "system.h"
100 #include "rtl.h"
101 #include "ggc.h"
102 #include "gensupport.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 obstack1, obstack2;
114 struct obstack *hash_obstack = &obstack1;
115 struct obstack *temp_obstack = &obstack2;
117 #define obstack_chunk_alloc xmalloc
118 #define obstack_chunk_free free
120 /* enough space to reserve for printing out ints */
121 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
123 /* Define structures used to record attributes and values. */
125 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
126 encountered, we store all the relevant information into a
127 `struct insn_def'. This is done to allow attribute definitions to occur
128 anywhere in the file. */
130 struct insn_def
132 struct insn_def *next; /* Next insn in chain. */
133 rtx def; /* The DEFINE_... */
134 int insn_code; /* Instruction number. */
135 int insn_index; /* Expression numer in file, for errors. */
136 int lineno; /* Line number. */
137 int num_alternatives; /* Number of alternatives. */
138 int vec_idx; /* Index of attribute vector in `def'. */
141 /* Once everything has been read in, we store in each attribute value a list
142 of insn codes that have that value. Here is the structure used for the
143 list. */
145 struct insn_ent
147 struct insn_ent *next; /* Next in chain. */
148 int insn_code; /* Instruction number. */
149 int insn_index; /* Index of definition in file */
150 int lineno; /* Line number. */
153 /* Each value of an attribute (either constant or computed) is assigned a
154 structure which is used as the listhead of the insns that have that
155 value. */
157 struct attr_value
159 rtx value; /* Value of attribute. */
160 struct attr_value *next; /* Next attribute value in chain. */
161 struct insn_ent *first_insn; /* First insn with this value. */
162 int num_insns; /* Number of insns with this value. */
163 int has_asm_insn; /* True if this value used for `asm' insns */
166 /* Structure for each attribute. */
168 struct attr_desc
170 char *name; /* Name of attribute. */
171 struct attr_desc *next; /* Next attribute. */
172 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
173 unsigned negative_ok : 1; /* Allow negative numeric values. */
174 unsigned unsigned_p : 1; /* Make the output function unsigned int. */
175 unsigned is_const : 1; /* Attribute value constant for each run. */
176 unsigned is_special : 1; /* Don't call `write_attr_set'. */
177 unsigned func_units_p : 1; /* this is the function_units attribute */
178 unsigned blockage_p : 1; /* this is the blockage range function */
179 struct attr_value *first_value; /* First value of this attribute. */
180 struct attr_value *default_val; /* Default value for this attribute. */
181 int lineno; /* Line number. */
184 #define NULL_ATTR (struct attr_desc *) NULL
186 /* A range of values. */
188 struct range
190 int min;
191 int max;
194 /* Structure for each DEFINE_DELAY. */
196 struct delay_desc
198 rtx def; /* DEFINE_DELAY expression. */
199 struct delay_desc *next; /* Next DEFINE_DELAY. */
200 int num; /* Number of DEFINE_DELAY, starting at 1. */
201 int lineno; /* Line number. */
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. */
215 int lineno; /* Line number. */
218 /* Record information about each function unit mentioned in a
219 DEFINE_FUNCTION_UNIT. */
221 struct function_unit
223 const char *name; /* Function unit name. */
224 struct function_unit *next; /* Next function unit. */
225 int num; /* Ordinal of this unit type. */
226 int multiplicity; /* Number of units of this type. */
227 int simultaneity; /* Maximum number of simultaneous insns
228 on this function unit or 0 if unlimited. */
229 rtx condexp; /* Expression TRUE for insn needing unit. */
230 int num_opclasses; /* Number of different operation types. */
231 struct function_unit_op *ops; /* Pointer to first operation type. */
232 int needs_conflict_function; /* Nonzero if a conflict function required. */
233 int needs_blockage_function; /* Nonzero if a blockage function required. */
234 int needs_range_function; /* Nonzero if blockage range function needed.*/
235 rtx default_cost; /* Conflict cost, if constant. */
236 struct range issue_delay; /* Range of issue delay values. */
237 int max_blockage; /* Maximum time an insn blocks the unit. */
238 int first_lineno; /* First seen line number. */
241 /* Listheads of above structures. */
243 /* This one is indexed by the first character of the attribute name. */
244 #define MAX_ATTRS_INDEX 256
245 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
246 static struct insn_def *defs;
247 static struct delay_desc *delays;
248 static struct function_unit *units;
250 /* An expression where all the unknown terms are EQ_ATTR tests can be
251 rearranged into a COND provided we can enumerate all possible
252 combinations of the unknown values. The set of combinations become the
253 tests of the COND; the value of the expression given that combination is
254 computed and becomes the corresponding value. To do this, we must be
255 able to enumerate all values for each attribute used in the expression
256 (currently, we give up if we find a numeric attribute).
258 If the set of EQ_ATTR tests used in an expression tests the value of N
259 different attributes, the list of all possible combinations can be made
260 by walking the N-dimensional attribute space defined by those
261 attributes. We record each of these as a struct dimension.
263 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
264 expression are the same, the will also have the same address. We find
265 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
266 represents the value of an EQ_ATTR node, so once all nodes are marked,
267 they are also given an initial value of FALSE.
269 We then separate the set of EQ_ATTR nodes into dimensions for each
270 attribute and put them on the VALUES list. Terms are added as needed by
271 `add_values_to_cover' so that all possible values of the attribute are
272 tested.
274 Each dimension also has a current value. This is the node that is
275 currently considered to be TRUE. If this is one of the nodes added by
276 `add_values_to_cover', all the EQ_ATTR tests in the original expression
277 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
279 NUM_VALUES is simply the length of the VALUES list and is there for
280 convenience.
282 Once the dimensions are created, the algorithm enumerates all possible
283 values and computes the current value of the given expression. */
285 struct dimension
287 struct attr_desc *attr; /* Attribute for this dimension. */
288 rtx values; /* List of attribute values used. */
289 rtx current_value; /* Position in the list for the TRUE value. */
290 int num_values; /* Length of the values list. */
293 /* Other variables. */
295 static int insn_code_number;
296 static int insn_index_number;
297 static int got_define_asm_attributes;
298 static int must_extract;
299 static int must_constrain;
300 static int address_used;
301 static int length_used;
302 static int num_delays;
303 static int have_annul_true, have_annul_false;
304 static int num_units, num_unit_opclasses;
305 static int num_insn_ents;
307 /* Used as operand to `operate_exp': */
309 enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
311 /* Stores, for each insn code, the number of constraint alternatives. */
313 static int *insn_n_alternatives;
315 /* Stores, for each insn code, a bitmap that has bits on for each possible
316 alternative. */
318 static int *insn_alternatives;
320 /* If nonzero, assume that the `alternative' attr has this value.
321 This is the hashed, unique string for the numeral
322 whose value is chosen alternative. */
324 static const char *current_alternative_string;
326 /* Used to simplify expressions. */
328 static rtx true_rtx, false_rtx;
330 /* Used to reduce calls to `strcmp' */
332 static char *alternative_name;
334 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
335 called. */
337 int reload_completed = 0;
339 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
340 to define it here. */
342 int optimize = 0;
344 /* Simplify an expression. Only call the routine if there is something to
345 simplify. */
346 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
347 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
348 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
350 /* Simplify (eq_attr ("alternative") ...)
351 when we are working with a particular alternative. */
352 #define SIMPLIFY_ALTERNATIVE(EXP) \
353 if (current_alternative_string \
354 && GET_CODE ((EXP)) == EQ_ATTR \
355 && XSTR ((EXP), 0) == alternative_name) \
356 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
357 ? true_rtx : false_rtx);
359 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
360 They won't actually be used. */
362 rtx global_rtl[GR_MAX];
363 rtx pic_offset_table_rtx;
365 static void attr_hash_add_rtx PARAMS ((int, rtx));
366 static void attr_hash_add_string PARAMS ((int, char *));
367 static rtx attr_rtx PARAMS ((enum rtx_code, ...));
368 static char *attr_printf PARAMS ((int, const char *, ...))
369 ATTRIBUTE_PRINTF_2;
370 static char *attr_string PARAMS ((const char *, int));
371 static rtx check_attr_test PARAMS ((rtx, int, int));
372 static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
373 static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
374 static rtx convert_set_attr PARAMS ((rtx, struct insn_def *));
375 static void check_defs PARAMS ((void));
376 #if 0
377 static rtx convert_const_symbol_ref PARAMS ((rtx, struct attr_desc *));
378 #endif
379 static rtx make_canonical PARAMS ((struct attr_desc *, rtx));
380 static struct attr_value *get_attr_value PARAMS ((rtx, struct attr_desc *, int));
381 static rtx copy_rtx_unchanging PARAMS ((rtx));
382 static rtx copy_boolean PARAMS ((rtx));
383 static void expand_delays PARAMS ((void));
384 static rtx operate_exp PARAMS ((enum operator, rtx, rtx));
385 static void expand_units PARAMS ((void));
386 static rtx simplify_knowing PARAMS ((rtx, rtx));
387 static rtx encode_units_mask PARAMS ((rtx));
388 static void fill_attr PARAMS ((struct attr_desc *));
389 /* dpx2 compiler chokes if we specify the arg types of the args. */
390 static rtx substitute_address PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
391 static void make_length_attrs PARAMS ((void));
392 static rtx identity_fn PARAMS ((rtx));
393 static rtx zero_fn PARAMS ((rtx));
394 static rtx one_fn PARAMS ((rtx));
395 static rtx max_fn PARAMS ((rtx));
396 static void write_length_unit_log PARAMS ((void));
397 static rtx simplify_cond PARAMS ((rtx, int, int));
398 #if 0
399 static rtx simplify_by_alternatives PARAMS ((rtx, int, int));
400 #endif
401 static rtx simplify_by_exploding PARAMS ((rtx));
402 static int find_and_mark_used_attributes PARAMS ((rtx, rtx *, int *));
403 static void unmark_used_attributes PARAMS ((rtx, struct dimension *, int));
404 static int add_values_to_cover PARAMS ((struct dimension *));
405 static int increment_current_value PARAMS ((struct dimension *, int));
406 static rtx test_for_current_value PARAMS ((struct dimension *, int));
407 static rtx simplify_with_current_value PARAMS ((rtx, struct dimension *, int));
408 static rtx simplify_with_current_value_aux PARAMS ((rtx));
409 static void clear_struct_flag PARAMS ((rtx));
410 static int count_sub_rtxs PARAMS ((rtx, int));
411 static void remove_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
412 static void insert_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
413 static rtx insert_right_side PARAMS ((enum rtx_code, rtx, rtx, int, int));
414 static rtx make_alternative_compare PARAMS ((int));
415 static int compute_alternative_mask PARAMS ((rtx, enum rtx_code));
416 static rtx evaluate_eq_attr PARAMS ((rtx, rtx, int, int));
417 static rtx simplify_and_tree PARAMS ((rtx, rtx *, int, int));
418 static rtx simplify_or_tree PARAMS ((rtx, rtx *, int, int));
419 static rtx simplify_test_exp PARAMS ((rtx, int, int));
420 static rtx simplify_test_exp_in_temp PARAMS ((rtx, int, int));
421 static void optimize_attrs PARAMS ((void));
422 static void gen_attr PARAMS ((rtx, int));
423 static int count_alternatives PARAMS ((rtx));
424 static int compares_alternatives_p PARAMS ((rtx));
425 static int contained_in_p PARAMS ((rtx, rtx));
426 static void gen_insn PARAMS ((rtx, int));
427 static void gen_delay PARAMS ((rtx, int));
428 static void gen_unit PARAMS ((rtx, int));
429 static void write_test_expr PARAMS ((rtx, int));
430 static int max_attr_value PARAMS ((rtx, int*));
431 static int or_attr_value PARAMS ((rtx, int*));
432 static void walk_attr_value PARAMS ((rtx));
433 static void write_attr_get PARAMS ((struct attr_desc *));
434 static rtx eliminate_known_true PARAMS ((rtx, rtx, int, int));
435 static void write_attr_set PARAMS ((struct attr_desc *, int, rtx,
436 const char *, const char *, rtx,
437 int, int));
438 static void write_attr_case PARAMS ((struct attr_desc *, struct attr_value *,
439 int, const char *, const char *, int, rtx));
440 static void write_unit_name PARAMS ((const char *, int, const char *));
441 static void write_attr_valueq PARAMS ((struct attr_desc *, const char *));
442 static void write_attr_value PARAMS ((struct attr_desc *, rtx));
443 static void write_upcase PARAMS ((const char *));
444 static void write_indent PARAMS ((int));
445 static void write_eligible_delay PARAMS ((const char *));
446 static void write_function_unit_info PARAMS ((void));
447 static void write_complex_function PARAMS ((struct function_unit *, const char *,
448 const char *));
449 static int write_expr_attr_cache PARAMS ((rtx, struct attr_desc *));
450 static void write_toplevel_expr PARAMS ((rtx));
451 static void write_const_num_delay_slots PARAMS ((void));
452 static int n_comma_elts PARAMS ((const char *));
453 static char *next_comma_elt PARAMS ((const char **));
454 static struct attr_desc *find_attr PARAMS ((const char *, int));
455 static void make_internal_attr PARAMS ((const char *, rtx, int));
456 static struct attr_value *find_most_used PARAMS ((struct attr_desc *));
457 static rtx find_single_value PARAMS ((struct attr_desc *));
458 static rtx make_numeric_value PARAMS ((int));
459 static void extend_range PARAMS ((struct range *, int, int));
460 static rtx attr_eq PARAMS ((const char *, const char *));
461 static const char *attr_numeral PARAMS ((int));
462 static int attr_equal_p PARAMS ((rtx, rtx));
463 static rtx attr_copy_rtx PARAMS ((rtx));
464 static int attr_rtx_cost PARAMS ((rtx));
466 #define oballoc(size) obstack_alloc (hash_obstack, size)
468 /* Hash table for sharing RTL and strings. */
470 /* Each hash table slot is a bucket containing a chain of these structures.
471 Strings are given negative hash codes; RTL expressions are given positive
472 hash codes. */
474 struct attr_hash
476 struct attr_hash *next; /* Next structure in the bucket. */
477 int hashcode; /* Hash code of this rtx or string. */
478 union
480 char *str; /* The string (negative hash codes) */
481 rtx rtl; /* or the RTL recorded here. */
482 } u;
485 /* Now here is the hash table. When recording an RTL, it is added to
486 the slot whose index is the hash code mod the table size. Note
487 that the hash table is used for several kinds of RTL (see attr_rtx)
488 and for strings. While all these live in the same table, they are
489 completely independent, and the hash code is computed differently
490 for each. */
492 #define RTL_HASH_SIZE 4093
493 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
495 /* Here is how primitive or already-shared RTL's hash
496 codes are made. */
497 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
499 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
501 static void
502 attr_hash_add_rtx (hashcode, rtl)
503 int hashcode;
504 rtx rtl;
506 register struct attr_hash *h;
508 h = (struct attr_hash *) obstack_alloc (hash_obstack,
509 sizeof (struct attr_hash));
510 h->hashcode = hashcode;
511 h->u.rtl = rtl;
512 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
513 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
516 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
518 static void
519 attr_hash_add_string (hashcode, str)
520 int hashcode;
521 char *str;
523 register struct attr_hash *h;
525 h = (struct attr_hash *) obstack_alloc (hash_obstack,
526 sizeof (struct attr_hash));
527 h->hashcode = -hashcode;
528 h->u.str = str;
529 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
530 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
533 /* Generate an RTL expression, but avoid duplicates.
534 Set the RTX_INTEGRATED_P flag for these permanent objects.
536 In some cases we cannot uniquify; then we return an ordinary
537 impermanent rtx with RTX_INTEGRATED_P clear.
539 Args are like gen_rtx, but without the mode:
541 rtx attr_rtx (code, [element1, ..., elementn]) */
543 static rtx
544 attr_rtx VPARAMS ((enum rtx_code code, ...))
546 #ifndef ANSI_PROTOTYPES
547 enum rtx_code code;
548 #endif
549 va_list p;
550 register int i; /* Array indices... */
551 register const char *fmt; /* Current rtx's format... */
552 register rtx rt_val = NULL_RTX;/* RTX to return to caller... */
553 int hashcode;
554 register struct attr_hash *h;
555 struct obstack *old_obstack = rtl_obstack;
557 VA_START (p, code);
559 #ifndef ANSI_PROTOTYPES
560 code = va_arg (p, enum rtx_code);
561 #endif
563 /* For each of several cases, search the hash table for an existing entry.
564 Use that entry if one is found; otherwise create a new RTL and add it
565 to the table. */
567 if (GET_RTX_CLASS (code) == '1')
569 rtx arg0 = va_arg (p, rtx);
571 /* A permanent object cannot point to impermanent ones. */
572 if (! RTX_INTEGRATED_P (arg0))
574 rt_val = rtx_alloc (code);
575 XEXP (rt_val, 0) = arg0;
576 va_end (p);
577 return rt_val;
580 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
581 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
582 if (h->hashcode == hashcode
583 && GET_CODE (h->u.rtl) == code
584 && XEXP (h->u.rtl, 0) == arg0)
585 goto found;
587 if (h == 0)
589 rtl_obstack = hash_obstack;
590 rt_val = rtx_alloc (code);
591 XEXP (rt_val, 0) = arg0;
594 else if (GET_RTX_CLASS (code) == 'c'
595 || GET_RTX_CLASS (code) == '2'
596 || GET_RTX_CLASS (code) == '<')
598 rtx arg0 = va_arg (p, rtx);
599 rtx arg1 = va_arg (p, rtx);
601 /* A permanent object cannot point to impermanent ones. */
602 if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
604 rt_val = rtx_alloc (code);
605 XEXP (rt_val, 0) = arg0;
606 XEXP (rt_val, 1) = arg1;
607 va_end (p);
608 return rt_val;
611 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
612 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
613 if (h->hashcode == hashcode
614 && GET_CODE (h->u.rtl) == code
615 && XEXP (h->u.rtl, 0) == arg0
616 && XEXP (h->u.rtl, 1) == arg1)
617 goto found;
619 if (h == 0)
621 rtl_obstack = hash_obstack;
622 rt_val = rtx_alloc (code);
623 XEXP (rt_val, 0) = arg0;
624 XEXP (rt_val, 1) = arg1;
627 else if (GET_RTX_LENGTH (code) == 1
628 && GET_RTX_FORMAT (code)[0] == 's')
630 char *arg0 = va_arg (p, char *);
632 if (code == SYMBOL_REF)
633 arg0 = attr_string (arg0, strlen (arg0));
635 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
636 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
637 if (h->hashcode == hashcode
638 && GET_CODE (h->u.rtl) == code
639 && XSTR (h->u.rtl, 0) == arg0)
640 goto found;
642 if (h == 0)
644 rtl_obstack = hash_obstack;
645 rt_val = rtx_alloc (code);
646 XSTR (rt_val, 0) = arg0;
649 else if (GET_RTX_LENGTH (code) == 2
650 && GET_RTX_FORMAT (code)[0] == 's'
651 && GET_RTX_FORMAT (code)[1] == 's')
653 char *arg0 = va_arg (p, char *);
654 char *arg1 = va_arg (p, char *);
656 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
657 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
658 if (h->hashcode == hashcode
659 && GET_CODE (h->u.rtl) == code
660 && XSTR (h->u.rtl, 0) == arg0
661 && XSTR (h->u.rtl, 1) == arg1)
662 goto found;
664 if (h == 0)
666 rtl_obstack = hash_obstack;
667 rt_val = rtx_alloc (code);
668 XSTR (rt_val, 0) = arg0;
669 XSTR (rt_val, 1) = arg1;
672 else if (code == CONST_INT)
674 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
675 if (arg0 == 0)
677 va_end (p);
678 return false_rtx;
680 if (arg0 == 1)
682 va_end (p);
683 return true_rtx;
685 goto nohash;
687 else
689 nohash:
690 rt_val = rtx_alloc (code); /* Allocate the storage space. */
692 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
693 for (i = 0; i < GET_RTX_LENGTH (code); i++)
695 switch (*fmt++)
697 case '0': /* Unused field. */
698 break;
700 case 'i': /* An integer? */
701 XINT (rt_val, i) = va_arg (p, int);
702 break;
704 case 'w': /* A wide integer? */
705 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
706 break;
708 case 's': /* A string? */
709 XSTR (rt_val, i) = va_arg (p, char *);
710 break;
712 case 'e': /* An expression? */
713 case 'u': /* An insn? Same except when printing. */
714 XEXP (rt_val, i) = va_arg (p, rtx);
715 break;
717 case 'E': /* An RTX vector? */
718 XVEC (rt_val, i) = va_arg (p, rtvec);
719 break;
721 default:
722 abort ();
725 va_end (p);
726 return rt_val;
729 rtl_obstack = old_obstack;
730 va_end (p);
731 attr_hash_add_rtx (hashcode, rt_val);
732 RTX_INTEGRATED_P (rt_val) = 1;
733 return rt_val;
735 found:
736 va_end (p);
737 return h->u.rtl;
740 /* Create a new string printed with the printf line arguments into a space
741 of at most LEN bytes:
743 rtx attr_printf (len, format, [arg1, ..., argn]) */
745 static char *
746 attr_printf VPARAMS ((register int len, const char *fmt, ...))
748 #ifndef ANSI_PROTOTYPES
749 register int len;
750 const char *fmt;
751 #endif
752 va_list p;
753 char str[256];
755 VA_START (p, fmt);
757 #ifndef ANSI_PROTOTYPES
758 len = va_arg (p, int);
759 fmt = va_arg (p, const char *);
760 #endif
762 if (len > 255) /* leave room for \0 */
763 abort ();
765 vsprintf (str, fmt, p);
766 va_end (p);
768 return attr_string (str, strlen (str));
771 static rtx
772 attr_eq (name, value)
773 const char *name, *value;
775 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
776 attr_string (value, strlen (value)));
779 static const char *
780 attr_numeral (n)
781 int n;
783 return XSTR (make_numeric_value (n), 0);
786 /* Return a permanent (possibly shared) copy of a string STR (not assumed
787 to be null terminated) with LEN bytes. */
789 static char *
790 attr_string (str, len)
791 const char *str;
792 int len;
794 register struct attr_hash *h;
795 int hashcode;
796 int i;
797 register char *new_str;
799 /* Compute the hash code. */
800 hashcode = (len + 1) * 613 + (unsigned) str[0];
801 for (i = 1; i <= len; i += 2)
802 hashcode = ((hashcode * 613) + (unsigned) str[i]);
803 if (hashcode < 0)
804 hashcode = -hashcode;
806 /* Search the table for the string. */
807 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
808 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
809 && !strncmp (h->u.str, str, len))
810 return h->u.str; /* <-- return if found. */
812 /* Not found; create a permanent copy and add it to the hash table. */
813 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
814 memcpy (new_str, str, len);
815 new_str[len] = '\0';
816 attr_hash_add_string (hashcode, new_str);
818 return new_str; /* Return the new string. */
821 /* Check two rtx's for equality of contents,
822 taking advantage of the fact that if both are hashed
823 then they can't be equal unless they are the same object. */
825 static int
826 attr_equal_p (x, y)
827 rtx x, y;
829 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
830 && rtx_equal_p (x, y)));
833 /* Copy an attribute value expression,
834 descending to all depths, but not copying any
835 permanent hashed subexpressions. */
837 static rtx
838 attr_copy_rtx (orig)
839 register rtx orig;
841 register rtx copy;
842 register int i, j;
843 register RTX_CODE code;
844 register const char *format_ptr;
846 /* No need to copy a permanent object. */
847 if (RTX_INTEGRATED_P (orig))
848 return orig;
850 code = GET_CODE (orig);
852 switch (code)
854 case REG:
855 case QUEUED:
856 case CONST_INT:
857 case CONST_DOUBLE:
858 case SYMBOL_REF:
859 case CODE_LABEL:
860 case PC:
861 case CC0:
862 return orig;
864 default:
865 break;
868 copy = rtx_alloc (code);
869 PUT_MODE (copy, GET_MODE (orig));
870 copy->in_struct = orig->in_struct;
871 copy->volatil = orig->volatil;
872 copy->unchanging = orig->unchanging;
873 copy->integrated = orig->integrated;
875 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
877 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
879 switch (*format_ptr++)
881 case 'e':
882 XEXP (copy, i) = XEXP (orig, i);
883 if (XEXP (orig, i) != NULL)
884 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
885 break;
887 case 'E':
888 case 'V':
889 XVEC (copy, i) = XVEC (orig, i);
890 if (XVEC (orig, i) != NULL)
892 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
893 for (j = 0; j < XVECLEN (copy, i); j++)
894 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
896 break;
898 case 'n':
899 case 'i':
900 XINT (copy, i) = XINT (orig, i);
901 break;
903 case 'w':
904 XWINT (copy, i) = XWINT (orig, i);
905 break;
907 case 's':
908 case 'S':
909 XSTR (copy, i) = XSTR (orig, i);
910 break;
912 default:
913 abort ();
916 return copy;
919 /* Given a test expression for an attribute, ensure it is validly formed.
920 IS_CONST indicates whether the expression is constant for each compiler
921 run (a constant expression may not test any particular insn).
923 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
924 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
925 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
927 Update the string address in EQ_ATTR expression to be the same used
928 in the attribute (or `alternative_name') to speed up subsequent
929 `find_attr' calls and eliminate most `strcmp' calls.
931 Return the new expression, if any. */
933 static rtx
934 check_attr_test (exp, is_const, lineno)
935 rtx exp;
936 int is_const;
937 int lineno;
939 struct attr_desc *attr;
940 struct attr_value *av;
941 const char *name_ptr, *p;
942 rtx orexp, newexp;
944 switch (GET_CODE (exp))
946 case EQ_ATTR:
947 /* Handle negation test. */
948 if (XSTR (exp, 1)[0] == '!')
949 return check_attr_test (attr_rtx (NOT,
950 attr_eq (XSTR (exp, 0),
951 &XSTR (exp, 1)[1])),
952 is_const, lineno);
954 else if (n_comma_elts (XSTR (exp, 1)) == 1)
956 attr = find_attr (XSTR (exp, 0), 0);
957 if (attr == NULL)
959 if (! strcmp (XSTR (exp, 0), "alternative"))
961 XSTR (exp, 0) = alternative_name;
962 /* This can't be simplified any further. */
963 RTX_UNCHANGING_P (exp) = 1;
964 return exp;
966 else
967 fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
970 if (is_const && ! attr->is_const)
971 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
972 XSTR (exp, 0));
974 /* Copy this just to make it permanent,
975 so expressions using it can be permanent too. */
976 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
978 /* It shouldn't be possible to simplify the value given to a
979 constant attribute, so don't expand this until it's time to
980 write the test expression. */
981 if (attr->is_const)
982 RTX_UNCHANGING_P (exp) = 1;
984 if (attr->is_numeric)
986 for (p = XSTR (exp, 1); *p; p++)
987 if (*p < '0' || *p > '9')
988 fatal ("Attribute `%s' takes only numeric values",
989 XSTR (exp, 0));
991 else
993 for (av = attr->first_value; av; av = av->next)
994 if (GET_CODE (av->value) == CONST_STRING
995 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
996 break;
998 if (av == NULL)
999 fatal ("Unknown value `%s' for `%s' attribute",
1000 XSTR (exp, 1), XSTR (exp, 0));
1003 else
1005 /* Make an IOR tree of the possible values. */
1006 orexp = false_rtx;
1007 name_ptr = XSTR (exp, 1);
1008 while ((p = next_comma_elt (&name_ptr)) != NULL)
1010 newexp = attr_eq (XSTR (exp, 0), p);
1011 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
1014 return check_attr_test (orexp, is_const, lineno);
1016 break;
1018 case ATTR_FLAG:
1019 break;
1021 case CONST_INT:
1022 /* Either TRUE or FALSE. */
1023 if (XWINT (exp, 0))
1024 return true_rtx;
1025 else
1026 return false_rtx;
1028 case IOR:
1029 case AND:
1030 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1031 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
1032 break;
1034 case NOT:
1035 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1036 break;
1038 case MATCH_INSN:
1039 case MATCH_OPERAND:
1040 if (is_const)
1041 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1042 GET_RTX_NAME (GET_CODE (exp)));
1043 /* These cases can't be simplified. */
1044 RTX_UNCHANGING_P (exp) = 1;
1045 break;
1047 case LE: case LT: case GT: case GE:
1048 case LEU: case LTU: case GTU: case GEU:
1049 case NE: case EQ:
1050 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1051 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1052 exp = attr_rtx (GET_CODE (exp),
1053 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1054 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
1055 /* These cases can't be simplified. */
1056 RTX_UNCHANGING_P (exp) = 1;
1057 break;
1059 case SYMBOL_REF:
1060 if (is_const)
1062 /* These cases are valid for constant attributes, but can't be
1063 simplified. */
1064 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1065 RTX_UNCHANGING_P (exp) = 1;
1066 break;
1068 default:
1069 fatal ("RTL operator \"%s\" not valid in attribute test",
1070 GET_RTX_NAME (GET_CODE (exp)));
1073 return exp;
1076 /* Given an expression, ensure that it is validly formed and that all named
1077 attribute values are valid for the given attribute. Issue a fatal error
1078 if not. If no attribute is specified, assume a numeric attribute.
1080 Return a perhaps modified replacement expression for the value. */
1082 static rtx
1083 check_attr_value (exp, attr)
1084 rtx exp;
1085 struct attr_desc *attr;
1087 struct attr_value *av;
1088 const char *p;
1089 int i;
1091 switch (GET_CODE (exp))
1093 case CONST_INT:
1094 if (attr && ! attr->is_numeric)
1096 message_with_line (attr->lineno,
1097 "CONST_INT not valid for non-numeric attribute %s",
1098 attr->name);
1099 have_error = 1;
1100 break;
1103 if (INTVAL (exp) < 0 && ! attr->negative_ok)
1105 message_with_line (attr->lineno,
1106 "negative numeric value specified for attribute %s",
1107 attr->name);
1108 have_error = 1;
1109 break;
1111 break;
1113 case CONST_STRING:
1114 if (! strcmp (XSTR (exp, 0), "*"))
1115 break;
1117 if (attr == 0 || attr->is_numeric)
1119 p = XSTR (exp, 0);
1120 if (attr && attr->negative_ok && *p == '-')
1121 p++;
1122 for (; *p; p++)
1123 if (*p > '9' || *p < '0')
1125 message_with_line (attr ? attr->lineno : 0,
1126 "non-numeric value for numeric attribute %s",
1127 attr ? attr->name : "internal");
1128 have_error = 1;
1129 break;
1131 break;
1134 for (av = attr->first_value; av; av = av->next)
1135 if (GET_CODE (av->value) == CONST_STRING
1136 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1137 break;
1139 if (av == NULL)
1141 message_with_line (attr->lineno,
1142 "unknown value `%s' for `%s' attribute",
1143 XSTR (exp, 0), attr ? attr->name : "internal");
1144 have_error = 1;
1146 break;
1148 case IF_THEN_ELSE:
1149 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1150 attr ? attr->is_const : 0,
1151 attr ? attr->lineno : 0);
1152 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1153 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1154 break;
1156 case PLUS:
1157 case MINUS:
1158 case MULT:
1159 case DIV:
1160 case MOD:
1161 if (attr && !attr->is_numeric)
1163 message_with_line (attr->lineno,
1164 "invalid operation `%s' for non-numeric attribute value",
1165 GET_RTX_NAME (GET_CODE (exp)));
1166 have_error = 1;
1167 break;
1169 /* FALLTHRU */
1171 case IOR:
1172 case AND:
1173 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1174 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1175 break;
1177 case FFS:
1178 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1179 break;
1181 case COND:
1182 if (XVECLEN (exp, 0) % 2 != 0)
1184 message_with_line (attr->lineno,
1185 "first operand of COND must have even length");
1186 have_error = 1;
1187 break;
1190 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1192 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1193 attr ? attr->is_const : 0,
1194 attr ? attr->lineno : 0);
1195 XVECEXP (exp, 0, i + 1)
1196 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1199 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1200 break;
1202 case ATTR:
1204 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
1205 if (attr2 == NULL)
1207 message_with_line (attr ? attr->lineno : 0,
1208 "unknown attribute `%s' in ATTR",
1209 XSTR (exp, 0));
1210 have_error = 1;
1212 else if (attr && attr->is_const && ! attr2->is_const)
1214 message_with_line (attr->lineno,
1215 "non-constant attribute `%s' referenced from `%s'",
1216 XSTR (exp, 0), attr->name);
1217 have_error = 1;
1219 else if (attr
1220 && (attr->is_numeric != attr2->is_numeric
1221 || (! attr->negative_ok && attr2->negative_ok)))
1223 message_with_line (attr->lineno,
1224 "numeric attribute mismatch calling `%s' from `%s'",
1225 XSTR (exp, 0), attr->name);
1226 have_error = 1;
1229 break;
1231 case SYMBOL_REF:
1232 /* A constant SYMBOL_REF is valid as a constant attribute test and
1233 is expanded later by make_canonical into a COND. In a non-constant
1234 attribute test, it is left be. */
1235 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1237 default:
1238 message_with_line (attr ? attr->lineno : 0,
1239 "invalid operation `%s' for attribute value",
1240 GET_RTX_NAME (GET_CODE (exp)));
1241 have_error = 1;
1242 break;
1245 return exp;
1248 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1249 It becomes a COND with each test being (eq_attr "alternative "n") */
1251 static rtx
1252 convert_set_attr_alternative (exp, id)
1253 rtx exp;
1254 struct insn_def *id;
1256 int num_alt = id->num_alternatives;
1257 rtx condexp;
1258 int i;
1260 if (XVECLEN (exp, 1) != num_alt)
1262 message_with_line (id->lineno,
1263 "bad number of entries in SET_ATTR_ALTERNATIVE");
1264 have_error = 1;
1265 return NULL_RTX;
1268 /* Make a COND with all tests but the last. Select the last value via the
1269 default. */
1270 condexp = rtx_alloc (COND);
1271 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1273 for (i = 0; i < num_alt - 1; i++)
1275 const char *p;
1276 p = attr_numeral (i);
1278 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1279 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1282 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1284 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1287 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1288 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1290 static rtx
1291 convert_set_attr (exp, id)
1292 rtx exp;
1293 struct insn_def *id;
1295 rtx newexp;
1296 const char *name_ptr;
1297 char *p;
1298 int n;
1300 /* See how many alternative specified. */
1301 n = n_comma_elts (XSTR (exp, 1));
1302 if (n == 1)
1303 return attr_rtx (SET,
1304 attr_rtx (ATTR, XSTR (exp, 0)),
1305 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1307 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1308 XSTR (newexp, 0) = XSTR (exp, 0);
1309 XVEC (newexp, 1) = rtvec_alloc (n);
1311 /* Process each comma-separated name. */
1312 name_ptr = XSTR (exp, 1);
1313 n = 0;
1314 while ((p = next_comma_elt (&name_ptr)) != NULL)
1315 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1317 return convert_set_attr_alternative (newexp, id);
1320 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1321 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1322 expressions. */
1324 static void
1325 check_defs ()
1327 struct insn_def *id;
1328 struct attr_desc *attr;
1329 int i;
1330 rtx value;
1332 for (id = defs; id; id = id->next)
1334 if (XVEC (id->def, id->vec_idx) == NULL)
1335 continue;
1337 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1339 value = XVECEXP (id->def, id->vec_idx, i);
1340 switch (GET_CODE (value))
1342 case SET:
1343 if (GET_CODE (XEXP (value, 0)) != ATTR)
1345 message_with_line (id->lineno, "bad attribute set");
1346 have_error = 1;
1347 value = NULL_RTX;
1349 break;
1351 case SET_ATTR_ALTERNATIVE:
1352 value = convert_set_attr_alternative (value, id);
1353 break;
1355 case SET_ATTR:
1356 value = convert_set_attr (value, id);
1357 break;
1359 default:
1360 message_with_line (id->lineno, "invalid attribute code %s",
1361 GET_RTX_NAME (GET_CODE (value)));
1362 have_error = 1;
1363 value = NULL_RTX;
1365 if (value == NULL_RTX)
1366 continue;
1368 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1370 message_with_line (id->lineno, "unknown attribute %s",
1371 XSTR (XEXP (value, 0), 0));
1372 have_error = 1;
1373 continue;
1376 XVECEXP (id->def, id->vec_idx, i) = value;
1377 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1382 #if 0
1383 /* Given a constant SYMBOL_REF expression, convert to a COND that
1384 explicitly tests each enumerated value. */
1386 static rtx
1387 convert_const_symbol_ref (exp, attr)
1388 rtx exp;
1389 struct attr_desc *attr;
1391 rtx condexp;
1392 struct attr_value *av;
1393 int i;
1394 int num_alt = 0;
1396 for (av = attr->first_value; av; av = av->next)
1397 num_alt++;
1399 /* Make a COND with all tests but the last, and in the original order.
1400 Select the last value via the default. Note that the attr values
1401 are constructed in reverse order. */
1403 condexp = rtx_alloc (COND);
1404 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1405 av = attr->first_value;
1406 XEXP (condexp, 1) = av->value;
1408 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1410 char *p, *string;
1411 rtx value;
1413 string = p = (char *) oballoc (2
1414 + strlen (attr->name)
1415 + strlen (XSTR (av->value, 0)));
1416 strcpy (p, attr->name);
1417 strcat (p, "_");
1418 strcat (p, XSTR (av->value, 0));
1419 for (; *p != '\0'; p++)
1420 *p = TOUPPER (*p);
1422 value = attr_rtx (SYMBOL_REF, string);
1423 RTX_UNCHANGING_P (value) = 1;
1425 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1427 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1430 return condexp;
1432 #endif
1434 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1435 expressions by converting them into a COND. This removes cases from this
1436 program. Also, replace an attribute value of "*" with the default attribute
1437 value. */
1439 static rtx
1440 make_canonical (attr, exp)
1441 struct attr_desc *attr;
1442 rtx exp;
1444 int i;
1445 rtx newexp;
1447 switch (GET_CODE (exp))
1449 case CONST_INT:
1450 exp = make_numeric_value (INTVAL (exp));
1451 break;
1453 case CONST_STRING:
1454 if (! strcmp (XSTR (exp, 0), "*"))
1456 if (attr == 0 || attr->default_val == 0)
1457 fatal ("(attr_value \"*\") used in invalid context.");
1458 exp = attr->default_val->value;
1461 break;
1463 case SYMBOL_REF:
1464 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1465 break;
1466 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1467 This makes the COND something that won't be considered an arbitrary
1468 expression by walk_attr_value. */
1469 RTX_UNCHANGING_P (exp) = 1;
1470 #if 0
1471 /* ??? Why do we do this? With attribute values { A B C D E }, this
1472 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1473 than (x==E). */
1474 exp = convert_const_symbol_ref (exp, attr);
1475 RTX_UNCHANGING_P (exp) = 1;
1476 exp = check_attr_value (exp, attr);
1477 /* Goto COND case since this is now a COND. Note that while the
1478 new expression is rescanned, all symbol_ref notes are marked as
1479 unchanging. */
1480 goto cond;
1481 #else
1482 exp = check_attr_value (exp, attr);
1483 break;
1484 #endif
1486 case IF_THEN_ELSE:
1487 newexp = rtx_alloc (COND);
1488 XVEC (newexp, 0) = rtvec_alloc (2);
1489 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1490 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1492 XEXP (newexp, 1) = XEXP (exp, 2);
1494 exp = newexp;
1495 /* Fall through to COND case since this is now a COND. */
1497 case COND:
1499 int allsame = 1;
1500 rtx defval;
1502 /* First, check for degenerate COND. */
1503 if (XVECLEN (exp, 0) == 0)
1504 return make_canonical (attr, XEXP (exp, 1));
1505 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1507 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1509 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1510 XVECEXP (exp, 0, i + 1)
1511 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1512 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1513 allsame = 0;
1515 if (allsame)
1516 return defval;
1518 break;
1520 default:
1521 break;
1524 return exp;
1527 static rtx
1528 copy_boolean (exp)
1529 rtx exp;
1531 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1532 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1533 copy_boolean (XEXP (exp, 1)));
1534 return exp;
1537 /* Given a value and an attribute description, return a `struct attr_value *'
1538 that represents that value. This is either an existing structure, if the
1539 value has been previously encountered, or a newly-created structure.
1541 `insn_code' is the code of an insn whose attribute has the specified
1542 value (-2 if not processing an insn). We ensure that all insns for
1543 a given value have the same number of alternatives if the value checks
1544 alternatives. */
1546 static struct attr_value *
1547 get_attr_value (value, attr, insn_code)
1548 rtx value;
1549 struct attr_desc *attr;
1550 int insn_code;
1552 struct attr_value *av;
1553 int num_alt = 0;
1555 value = make_canonical (attr, value);
1556 if (compares_alternatives_p (value))
1558 if (insn_code < 0 || insn_alternatives == NULL)
1559 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1560 else
1561 num_alt = insn_alternatives[insn_code];
1564 for (av = attr->first_value; av; av = av->next)
1565 if (rtx_equal_p (value, av->value)
1566 && (num_alt == 0 || av->first_insn == NULL
1567 || insn_alternatives[av->first_insn->insn_code]))
1568 return av;
1570 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1571 av->value = value;
1572 av->next = attr->first_value;
1573 attr->first_value = av;
1574 av->first_insn = NULL;
1575 av->num_insns = 0;
1576 av->has_asm_insn = 0;
1578 return av;
1581 /* After all DEFINE_DELAYs have been read in, create internal attributes
1582 to generate the required routines.
1584 First, we compute the number of delay slots for each insn (as a COND of
1585 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1586 delay type is specified, we compute a similar function giving the
1587 DEFINE_DELAY ordinal for each insn.
1589 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1590 tells whether a given insn can be in that delay slot.
1592 Normal attribute filling and optimization expands these to contain the
1593 information needed to handle delay slots. */
1595 static void
1596 expand_delays ()
1598 struct delay_desc *delay;
1599 rtx condexp;
1600 rtx newexp;
1601 int i;
1602 char *p;
1604 /* First, generate data for `num_delay_slots' function. */
1606 condexp = rtx_alloc (COND);
1607 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1608 XEXP (condexp, 1) = make_numeric_value (0);
1610 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1612 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1613 XVECEXP (condexp, 0, i + 1)
1614 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1617 make_internal_attr ("*num_delay_slots", condexp, 0);
1619 /* If more than one delay type, do the same for computing the delay type. */
1620 if (num_delays > 1)
1622 condexp = rtx_alloc (COND);
1623 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1624 XEXP (condexp, 1) = make_numeric_value (0);
1626 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1628 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1629 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1632 make_internal_attr ("*delay_type", condexp, 1);
1635 /* For each delay possibility and delay slot, compute an eligibility
1636 attribute for non-annulled insns and for each type of annulled (annul
1637 if true and annul if false). */
1638 for (delay = delays; delay; delay = delay->next)
1640 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1642 condexp = XVECEXP (delay->def, 1, i);
1643 if (condexp == 0)
1644 condexp = false_rtx;
1645 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1646 make_numeric_value (1), make_numeric_value (0));
1648 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS * 2,
1649 "*delay_%d_%d",
1650 delay->num, i / 3);
1651 make_internal_attr (p, newexp, 1);
1653 if (have_annul_true)
1655 condexp = XVECEXP (delay->def, 1, i + 1);
1656 if (condexp == 0) condexp = false_rtx;
1657 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1658 make_numeric_value (1),
1659 make_numeric_value (0));
1660 p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS * 2,
1661 "*annul_true_%d_%d", delay->num, i / 3);
1662 make_internal_attr (p, newexp, 1);
1665 if (have_annul_false)
1667 condexp = XVECEXP (delay->def, 1, i + 2);
1668 if (condexp == 0) condexp = false_rtx;
1669 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1670 make_numeric_value (1),
1671 make_numeric_value (0));
1672 p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS * 2,
1673 "*annul_false_%d_%d", delay->num, i / 3);
1674 make_internal_attr (p, newexp, 1);
1680 /* This function is given a left and right side expression and an operator.
1681 Each side is a conditional expression, each alternative of which has a
1682 numerical value. The function returns another conditional expression
1683 which, for every possible set of condition values, returns a value that is
1684 the operator applied to the values of the two sides.
1686 Since this is called early, it must also support IF_THEN_ELSE. */
1688 static rtx
1689 operate_exp (op, left, right)
1690 enum operator op;
1691 rtx left, right;
1693 int left_value, right_value;
1694 rtx newexp;
1695 int i;
1697 /* If left is a string, apply operator to it and the right side. */
1698 if (GET_CODE (left) == CONST_STRING)
1700 /* If right is also a string, just perform the operation. */
1701 if (GET_CODE (right) == CONST_STRING)
1703 left_value = atoi (XSTR (left, 0));
1704 right_value = atoi (XSTR (right, 0));
1705 switch (op)
1707 case PLUS_OP:
1708 i = left_value + right_value;
1709 break;
1711 case MINUS_OP:
1712 i = left_value - right_value;
1713 break;
1715 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1716 if (left_value > right_value)
1717 i = left_value - right_value;
1718 else
1719 i = 0;
1720 break;
1722 case OR_OP:
1723 case ORX_OP:
1724 i = left_value | right_value;
1725 break;
1727 case EQ_OP:
1728 i = left_value == right_value;
1729 break;
1731 case RANGE_OP:
1732 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1733 break;
1735 case MAX_OP:
1736 if (left_value > right_value)
1737 i = left_value;
1738 else
1739 i = right_value;
1740 break;
1742 case MIN_OP:
1743 if (left_value < right_value)
1744 i = left_value;
1745 else
1746 i = right_value;
1747 break;
1749 default:
1750 abort ();
1753 if (i == left_value)
1754 return left;
1755 if (i == right_value)
1756 return right;
1757 return make_numeric_value (i);
1759 else if (GET_CODE (right) == IF_THEN_ELSE)
1761 /* Apply recursively to all values within. */
1762 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1763 rtx newright = operate_exp (op, left, XEXP (right, 2));
1764 if (rtx_equal_p (newleft, newright))
1765 return newleft;
1766 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1768 else if (GET_CODE (right) == COND)
1770 int allsame = 1;
1771 rtx defval;
1773 newexp = rtx_alloc (COND);
1774 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1775 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1777 for (i = 0; i < XVECLEN (right, 0); i += 2)
1779 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1780 XVECEXP (newexp, 0, i + 1)
1781 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1782 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1783 defval))
1784 allsame = 0;
1787 /* If the resulting cond is trivial (all alternatives
1788 give the same value), optimize it away. */
1789 if (allsame)
1790 return operate_exp (op, left, XEXP (right, 1));
1792 return newexp;
1794 else
1795 fatal ("Badly formed attribute value");
1798 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1799 not associate through IF_THEN_ELSE. */
1800 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1802 return attr_rtx (IOR, left, right);
1805 /* Otherwise, do recursion the other way. */
1806 else if (GET_CODE (left) == IF_THEN_ELSE)
1808 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1809 rtx newright = operate_exp (op, XEXP (left, 2), right);
1810 if (rtx_equal_p (newleft, newright))
1811 return newleft;
1812 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1814 else if (GET_CODE (left) == COND)
1816 int allsame = 1;
1817 rtx defval;
1819 newexp = rtx_alloc (COND);
1820 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1821 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1823 for (i = 0; i < XVECLEN (left, 0); i += 2)
1825 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1826 XVECEXP (newexp, 0, i + 1)
1827 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1828 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1829 defval))
1830 allsame = 0;
1833 /* If the cond is trivial (all alternatives give the same value),
1834 optimize it away. */
1835 if (allsame)
1836 return operate_exp (op, XEXP (left, 1), right);
1838 /* If the result is the same as the LEFT operand,
1839 just use that. */
1840 if (rtx_equal_p (newexp, left))
1841 return left;
1843 return newexp;
1846 else
1847 fatal ("Badly formed attribute value.");
1848 /* NOTREACHED */
1849 return NULL;
1852 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1853 construct a number of attributes.
1855 The first produces a function `function_units_used' which is given an
1856 insn and produces an encoding showing which function units are required
1857 for the execution of that insn. If the value is non-negative, the insn
1858 uses that unit; otherwise, the value is a one's compliment mask of units
1859 used.
1861 The second produces a function `result_ready_cost' which is used to
1862 determine the time that the result of an insn will be ready and hence
1863 a worst-case schedule.
1865 Both of these produce quite complex expressions which are then set as the
1866 default value of internal attributes. Normal attribute simplification
1867 should produce reasonable expressions.
1869 For each unit, a `<name>_unit_ready_cost' function will take an
1870 insn and give the delay until that unit will be ready with the result
1871 and a `<name>_unit_conflict_cost' function is given an insn already
1872 executing on the unit and a candidate to execute and will give the
1873 cost from the time the executing insn started until the candidate
1874 can start (ignore limitations on the number of simultaneous insns).
1876 For each unit, a `<name>_unit_blockage' function is given an insn
1877 already executing on the unit and a candidate to execute and will
1878 give the delay incurred due to function unit conflicts. The range of
1879 blockage cost values for a given executing insn is given by the
1880 `<name>_unit_blockage_range' function. These values are encoded in
1881 an int where the upper half gives the minimum value and the lower
1882 half gives the maximum value. */
1884 static void
1885 expand_units ()
1887 struct function_unit *unit, **unit_num;
1888 struct function_unit_op *op, **op_array, ***unit_ops;
1889 rtx unitsmask;
1890 rtx readycost;
1891 rtx newexp;
1892 const char *str;
1893 int i, j, u, num, nvalues;
1895 /* Rebuild the condition for the unit to share the RTL expressions.
1896 Sharing is required by simplify_by_exploding. Build the issue delay
1897 expressions. Validate the expressions we were given for the conditions
1898 and conflict vector. Then make attributes for use in the conflict
1899 function. */
1901 for (unit = units; unit; unit = unit->next)
1903 unit->condexp = check_attr_test (unit->condexp, 0, unit->first_lineno);
1905 for (op = unit->ops; op; op = op->next)
1907 rtx issue_delay = make_numeric_value (op->issue_delay);
1908 rtx issue_exp = issue_delay;
1910 /* Build, validate, and simplify the issue delay expression. */
1911 if (op->conflict_exp != true_rtx)
1912 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1913 issue_exp, make_numeric_value (0));
1914 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1915 issue_exp),
1916 NULL_ATTR);
1917 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1918 op->issue_exp = issue_exp;
1920 /* Make an attribute for use in the conflict function if needed. */
1921 unit->needs_conflict_function = (unit->issue_delay.min
1922 != unit->issue_delay.max);
1923 if (unit->needs_conflict_function)
1925 str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1926 "*%s_cost_%d", unit->name, op->num);
1927 make_internal_attr (str, issue_exp, 1);
1930 /* Validate the condition. */
1931 op->condexp = check_attr_test (op->condexp, 0, op->lineno);
1935 /* Compute the mask of function units used. Initially, the unitsmask is
1936 zero. Set up a conditional to compute each unit's contribution. */
1937 unitsmask = make_numeric_value (0);
1938 newexp = rtx_alloc (IF_THEN_ELSE);
1939 XEXP (newexp, 2) = make_numeric_value (0);
1941 /* If we have just a few units, we may be all right expanding the whole
1942 thing. But the expansion is 2**N in space on the number of opclasses,
1943 so we can't do this for very long -- Alpha and MIPS in particular have
1944 problems with this. So in that situation, we fall back on an alternate
1945 implementation method. */
1946 #define NUM_UNITOP_CUTOFF 20
1948 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1950 /* Merge each function unit into the unit mask attributes. */
1951 for (unit = units; unit; unit = unit->next)
1953 XEXP (newexp, 0) = unit->condexp;
1954 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1955 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1958 else
1960 /* Merge each function unit into the unit mask attributes. */
1961 for (unit = units; unit; unit = unit->next)
1963 XEXP (newexp, 0) = unit->condexp;
1964 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1965 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1969 /* Simplify the unit mask expression, encode it, and make an attribute
1970 for the function_units_used function. */
1971 unitsmask = simplify_by_exploding (unitsmask);
1973 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1974 unitsmask = encode_units_mask (unitsmask);
1975 else
1977 /* We can no longer encode unitsmask at compile time, so emit code to
1978 calculate it at runtime. Rather, put a marker for where we'd do
1979 the code, and actually output it in write_attr_get(). */
1980 unitsmask = attr_rtx (FFS, unitsmask);
1983 make_internal_attr ("*function_units_used", unitsmask, 10);
1985 /* Create an array of ops for each unit. Add an extra unit for the
1986 result_ready_cost function that has the ops of all other units. */
1987 unit_ops = (struct function_unit_op ***)
1988 xmalloc ((num_units + 1) * sizeof (struct function_unit_op **));
1989 unit_num = (struct function_unit **)
1990 xmalloc ((num_units + 1) * sizeof (struct function_unit *));
1992 unit_num[num_units] = unit = (struct function_unit *)
1993 xmalloc (sizeof (struct function_unit));
1994 unit->num = num_units;
1995 unit->num_opclasses = 0;
1997 for (unit = units; unit; unit = unit->next)
1999 unit_num[num_units]->num_opclasses += unit->num_opclasses;
2000 unit_num[unit->num] = unit;
2001 unit_ops[unit->num] = op_array = (struct function_unit_op **)
2002 xmalloc (unit->num_opclasses * sizeof (struct function_unit_op *));
2004 for (op = unit->ops; op; op = op->next)
2005 op_array[op->num] = op;
2008 /* Compose the array of ops for the extra unit. */
2009 unit_ops[num_units] = op_array = (struct function_unit_op **)
2010 xmalloc (unit_num[num_units]->num_opclasses
2011 * sizeof (struct function_unit_op *));
2013 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
2014 memcpy (&op_array[i], unit_ops[unit->num],
2015 unit->num_opclasses * sizeof (struct function_unit_op *));
2017 /* Compute the ready cost function for each unit by computing the
2018 condition for each non-default value. */
2019 for (u = 0; u <= num_units; u++)
2021 rtx orexp;
2022 int value;
2024 unit = unit_num[u];
2025 op_array = unit_ops[unit->num];
2026 num = unit->num_opclasses;
2028 /* Sort the array of ops into increasing ready cost order. */
2029 for (i = 0; i < num; i++)
2030 for (j = num - 1; j > i; j--)
2031 if (op_array[j - 1]->ready < op_array[j]->ready)
2033 op = op_array[j];
2034 op_array[j] = op_array[j - 1];
2035 op_array[j - 1] = op;
2038 /* Determine how many distinct non-default ready cost values there
2039 are. We use a default ready cost value of 1. */
2040 nvalues = 0; value = 1;
2041 for (i = num - 1; i >= 0; i--)
2042 if (op_array[i]->ready > value)
2044 value = op_array[i]->ready;
2045 nvalues++;
2048 if (nvalues == 0)
2049 readycost = make_numeric_value (1);
2050 else
2052 /* Construct the ready cost expression as a COND of each value from
2053 the largest to the smallest. */
2054 readycost = rtx_alloc (COND);
2055 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2056 XEXP (readycost, 1) = make_numeric_value (1);
2058 nvalues = 0;
2059 orexp = false_rtx;
2060 value = op_array[0]->ready;
2061 for (i = 0; i < num; i++)
2063 op = op_array[i];
2064 if (op->ready <= 1)
2065 break;
2066 else if (op->ready == value)
2067 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
2068 else
2070 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2071 XVECEXP (readycost, 0, nvalues * 2 + 1)
2072 = make_numeric_value (value);
2073 nvalues++;
2074 value = op->ready;
2075 orexp = op->condexp;
2078 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2079 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2082 if (u < num_units)
2084 rtx max_blockage = 0, min_blockage = 0;
2086 /* Simplify the readycost expression by only considering insns
2087 that use the unit. */
2088 readycost = simplify_knowing (readycost, unit->condexp);
2090 /* Determine the blockage cost the executing insn (E) given
2091 the candidate insn (C). This is the maximum of the issue
2092 delay, the pipeline delay, and the simultaneity constraint.
2093 Each function_unit_op represents the characteristics of the
2094 candidate insn, so in the expressions below, C is a known
2095 term and E is an unknown term.
2097 We compute the blockage cost for each E for every possible C.
2098 Thus OP represents E, and READYCOST is a list of values for
2099 every possible C.
2101 The issue delay function for C is op->issue_exp and is used to
2102 write the `<name>_unit_conflict_cost' function. Symbolicly
2103 this is "ISSUE-DELAY (E,C)".
2105 The pipeline delay results form the FIFO constraint on the
2106 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2108 The simultaneity constraint is based on how long it takes to
2109 fill the unit given the minimum issue delay. FILL-TIME is the
2110 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2111 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2112 if SIMULTANEITY is non-zero and zero otherwise.
2114 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2116 MAX (ISSUE-DELAY (E,C),
2117 READY-COST (E) - (READY-COST (C) - 1))
2119 and otherwise
2121 MAX (ISSUE-DELAY (E,C),
2122 READY-COST (E) - (READY-COST (C) - 1),
2123 READY-COST (E) - FILL-TIME)
2125 The `<name>_unit_blockage' function is computed by determining
2126 this value for each candidate insn. As these values are
2127 computed, we also compute the upper and lower bounds for
2128 BLOCKAGE (E,*). These are combined to form the function
2129 `<name>_unit_blockage_range'. Finally, the maximum blockage
2130 cost, MAX (BLOCKAGE (*,*)), is computed. */
2132 for (op = unit->ops; op; op = op->next)
2134 rtx blockage = op->issue_exp;
2135 blockage = simplify_knowing (blockage, unit->condexp);
2137 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2138 MIN (BLOCKAGE (E,*)). */
2139 if (max_blockage == 0)
2140 max_blockage = min_blockage = blockage;
2141 else
2143 max_blockage
2144 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2145 blockage),
2146 unit->condexp);
2147 min_blockage
2148 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2149 blockage),
2150 unit->condexp);
2153 /* Make an attribute for use in the blockage function. */
2154 str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2155 "*%s_block_%d", unit->name, op->num);
2156 make_internal_attr (str, blockage, 1);
2159 /* Record MAX (BLOCKAGE (*,*)). */
2161 int unknown;
2162 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2165 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2166 same. If so, the blockage function carries no additional
2167 information and is not written. */
2168 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2169 newexp = simplify_knowing (newexp, unit->condexp);
2170 unit->needs_blockage_function
2171 = (GET_CODE (newexp) != CONST_STRING
2172 || atoi (XSTR (newexp, 0)) != 1);
2174 /* If the all values of BLOCKAGE (E,C) have the same value,
2175 neither blockage function is written. */
2176 unit->needs_range_function
2177 = (unit->needs_blockage_function
2178 || GET_CODE (max_blockage) != CONST_STRING);
2180 if (unit->needs_range_function)
2182 /* Compute the blockage range function and make an attribute
2183 for writing its value. */
2184 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2185 newexp = simplify_knowing (newexp, unit->condexp);
2187 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
2188 "*%s_unit_blockage_range", unit->name);
2189 make_internal_attr (str, newexp, 20);
2192 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2193 "*%s_unit_ready_cost", unit->name);
2195 else
2196 str = "*result_ready_cost";
2198 /* Make an attribute for the ready_cost function. Simplifying
2199 further with simplify_by_exploding doesn't win. */
2200 make_internal_attr (str, readycost, 0);
2203 /* For each unit that requires a conflict cost function, make an attribute
2204 that maps insns to the operation number. */
2205 for (unit = units; unit; unit = unit->next)
2207 rtx caseexp;
2209 if (! unit->needs_conflict_function
2210 && ! unit->needs_blockage_function)
2211 continue;
2213 caseexp = rtx_alloc (COND);
2214 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2216 for (op = unit->ops; op; op = op->next)
2218 /* Make our adjustment to the COND being computed. If we are the
2219 last operation class, place our values into the default of the
2220 COND. */
2221 if (op->num == unit->num_opclasses - 1)
2223 XEXP (caseexp, 1) = make_numeric_value (op->num);
2225 else
2227 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2228 XVECEXP (caseexp, 0, op->num * 2 + 1)
2229 = make_numeric_value (op->num);
2233 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2234 str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2235 "*%s_cases", unit->name);
2236 make_internal_attr (str, caseexp, 1);
2240 /* Simplify EXP given KNOWN_TRUE. */
2242 static rtx
2243 simplify_knowing (exp, known_true)
2244 rtx exp, known_true;
2246 if (GET_CODE (exp) != CONST_STRING)
2248 int unknown = 0, max;
2249 max = max_attr_value (exp, &unknown);
2250 if (! unknown)
2252 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2253 make_numeric_value (max));
2254 exp = simplify_by_exploding (exp);
2257 return exp;
2260 /* Translate the CONST_STRING expressions in X to change the encoding of
2261 value. On input, the value is a bitmask with a one bit for each unit
2262 used; on output, the value is the unit number (zero based) if one
2263 and only one unit is used or the one's compliment of the bitmask. */
2265 static rtx
2266 encode_units_mask (x)
2267 rtx x;
2269 register int i;
2270 register int j;
2271 register enum rtx_code code;
2272 register const char *fmt;
2274 code = GET_CODE (x);
2276 switch (code)
2278 case CONST_STRING:
2279 i = atoi (XSTR (x, 0));
2280 if (i < 0)
2281 /* The sign bit encodes a one's compliment mask. */
2282 abort ();
2283 else if (i != 0 && i == (i & -i))
2284 /* Only one bit is set, so yield that unit number. */
2285 for (j = 0; (i >>= 1) != 0; j++)
2287 else
2288 j = ~i;
2289 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2291 case REG:
2292 case QUEUED:
2293 case CONST_INT:
2294 case CONST_DOUBLE:
2295 case SYMBOL_REF:
2296 case CODE_LABEL:
2297 case PC:
2298 case CC0:
2299 case EQ_ATTR:
2300 return x;
2302 default:
2303 break;
2306 /* Compare the elements. If any pair of corresponding elements
2307 fail to match, return 0 for the whole things. */
2309 fmt = GET_RTX_FORMAT (code);
2310 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2312 switch (fmt[i])
2314 case 'V':
2315 case 'E':
2316 for (j = 0; j < XVECLEN (x, i); j++)
2317 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2318 break;
2320 case 'e':
2321 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2322 break;
2325 return x;
2328 /* Once all attributes and insns have been read and checked, we construct for
2329 each attribute value a list of all the insns that have that value for
2330 the attribute. */
2332 static void
2333 fill_attr (attr)
2334 struct attr_desc *attr;
2336 struct attr_value *av;
2337 struct insn_ent *ie;
2338 struct insn_def *id;
2339 int i;
2340 rtx value;
2342 /* Don't fill constant attributes. The value is independent of
2343 any particular insn. */
2344 if (attr->is_const)
2345 return;
2347 for (id = defs; id; id = id->next)
2349 /* If no value is specified for this insn for this attribute, use the
2350 default. */
2351 value = NULL;
2352 if (XVEC (id->def, id->vec_idx))
2353 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2354 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2355 attr->name))
2356 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2358 if (value == NULL)
2359 av = attr->default_val;
2360 else
2361 av = get_attr_value (value, attr, id->insn_code);
2363 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2364 ie->insn_code = id->insn_code;
2365 ie->insn_index = id->insn_code;
2366 insert_insn_ent (av, ie);
2370 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2371 test that checks relative positions of insns (uses MATCH_DUP or PC).
2372 If so, replace it with what is obtained by passing the expression to
2373 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2374 recursively on each value (including the default value). Otherwise,
2375 return the value returned by NO_ADDRESS_FN applied to EXP. */
2377 static rtx
2378 substitute_address (exp, no_address_fn, address_fn)
2379 rtx exp;
2380 rtx (*no_address_fn) PARAMS ((rtx));
2381 rtx (*address_fn) PARAMS ((rtx));
2383 int i;
2384 rtx newexp;
2386 if (GET_CODE (exp) == COND)
2388 /* See if any tests use addresses. */
2389 address_used = 0;
2390 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2391 walk_attr_value (XVECEXP (exp, 0, i));
2393 if (address_used)
2394 return (*address_fn) (exp);
2396 /* Make a new copy of this COND, replacing each element. */
2397 newexp = rtx_alloc (COND);
2398 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2399 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2401 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2402 XVECEXP (newexp, 0, i + 1)
2403 = substitute_address (XVECEXP (exp, 0, i + 1),
2404 no_address_fn, address_fn);
2407 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2408 no_address_fn, address_fn);
2410 return newexp;
2413 else if (GET_CODE (exp) == IF_THEN_ELSE)
2415 address_used = 0;
2416 walk_attr_value (XEXP (exp, 0));
2417 if (address_used)
2418 return (*address_fn) (exp);
2420 return attr_rtx (IF_THEN_ELSE,
2421 substitute_address (XEXP (exp, 0),
2422 no_address_fn, address_fn),
2423 substitute_address (XEXP (exp, 1),
2424 no_address_fn, address_fn),
2425 substitute_address (XEXP (exp, 2),
2426 no_address_fn, address_fn));
2429 return (*no_address_fn) (exp);
2432 /* Make new attributes from the `length' attribute. The following are made,
2433 each corresponding to a function called from `shorten_branches' or
2434 `get_attr_length':
2436 *insn_default_length This is the length of the insn to be returned
2437 by `get_attr_length' before `shorten_branches'
2438 has been called. In each case where the length
2439 depends on relative addresses, the largest
2440 possible is used. This routine is also used
2441 to compute the initial size of the insn.
2443 *insn_variable_length_p This returns 1 if the insn's length depends
2444 on relative addresses, zero otherwise.
2446 *insn_current_length This is only called when it is known that the
2447 insn has a variable length and returns the
2448 current length, based on relative addresses.
2451 static void
2452 make_length_attrs ()
2454 static const char *new_names[] = {"*insn_default_length",
2455 "*insn_variable_length_p",
2456 "*insn_current_length"};
2457 static rtx (*no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
2458 static rtx (*address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
2459 size_t i;
2460 struct attr_desc *length_attr, *new_attr;
2461 struct attr_value *av, *new_av;
2462 struct insn_ent *ie, *new_ie;
2464 /* See if length attribute is defined. If so, it must be numeric. Make
2465 it special so we don't output anything for it. */
2466 length_attr = find_attr ("length", 0);
2467 if (length_attr == 0)
2468 return;
2470 if (! length_attr->is_numeric)
2471 fatal ("length attribute must be numeric.");
2473 length_attr->is_const = 0;
2474 length_attr->is_special = 1;
2476 /* Make each new attribute, in turn. */
2477 for (i = 0; i < ARRAY_SIZE (new_names); i++)
2479 make_internal_attr (new_names[i],
2480 substitute_address (length_attr->default_val->value,
2481 no_address_fn[i], address_fn[i]),
2483 new_attr = find_attr (new_names[i], 0);
2484 for (av = length_attr->first_value; av; av = av->next)
2485 for (ie = av->first_insn; ie; ie = ie->next)
2487 new_av = get_attr_value (substitute_address (av->value,
2488 no_address_fn[i],
2489 address_fn[i]),
2490 new_attr, ie->insn_code);
2491 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2492 new_ie->insn_code = ie->insn_code;
2493 new_ie->insn_index = ie->insn_index;
2494 insert_insn_ent (new_av, new_ie);
2499 /* Utility functions called from above routine. */
2501 static rtx
2502 identity_fn (exp)
2503 rtx exp;
2505 return exp;
2508 static rtx
2509 zero_fn (exp)
2510 rtx exp ATTRIBUTE_UNUSED;
2512 return make_numeric_value (0);
2515 static rtx
2516 one_fn (exp)
2517 rtx exp ATTRIBUTE_UNUSED;
2519 return make_numeric_value (1);
2522 static rtx
2523 max_fn (exp)
2524 rtx exp;
2526 int unknown;
2527 return make_numeric_value (max_attr_value (exp, &unknown));
2530 static void
2531 write_length_unit_log ()
2533 struct attr_desc *length_attr = find_attr ("length", 0);
2534 struct attr_value *av;
2535 struct insn_ent *ie;
2536 unsigned int length_unit_log, length_or;
2537 int unknown = 0;
2539 if (length_attr == 0)
2540 return;
2541 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2542 for (av = length_attr->first_value; av; av = av->next)
2543 for (ie = av->first_insn; ie; ie = ie->next)
2544 length_or |= or_attr_value (av->value, &unknown);
2546 if (unknown)
2547 length_unit_log = 0;
2548 else
2550 length_or = ~length_or;
2551 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
2552 length_unit_log++;
2554 printf ("int length_unit_log = %u;\n", length_unit_log);
2557 /* Take a COND expression and see if any of the conditions in it can be
2558 simplified. If any are known true or known false for the particular insn
2559 code, the COND can be further simplified.
2561 Also call ourselves on any COND operations that are values of this COND.
2563 We do not modify EXP; rather, we make and return a new rtx. */
2565 static rtx
2566 simplify_cond (exp, insn_code, insn_index)
2567 rtx exp;
2568 int insn_code, insn_index;
2570 int i, j;
2571 /* We store the desired contents here,
2572 then build a new expression if they don't match EXP. */
2573 rtx defval = XEXP (exp, 1);
2574 rtx new_defval = XEXP (exp, 1);
2575 int len = XVECLEN (exp, 0);
2576 rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
2577 int allsame = 1;
2578 char *first_spacer;
2579 rtx ret;
2581 /* This lets us free all storage allocated below, if appropriate. */
2582 first_spacer = (char *) obstack_finish (rtl_obstack);
2584 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
2586 /* See if default value needs simplification. */
2587 if (GET_CODE (defval) == COND)
2588 new_defval = simplify_cond (defval, insn_code, insn_index);
2590 /* Simplify the subexpressions, and see what tests we can get rid of. */
2592 for (i = 0; i < len; i += 2)
2594 rtx newtest, newval;
2596 /* Simplify this test. */
2597 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
2598 tests[i] = newtest;
2600 newval = tests[i + 1];
2601 /* See if this value may need simplification. */
2602 if (GET_CODE (newval) == COND)
2603 newval = simplify_cond (newval, insn_code, insn_index);
2605 /* Look for ways to delete or combine this test. */
2606 if (newtest == true_rtx)
2608 /* If test is true, make this value the default
2609 and discard this + any following tests. */
2610 len = i;
2611 defval = tests[i + 1];
2612 new_defval = newval;
2615 else if (newtest == false_rtx)
2617 /* If test is false, discard it and its value. */
2618 for (j = i; j < len - 2; j++)
2619 tests[j] = tests[j + 2];
2620 len -= 2;
2623 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
2625 /* If this value and the value for the prev test are the same,
2626 merge the tests. */
2628 tests[i - 2]
2629 = insert_right_side (IOR, tests[i - 2], newtest,
2630 insn_code, insn_index);
2632 /* Delete this test/value. */
2633 for (j = i; j < len - 2; j++)
2634 tests[j] = tests[j + 2];
2635 len -= 2;
2638 else
2639 tests[i + 1] = newval;
2642 /* If the last test in a COND has the same value
2643 as the default value, that test isn't needed. */
2645 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
2646 len -= 2;
2648 /* See if we changed anything. */
2649 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2650 allsame = 0;
2651 else
2652 for (i = 0; i < len; i++)
2653 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
2655 allsame = 0;
2656 break;
2659 if (len == 0)
2661 if (GET_CODE (defval) == COND)
2662 ret = simplify_cond (defval, insn_code, insn_index);
2663 else
2664 ret = defval;
2666 else if (allsame)
2667 ret = exp;
2668 else
2670 rtx newexp = rtx_alloc (COND);
2672 XVEC (newexp, 0) = rtvec_alloc (len);
2673 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
2674 XEXP (newexp, 1) = new_defval;
2675 ret = newexp;
2677 free (tests);
2678 return ret;
2681 /* Remove an insn entry from an attribute value. */
2683 static void
2684 remove_insn_ent (av, ie)
2685 struct attr_value *av;
2686 struct insn_ent *ie;
2688 struct insn_ent *previe;
2690 if (av->first_insn == ie)
2691 av->first_insn = ie->next;
2692 else
2694 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2696 previe->next = ie->next;
2699 av->num_insns--;
2700 if (ie->insn_code == -1)
2701 av->has_asm_insn = 0;
2703 num_insn_ents--;
2706 /* Insert an insn entry in an attribute value list. */
2708 static void
2709 insert_insn_ent (av, ie)
2710 struct attr_value *av;
2711 struct insn_ent *ie;
2713 ie->next = av->first_insn;
2714 av->first_insn = ie;
2715 av->num_insns++;
2716 if (ie->insn_code == -1)
2717 av->has_asm_insn = 1;
2719 num_insn_ents++;
2722 /* This is a utility routine to take an expression that is a tree of either
2723 AND or IOR expressions and insert a new term. The new term will be
2724 inserted at the right side of the first node whose code does not match
2725 the root. A new node will be created with the root's code. Its left
2726 side will be the old right side and its right side will be the new
2727 term.
2729 If the `term' is itself a tree, all its leaves will be inserted. */
2731 static rtx
2732 insert_right_side (code, exp, term, insn_code, insn_index)
2733 enum rtx_code code;
2734 rtx exp;
2735 rtx term;
2736 int insn_code, insn_index;
2738 rtx newexp;
2740 /* Avoid consing in some special cases. */
2741 if (code == AND && term == true_rtx)
2742 return exp;
2743 if (code == AND && term == false_rtx)
2744 return false_rtx;
2745 if (code == AND && exp == true_rtx)
2746 return term;
2747 if (code == AND && exp == false_rtx)
2748 return false_rtx;
2749 if (code == IOR && term == true_rtx)
2750 return true_rtx;
2751 if (code == IOR && term == false_rtx)
2752 return exp;
2753 if (code == IOR && exp == true_rtx)
2754 return true_rtx;
2755 if (code == IOR && exp == false_rtx)
2756 return term;
2757 if (attr_equal_p (exp, term))
2758 return exp;
2760 if (GET_CODE (term) == code)
2762 exp = insert_right_side (code, exp, XEXP (term, 0),
2763 insn_code, insn_index);
2764 exp = insert_right_side (code, exp, XEXP (term, 1),
2765 insn_code, insn_index);
2767 return exp;
2770 if (GET_CODE (exp) == code)
2772 rtx new = insert_right_side (code, XEXP (exp, 1),
2773 term, insn_code, insn_index);
2774 if (new != XEXP (exp, 1))
2775 /* Make a copy of this expression and call recursively. */
2776 newexp = attr_rtx (code, XEXP (exp, 0), new);
2777 else
2778 newexp = exp;
2780 else
2782 /* Insert the new term. */
2783 newexp = attr_rtx (code, exp, term);
2786 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2789 /* If we have an expression which AND's a bunch of
2790 (not (eq_attrq "alternative" "n"))
2791 terms, we may have covered all or all but one of the possible alternatives.
2792 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2794 This routine is passed an expression and either AND or IOR. It returns a
2795 bitmask indicating which alternatives are mentioned within EXP. */
2797 static int
2798 compute_alternative_mask (exp, code)
2799 rtx exp;
2800 enum rtx_code code;
2802 const char *string;
2803 if (GET_CODE (exp) == code)
2804 return compute_alternative_mask (XEXP (exp, 0), code)
2805 | compute_alternative_mask (XEXP (exp, 1), code);
2807 else if (code == AND && GET_CODE (exp) == NOT
2808 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2809 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2810 string = XSTR (XEXP (exp, 0), 1);
2812 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2813 && XSTR (exp, 0) == alternative_name)
2814 string = XSTR (exp, 1);
2816 else
2817 return 0;
2819 if (string[1] == 0)
2820 return 1 << (string[0] - '0');
2821 return 1 << atoi (string);
2824 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2825 attribute with the value represented by that bit. */
2827 static rtx
2828 make_alternative_compare (mask)
2829 int mask;
2831 rtx newexp;
2832 int i;
2834 /* Find the bit. */
2835 for (i = 0; (mask & (1 << i)) == 0; i++)
2838 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2839 RTX_UNCHANGING_P (newexp) = 1;
2841 return newexp;
2844 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2845 of "attr" for this insn code. From that value, we can compute a test
2846 showing when the EQ_ATTR will be true. This routine performs that
2847 computation. If a test condition involves an address, we leave the EQ_ATTR
2848 intact because addresses are only valid for the `length' attribute.
2850 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2851 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2853 static rtx
2854 evaluate_eq_attr (exp, value, insn_code, insn_index)
2855 rtx exp;
2856 rtx value;
2857 int insn_code, insn_index;
2859 rtx orexp, andexp;
2860 rtx right;
2861 rtx newexp;
2862 int i;
2864 if (GET_CODE (value) == CONST_STRING)
2866 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2867 newexp = true_rtx;
2868 else
2869 newexp = false_rtx;
2871 else if (GET_CODE (value) == SYMBOL_REF)
2873 char *p;
2874 char string[256];
2876 if (GET_CODE (exp) != EQ_ATTR)
2877 abort ();
2879 if (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 > 256)
2880 abort ();
2882 strcpy (string, XSTR (exp, 0));
2883 strcat (string, "_");
2884 strcat (string, XSTR (exp, 1));
2885 for (p = string; *p; p++)
2886 *p = TOUPPER (*p);
2888 newexp = attr_rtx (EQ, value,
2889 attr_rtx (SYMBOL_REF,
2890 attr_string (string, strlen (string))));
2892 else if (GET_CODE (value) == COND)
2894 /* We construct an IOR of all the cases for which the requested attribute
2895 value is present. Since we start with FALSE, if it is not present,
2896 FALSE will be returned.
2898 Each case is the AND of the NOT's of the previous conditions with the
2899 current condition; in the default case the current condition is TRUE.
2901 For each possible COND value, call ourselves recursively.
2903 The extra TRUE and FALSE expressions will be eliminated by another
2904 call to the simplification routine. */
2906 orexp = false_rtx;
2907 andexp = true_rtx;
2909 if (current_alternative_string)
2910 clear_struct_flag (value);
2912 for (i = 0; i < XVECLEN (value, 0); i += 2)
2914 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2915 insn_code, insn_index);
2917 SIMPLIFY_ALTERNATIVE (this);
2919 right = insert_right_side (AND, andexp, this,
2920 insn_code, insn_index);
2921 right = insert_right_side (AND, right,
2922 evaluate_eq_attr (exp,
2923 XVECEXP (value, 0,
2924 i + 1),
2925 insn_code, insn_index),
2926 insn_code, insn_index);
2927 orexp = insert_right_side (IOR, orexp, right,
2928 insn_code, insn_index);
2930 /* Add this condition into the AND expression. */
2931 newexp = attr_rtx (NOT, this);
2932 andexp = insert_right_side (AND, andexp, newexp,
2933 insn_code, insn_index);
2936 /* Handle the default case. */
2937 right = insert_right_side (AND, andexp,
2938 evaluate_eq_attr (exp, XEXP (value, 1),
2939 insn_code, insn_index),
2940 insn_code, insn_index);
2941 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2943 else
2944 abort ();
2946 /* If uses an address, must return original expression. But set the
2947 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2949 address_used = 0;
2950 walk_attr_value (newexp);
2952 if (address_used)
2954 /* This had `&& current_alternative_string', which seems to be wrong. */
2955 if (! RTX_UNCHANGING_P (exp))
2956 return copy_rtx_unchanging (exp);
2957 return exp;
2959 else
2960 return newexp;
2963 /* This routine is called when an AND of a term with a tree of AND's is
2964 encountered. If the term or its complement is present in the tree, it
2965 can be replaced with TRUE or FALSE, respectively.
2967 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2968 be true and hence are complementary.
2970 There is one special case: If we see
2971 (and (not (eq_attr "att" "v1"))
2972 (eq_attr "att" "v2"))
2973 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2974 replace the term, not anything in the AND tree. So we pass a pointer to
2975 the term. */
2977 static rtx
2978 simplify_and_tree (exp, pterm, insn_code, insn_index)
2979 rtx exp;
2980 rtx *pterm;
2981 int insn_code, insn_index;
2983 rtx left, right;
2984 rtx newexp;
2985 rtx temp;
2986 int left_eliminates_term, right_eliminates_term;
2988 if (GET_CODE (exp) == AND)
2990 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2991 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2992 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2994 newexp = attr_rtx (GET_CODE (exp), left, right);
2996 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3000 else if (GET_CODE (exp) == IOR)
3002 /* For the IOR case, we do the same as above, except that we can
3003 only eliminate `term' if both sides of the IOR would do so. */
3004 temp = *pterm;
3005 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3006 left_eliminates_term = (temp == true_rtx);
3008 temp = *pterm;
3009 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3010 right_eliminates_term = (temp == true_rtx);
3012 if (left_eliminates_term && right_eliminates_term)
3013 *pterm = true_rtx;
3015 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3017 newexp = attr_rtx (GET_CODE (exp), left, right);
3019 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3023 /* Check for simplifications. Do some extra checking here since this
3024 routine is called so many times. */
3026 if (exp == *pterm)
3027 return true_rtx;
3029 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
3030 return false_rtx;
3032 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
3033 return false_rtx;
3035 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
3037 if (XSTR (exp, 0) != XSTR (*pterm, 0))
3038 return exp;
3040 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
3041 return true_rtx;
3042 else
3043 return false_rtx;
3046 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3047 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3049 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3050 return exp;
3052 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3053 return false_rtx;
3054 else
3055 return true_rtx;
3058 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3059 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3061 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3062 return exp;
3064 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3065 return false_rtx;
3066 else
3067 *pterm = true_rtx;
3070 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3072 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
3073 return true_rtx;
3076 else if (GET_CODE (exp) == NOT)
3078 if (attr_equal_p (XEXP (exp, 0), *pterm))
3079 return false_rtx;
3082 else if (GET_CODE (*pterm) == NOT)
3084 if (attr_equal_p (XEXP (*pterm, 0), exp))
3085 return false_rtx;
3088 else if (attr_equal_p (exp, *pterm))
3089 return true_rtx;
3091 return exp;
3094 /* Similar to `simplify_and_tree', but for IOR trees. */
3096 static rtx
3097 simplify_or_tree (exp, pterm, insn_code, insn_index)
3098 rtx exp;
3099 rtx *pterm;
3100 int insn_code, insn_index;
3102 rtx left, right;
3103 rtx newexp;
3104 rtx temp;
3105 int left_eliminates_term, right_eliminates_term;
3107 if (GET_CODE (exp) == IOR)
3109 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
3110 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3111 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3113 newexp = attr_rtx (GET_CODE (exp), left, right);
3115 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3119 else if (GET_CODE (exp) == AND)
3121 /* For the AND case, we do the same as above, except that we can
3122 only eliminate `term' if both sides of the AND would do so. */
3123 temp = *pterm;
3124 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3125 left_eliminates_term = (temp == false_rtx);
3127 temp = *pterm;
3128 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3129 right_eliminates_term = (temp == false_rtx);
3131 if (left_eliminates_term && right_eliminates_term)
3132 *pterm = false_rtx;
3134 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3136 newexp = attr_rtx (GET_CODE (exp), left, right);
3138 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3142 if (attr_equal_p (exp, *pterm))
3143 return false_rtx;
3145 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
3146 return true_rtx;
3148 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
3149 return true_rtx;
3151 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3152 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3153 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3154 *pterm = false_rtx;
3156 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3157 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3158 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3159 return false_rtx;
3161 return exp;
3163 /* Compute approximate cost of the expression. Used to decide whether
3164 expression is cheap enought for inline. */
3165 static int
3166 attr_rtx_cost (x)
3167 rtx x;
3169 int cost = 0;
3170 enum rtx_code code;
3171 if (!x)
3172 return 0;
3173 code = GET_CODE (x);
3174 switch (code)
3176 case MATCH_OPERAND:
3177 if (XSTR (x, 1)[0])
3178 return 10;
3179 else
3180 return 0;
3181 case EQ_ATTR:
3182 /* Alternatives don't result into function call. */
3183 if (!strcmp (XSTR (x, 0), "alternative"))
3184 return 0;
3185 else
3186 return 5;
3187 default:
3189 int i, j;
3190 const char *fmt = GET_RTX_FORMAT (code);
3191 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3193 switch (fmt[i])
3195 case 'V':
3196 case 'E':
3197 for (j = 0; j < XVECLEN (x, i); j++)
3198 cost += attr_rtx_cost (XVECEXP (x, i, j));
3199 break;
3200 case 'e':
3201 cost += attr_rtx_cost (XEXP (x, i));
3202 break;
3206 break;
3208 return cost;
3212 /* Simplify test expression and use temporary obstack in order to avoid
3213 memory bloat. Use RTX_UNCHANGING_P to avoid unnecesary simplifications
3214 and avoid unnecesary copying if possible. */
3216 static rtx
3217 simplify_test_exp_in_temp (exp, insn_code, insn_index)
3218 rtx exp;
3219 int insn_code, insn_index;
3221 rtx x;
3222 struct obstack *old;
3223 if (RTX_UNCHANGING_P (exp))
3224 return exp;
3225 old = rtl_obstack;
3226 rtl_obstack = temp_obstack;
3227 x = simplify_test_exp (exp, insn_code, insn_index);
3228 rtl_obstack = old;
3229 if (x == exp || rtl_obstack == temp_obstack)
3230 return x;
3231 return attr_copy_rtx (x);
3234 /* Given an expression, see if it can be simplified for a particular insn
3235 code based on the values of other attributes being tested. This can
3236 eliminate nested get_attr_... calls.
3238 Note that if an endless recursion is specified in the patterns, the
3239 optimization will loop. However, it will do so in precisely the cases where
3240 an infinite recursion loop could occur during compilation. It's better that
3241 it occurs here! */
3243 static rtx
3244 simplify_test_exp (exp, insn_code, insn_index)
3245 rtx exp;
3246 int insn_code, insn_index;
3248 rtx left, right;
3249 struct attr_desc *attr;
3250 struct attr_value *av;
3251 struct insn_ent *ie;
3252 int i;
3253 rtx newexp = exp;
3255 /* Don't re-simplify something we already simplified. */
3256 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3257 return exp;
3259 switch (GET_CODE (exp))
3261 case AND:
3262 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3263 SIMPLIFY_ALTERNATIVE (left);
3264 if (left == false_rtx)
3265 return false_rtx;
3266 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3267 SIMPLIFY_ALTERNATIVE (right);
3268 if (left == false_rtx)
3269 return false_rtx;
3271 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3272 present on both sides, apply the distributive law since this will
3273 yield simplifications. */
3274 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3275 && compute_alternative_mask (left, IOR)
3276 && compute_alternative_mask (right, IOR))
3278 if (GET_CODE (left) == IOR)
3280 rtx tem = left;
3281 left = right;
3282 right = tem;
3285 newexp = attr_rtx (IOR,
3286 attr_rtx (AND, left, XEXP (right, 0)),
3287 attr_rtx (AND, left, XEXP (right, 1)));
3289 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3292 /* Try with the term on both sides. */
3293 right = simplify_and_tree (right, &left, insn_code, insn_index);
3294 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3295 left = simplify_and_tree (left, &right, insn_code, insn_index);
3297 if (left == false_rtx || right == false_rtx)
3298 return false_rtx;
3299 else if (left == true_rtx)
3301 return right;
3303 else if (right == true_rtx)
3305 return left;
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) == AND
3312 || (GET_CODE (left) == NOT
3313 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3314 && XSTR (XEXP (left, 0), 0) == alternative_name)
3315 || GET_CODE (right) == AND
3316 || (GET_CODE (right) == NOT
3317 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3318 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3320 i = compute_alternative_mask (exp, AND);
3321 if (i & ~insn_alternatives[insn_code])
3322 fatal ("Invalid alternative specified for pattern number %d",
3323 insn_index);
3325 /* If all alternatives are excluded, this is false. */
3326 i ^= insn_alternatives[insn_code];
3327 if (i == 0)
3328 return false_rtx;
3329 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3331 /* If just one excluded, AND a comparison with that one to the
3332 front of the tree. The others will be eliminated by
3333 optimization. We do not want to do this if the insn has one
3334 alternative and we have tested none of them! */
3335 left = make_alternative_compare (i);
3336 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3337 newexp = attr_rtx (AND, left, right);
3339 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3343 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3345 newexp = attr_rtx (AND, left, right);
3346 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3348 break;
3350 case IOR:
3351 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3352 SIMPLIFY_ALTERNATIVE (left);
3353 if (left == true_rtx)
3354 return true_rtx;
3355 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3356 SIMPLIFY_ALTERNATIVE (right);
3357 if (right == true_rtx)
3358 return true_rtx;
3360 right = simplify_or_tree (right, &left, insn_code, insn_index);
3361 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3362 left = simplify_or_tree (left, &right, insn_code, insn_index);
3364 if (right == true_rtx || left == true_rtx)
3365 return true_rtx;
3366 else if (left == false_rtx)
3368 return right;
3370 else if (right == false_rtx)
3372 return left;
3375 /* Test for simple cases where the distributive law is useful. I.e.,
3376 convert (ior (and (x) (y))
3377 (and (x) (z)))
3378 to (and (x)
3379 (ior (y) (z)))
3382 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3383 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3385 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3387 left = XEXP (left, 0);
3388 right = newexp;
3389 newexp = attr_rtx (AND, left, right);
3390 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3393 /* See if all or all but one of the insn's alternatives are specified
3394 in this tree. Optimize if so. */
3396 else if (insn_code >= 0
3397 && (GET_CODE (left) == IOR
3398 || (GET_CODE (left) == EQ_ATTR
3399 && XSTR (left, 0) == alternative_name)
3400 || GET_CODE (right) == IOR
3401 || (GET_CODE (right) == EQ_ATTR
3402 && XSTR (right, 0) == alternative_name)))
3404 i = compute_alternative_mask (exp, IOR);
3405 if (i & ~insn_alternatives[insn_code])
3406 fatal ("Invalid alternative specified for pattern number %d",
3407 insn_index);
3409 /* If all alternatives are included, this is true. */
3410 i ^= insn_alternatives[insn_code];
3411 if (i == 0)
3412 return true_rtx;
3413 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3415 /* If just one excluded, IOR a comparison with that one to the
3416 front of the tree. The others will be eliminated by
3417 optimization. We do not want to do this if the insn has one
3418 alternative and we have tested none of them! */
3419 left = make_alternative_compare (i);
3420 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3421 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3423 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3427 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3429 newexp = attr_rtx (IOR, left, right);
3430 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3432 break;
3434 case NOT:
3435 if (GET_CODE (XEXP (exp, 0)) == NOT)
3437 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3438 insn_code, insn_index);
3439 SIMPLIFY_ALTERNATIVE (left);
3440 return left;
3443 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3444 SIMPLIFY_ALTERNATIVE (left);
3445 if (GET_CODE (left) == NOT)
3446 return XEXP (left, 0);
3448 if (left == false_rtx)
3449 return true_rtx;
3450 else if (left == true_rtx)
3451 return false_rtx;
3453 /* Try to apply De`Morgan's laws. */
3454 else if (GET_CODE (left) == IOR)
3456 newexp = attr_rtx (AND,
3457 attr_rtx (NOT, XEXP (left, 0)),
3458 attr_rtx (NOT, XEXP (left, 1)));
3460 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3462 else if (GET_CODE (left) == AND)
3464 newexp = attr_rtx (IOR,
3465 attr_rtx (NOT, XEXP (left, 0)),
3466 attr_rtx (NOT, XEXP (left, 1)));
3468 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3470 else if (left != XEXP (exp, 0))
3472 newexp = attr_rtx (NOT, left);
3474 break;
3476 case EQ_ATTR:
3477 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3478 return (XSTR (exp, 1) == current_alternative_string
3479 ? true_rtx : false_rtx);
3481 /* Look at the value for this insn code in the specified attribute.
3482 We normally can replace this comparison with the condition that
3483 would give this insn the values being tested for. */
3484 if (XSTR (exp, 0) != alternative_name
3485 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3486 for (av = attr->first_value; av; av = av->next)
3487 for (ie = av->first_insn; ie; ie = ie->next)
3488 if (ie->insn_code == insn_code)
3490 rtx x;
3491 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3492 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
3493 if (attr_rtx_cost(x) < 20)
3494 return x;
3496 break;
3498 default:
3499 break;
3502 /* We have already simplified this expression. Simplifying it again
3503 won't buy anything unless we weren't given a valid insn code
3504 to process (i.e., we are canonicalizing something.). */
3505 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3506 && ! RTX_UNCHANGING_P (newexp))
3507 return copy_rtx_unchanging (newexp);
3509 return newexp;
3512 /* Optimize the attribute lists by seeing if we can determine conditional
3513 values from the known values of other attributes. This will save subroutine
3514 calls during the compilation. */
3516 static void
3517 optimize_attrs ()
3519 struct attr_desc *attr;
3520 struct attr_value *av;
3521 struct insn_ent *ie;
3522 rtx newexp;
3523 int i;
3524 struct attr_value_list
3526 struct attr_value *av;
3527 struct insn_ent *ie;
3528 struct attr_desc *attr;
3529 struct attr_value_list *next;
3531 struct attr_value_list **insn_code_values;
3532 struct attr_value_list *ivbuf;
3533 struct attr_value_list *iv;
3535 /* For each insn code, make a list of all the insn_ent's for it,
3536 for all values for all attributes. */
3538 if (num_insn_ents == 0)
3539 return;
3541 /* Make 2 extra elements, for "code" values -2 and -1. */
3542 insn_code_values
3543 = (struct attr_value_list **) xmalloc ((insn_code_number + 2)
3544 * sizeof (struct attr_value_list *));
3545 memset ((char *) insn_code_values, 0,
3546 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3548 /* Offset the table address so we can index by -2 or -1. */
3549 insn_code_values += 2;
3551 iv = ivbuf = ((struct attr_value_list *)
3552 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3554 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3555 for (attr = attrs[i]; attr; attr = attr->next)
3556 for (av = attr->first_value; av; av = av->next)
3557 for (ie = av->first_insn; ie; ie = ie->next)
3559 iv->attr = attr;
3560 iv->av = av;
3561 iv->ie = ie;
3562 iv->next = insn_code_values[ie->insn_code];
3563 insn_code_values[ie->insn_code] = iv;
3564 iv++;
3567 /* Sanity check on num_insn_ents. */
3568 if (iv != ivbuf + num_insn_ents)
3569 abort ();
3571 /* Process one insn code at a time. */
3572 for (i = -2; i < insn_code_number; i++)
3574 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3575 We use it to mean "already simplified for this insn". */
3576 for (iv = insn_code_values[i]; iv; iv = iv->next)
3577 clear_struct_flag (iv->av->value);
3579 for (iv = insn_code_values[i]; iv; iv = iv->next)
3581 struct obstack *old = rtl_obstack;
3583 attr = iv->attr;
3584 av = iv->av;
3585 ie = iv->ie;
3586 if (GET_CODE (av->value) != COND)
3587 continue;
3589 rtl_obstack = temp_obstack;
3590 #if 0 /* This was intended as a speed up, but it was slower. */
3591 if (insn_n_alternatives[ie->insn_code] > 6
3592 && count_sub_rtxs (av->value, 200) >= 200)
3593 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3594 ie->insn_index);
3595 else
3596 #endif
3597 newexp = av->value;
3598 while (GET_CODE (newexp) == COND)
3600 rtx newexp2 = simplify_cond (newexp, ie->insn_code,
3601 ie->insn_index);
3602 if (newexp2 == newexp)
3603 break;
3604 newexp = newexp2;
3607 rtl_obstack = old;
3608 if (newexp != av->value)
3610 newexp = attr_copy_rtx (newexp);
3611 remove_insn_ent (av, ie);
3612 av = get_attr_value (newexp, attr, ie->insn_code);
3613 iv->av = av;
3614 insert_insn_ent (av, ie);
3619 free (ivbuf);
3620 free (insn_code_values - 2);
3623 #if 0
3624 static rtx
3625 simplify_by_alternatives (exp, insn_code, insn_index)
3626 rtx exp;
3627 int insn_code, insn_index;
3629 int i;
3630 int len = insn_n_alternatives[insn_code];
3631 rtx newexp = rtx_alloc (COND);
3632 rtx ultimate;
3634 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3636 /* It will not matter what value we use as the default value
3637 of the new COND, since that default will never be used.
3638 Choose something of the right type. */
3639 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3640 ultimate = XEXP (ultimate, 1);
3641 XEXP (newexp, 1) = ultimate;
3643 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3645 current_alternative_string = attr_numeral (i);
3646 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3647 XVECEXP (newexp, 0, i * 2 + 1)
3648 = simplify_cond (exp, insn_code, insn_index);
3651 current_alternative_string = 0;
3652 return simplify_cond (newexp, insn_code, insn_index);
3654 #endif
3656 /* If EXP is a suitable expression, reorganize it by constructing an
3657 equivalent expression that is a COND with the tests being all combinations
3658 of attribute values and the values being simple constants. */
3660 static rtx
3661 simplify_by_exploding (exp)
3662 rtx exp;
3664 rtx list = 0, link, condexp, defval = NULL_RTX;
3665 struct dimension *space;
3666 rtx *condtest, *condval;
3667 int i, j, total, ndim = 0;
3668 int most_tests, num_marks, new_marks;
3669 rtx ret;
3671 /* Locate all the EQ_ATTR expressions. */
3672 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3674 unmark_used_attributes (list, 0, 0);
3675 return exp;
3678 /* Create an attribute space from the list of used attributes. For each
3679 dimension in the attribute space, record the attribute, list of values
3680 used, and number of values used. Add members to the list of values to
3681 cover the domain of the attribute. This makes the expanded COND form
3682 order independent. */
3684 space = (struct dimension *) xmalloc (ndim * sizeof (struct dimension));
3686 total = 1;
3687 for (ndim = 0; list; ndim++)
3689 /* Pull the first attribute value from the list and record that
3690 attribute as another dimension in the attribute space. */
3691 const char *name = XSTR (XEXP (list, 0), 0);
3692 rtx *prev;
3694 if ((space[ndim].attr = find_attr (name, 0)) == 0
3695 || space[ndim].attr->is_numeric)
3697 unmark_used_attributes (list, space, ndim);
3698 return exp;
3701 /* Add all remaining attribute values that refer to this attribute. */
3702 space[ndim].num_values = 0;
3703 space[ndim].values = 0;
3704 prev = &list;
3705 for (link = list; link; link = *prev)
3706 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3708 space[ndim].num_values++;
3709 *prev = XEXP (link, 1);
3710 XEXP (link, 1) = space[ndim].values;
3711 space[ndim].values = link;
3713 else
3714 prev = &XEXP (link, 1);
3716 /* Add sufficient members to the list of values to make the list
3717 mutually exclusive and record the total size of the attribute
3718 space. */
3719 total *= add_values_to_cover (&space[ndim]);
3722 /* Sort the attribute space so that the attributes go from non-constant
3723 to constant and from most values to least values. */
3724 for (i = 0; i < ndim; i++)
3725 for (j = ndim - 1; j > i; j--)
3726 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3727 || space[j-1].num_values < space[j].num_values)
3729 struct dimension tmp;
3730 tmp = space[j];
3731 space[j] = space[j - 1];
3732 space[j - 1] = tmp;
3735 /* Establish the initial current value. */
3736 for (i = 0; i < ndim; i++)
3737 space[i].current_value = space[i].values;
3739 condtest = (rtx *) xmalloc (total * sizeof (rtx));
3740 condval = (rtx *) xmalloc (total * sizeof (rtx));
3742 /* Expand the tests and values by iterating over all values in the
3743 attribute space. */
3744 for (i = 0;; i++)
3746 condtest[i] = test_for_current_value (space, ndim);
3747 condval[i] = simplify_with_current_value (exp, space, ndim);
3748 if (! increment_current_value (space, ndim))
3749 break;
3751 if (i != total - 1)
3752 abort ();
3754 /* We are now finished with the original expression. */
3755 unmark_used_attributes (0, space, ndim);
3756 free (space);
3758 /* Find the most used constant value and make that the default. */
3759 most_tests = -1;
3760 for (i = num_marks = 0; i < total; i++)
3761 if (GET_CODE (condval[i]) == CONST_STRING
3762 && ! MEM_VOLATILE_P (condval[i]))
3764 /* Mark the unmarked constant value and count how many are marked. */
3765 MEM_VOLATILE_P (condval[i]) = 1;
3766 for (j = new_marks = 0; j < total; j++)
3767 if (GET_CODE (condval[j]) == CONST_STRING
3768 && MEM_VOLATILE_P (condval[j]))
3769 new_marks++;
3770 if (new_marks - num_marks > most_tests)
3772 most_tests = new_marks - num_marks;
3773 defval = condval[i];
3775 num_marks = new_marks;
3777 /* Clear all the marks. */
3778 for (i = 0; i < total; i++)
3779 MEM_VOLATILE_P (condval[i]) = 0;
3781 /* Give up if nothing is constant. */
3782 if (num_marks == 0)
3783 ret = exp;
3785 /* If all values are the default, use that. */
3786 else if (total == most_tests)
3787 ret = defval;
3789 /* Make a COND with the most common constant value the default. (A more
3790 complex method where tests with the same value were combined didn't
3791 seem to improve things.) */
3792 else
3794 condexp = rtx_alloc (COND);
3795 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3796 XEXP (condexp, 1) = defval;
3797 for (i = j = 0; i < total; i++)
3798 if (condval[i] != defval)
3800 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3801 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3802 j++;
3804 ret = condexp;
3806 free (condtest);
3807 free (condval);
3808 return ret;
3811 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3812 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3813 tests have known value. */
3815 static int
3816 find_and_mark_used_attributes (exp, terms, nterms)
3817 rtx exp, *terms;
3818 int *nterms;
3820 int i;
3822 switch (GET_CODE (exp))
3824 case EQ_ATTR:
3825 if (! MEM_VOLATILE_P (exp))
3827 rtx link = rtx_alloc (EXPR_LIST);
3828 XEXP (link, 0) = exp;
3829 XEXP (link, 1) = *terms;
3830 *terms = link;
3831 *nterms += 1;
3832 MEM_VOLATILE_P (exp) = 1;
3834 return 1;
3836 case CONST_STRING:
3837 case CONST_INT:
3838 return 1;
3840 case IF_THEN_ELSE:
3841 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3842 return 0;
3843 case IOR:
3844 case AND:
3845 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3846 return 0;
3847 case NOT:
3848 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3849 return 0;
3850 return 1;
3852 case COND:
3853 for (i = 0; i < XVECLEN (exp, 0); i++)
3854 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3855 return 0;
3856 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3857 return 0;
3858 return 1;
3860 default:
3861 return 0;
3865 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3866 in the values of the NDIM-dimensional attribute space SPACE. */
3868 static void
3869 unmark_used_attributes (list, space, ndim)
3870 rtx list;
3871 struct dimension *space;
3872 int ndim;
3874 rtx link, exp;
3875 int i;
3877 for (i = 0; i < ndim; i++)
3878 unmark_used_attributes (space[i].values, 0, 0);
3880 for (link = list; link; link = XEXP (link, 1))
3882 exp = XEXP (link, 0);
3883 if (GET_CODE (exp) == EQ_ATTR)
3884 MEM_VOLATILE_P (exp) = 0;
3888 /* Update the attribute dimension DIM so that all values of the attribute
3889 are tested. Return the updated number of values. */
3891 static int
3892 add_values_to_cover (dim)
3893 struct dimension *dim;
3895 struct attr_value *av;
3896 rtx exp, link, *prev;
3897 int nalt = 0;
3899 for (av = dim->attr->first_value; av; av = av->next)
3900 if (GET_CODE (av->value) == CONST_STRING)
3901 nalt++;
3903 if (nalt < dim->num_values)
3904 abort ();
3905 else if (nalt == dim->num_values)
3906 /* OK. */
3908 else if (nalt * 2 < dim->num_values * 3)
3910 /* Most all the values of the attribute are used, so add all the unused
3911 values. */
3912 prev = &dim->values;
3913 for (link = dim->values; link; link = *prev)
3914 prev = &XEXP (link, 1);
3916 for (av = dim->attr->first_value; av; av = av->next)
3917 if (GET_CODE (av->value) == CONST_STRING)
3919 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3920 if (MEM_VOLATILE_P (exp))
3921 continue;
3923 link = rtx_alloc (EXPR_LIST);
3924 XEXP (link, 0) = exp;
3925 XEXP (link, 1) = 0;
3926 *prev = link;
3927 prev = &XEXP (link, 1);
3929 dim->num_values = nalt;
3931 else
3933 rtx orexp = false_rtx;
3935 /* Very few values are used, so compute a mutually exclusive
3936 expression. (We could do this for numeric values if that becomes
3937 important.) */
3938 prev = &dim->values;
3939 for (link = dim->values; link; link = *prev)
3941 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3942 prev = &XEXP (link, 1);
3944 link = rtx_alloc (EXPR_LIST);
3945 XEXP (link, 0) = attr_rtx (NOT, orexp);
3946 XEXP (link, 1) = 0;
3947 *prev = link;
3948 dim->num_values++;
3950 return dim->num_values;
3953 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3954 and return FALSE if the increment overflowed. */
3956 static int
3957 increment_current_value (space, ndim)
3958 struct dimension *space;
3959 int ndim;
3961 int i;
3963 for (i = ndim - 1; i >= 0; i--)
3965 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3966 space[i].current_value = space[i].values;
3967 else
3968 return 1;
3970 return 0;
3973 /* Construct an expression corresponding to the current value for the
3974 NDIM-dimensional attribute space SPACE. */
3976 static rtx
3977 test_for_current_value (space, ndim)
3978 struct dimension *space;
3979 int ndim;
3981 int i;
3982 rtx exp = true_rtx;
3984 for (i = 0; i < ndim; i++)
3985 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3986 -2, -2);
3988 return exp;
3991 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3992 set the corresponding EQ_ATTR expressions to that value and reduce
3993 the expression EXP as much as possible. On input [and output], all
3994 known EQ_ATTR expressions are set to FALSE. */
3996 static rtx
3997 simplify_with_current_value (exp, space, ndim)
3998 rtx exp;
3999 struct dimension *space;
4000 int ndim;
4002 int i;
4003 rtx x;
4005 /* Mark each current value as TRUE. */
4006 for (i = 0; i < ndim; i++)
4008 x = XEXP (space[i].current_value, 0);
4009 if (GET_CODE (x) == EQ_ATTR)
4010 MEM_VOLATILE_P (x) = 0;
4013 exp = simplify_with_current_value_aux (exp);
4015 /* Change each current value back to FALSE. */
4016 for (i = 0; i < ndim; i++)
4018 x = XEXP (space[i].current_value, 0);
4019 if (GET_CODE (x) == EQ_ATTR)
4020 MEM_VOLATILE_P (x) = 1;
4023 return exp;
4026 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
4027 all EQ_ATTR expressions. */
4029 static rtx
4030 simplify_with_current_value_aux (exp)
4031 rtx exp;
4033 register int i;
4034 rtx cond;
4036 switch (GET_CODE (exp))
4038 case EQ_ATTR:
4039 if (MEM_VOLATILE_P (exp))
4040 return false_rtx;
4041 else
4042 return true_rtx;
4043 case CONST_STRING:
4044 case CONST_INT:
4045 return exp;
4047 case IF_THEN_ELSE:
4048 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4049 if (cond == true_rtx)
4050 return simplify_with_current_value_aux (XEXP (exp, 1));
4051 else if (cond == false_rtx)
4052 return simplify_with_current_value_aux (XEXP (exp, 2));
4053 else
4054 return attr_rtx (IF_THEN_ELSE, cond,
4055 simplify_with_current_value_aux (XEXP (exp, 1)),
4056 simplify_with_current_value_aux (XEXP (exp, 2)));
4058 case IOR:
4059 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4060 if (cond == true_rtx)
4061 return cond;
4062 else if (cond == false_rtx)
4063 return simplify_with_current_value_aux (XEXP (exp, 0));
4064 else
4065 return attr_rtx (IOR, cond,
4066 simplify_with_current_value_aux (XEXP (exp, 0)));
4068 case AND:
4069 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4070 if (cond == true_rtx)
4071 return simplify_with_current_value_aux (XEXP (exp, 0));
4072 else if (cond == false_rtx)
4073 return cond;
4074 else
4075 return attr_rtx (AND, cond,
4076 simplify_with_current_value_aux (XEXP (exp, 0)));
4078 case NOT:
4079 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4080 if (cond == true_rtx)
4081 return false_rtx;
4082 else if (cond == false_rtx)
4083 return true_rtx;
4084 else
4085 return attr_rtx (NOT, cond);
4087 case COND:
4088 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4090 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
4091 if (cond == true_rtx)
4092 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4093 else if (cond == false_rtx)
4094 continue;
4095 else
4096 abort (); /* With all EQ_ATTR's of known value, a case should
4097 have been selected. */
4099 return simplify_with_current_value_aux (XEXP (exp, 1));
4101 default:
4102 abort ();
4106 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4108 static void
4109 clear_struct_flag (x)
4110 rtx x;
4112 register int i;
4113 register int j;
4114 register enum rtx_code code;
4115 register const char *fmt;
4117 MEM_IN_STRUCT_P (x) = 0;
4118 if (RTX_UNCHANGING_P (x))
4119 return;
4121 code = GET_CODE (x);
4123 switch (code)
4125 case REG:
4126 case QUEUED:
4127 case CONST_INT:
4128 case CONST_DOUBLE:
4129 case SYMBOL_REF:
4130 case CODE_LABEL:
4131 case PC:
4132 case CC0:
4133 case EQ_ATTR:
4134 case ATTR_FLAG:
4135 return;
4137 default:
4138 break;
4141 /* Compare the elements. If any pair of corresponding elements
4142 fail to match, return 0 for the whole things. */
4144 fmt = GET_RTX_FORMAT (code);
4145 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4147 switch (fmt[i])
4149 case 'V':
4150 case 'E':
4151 for (j = 0; j < XVECLEN (x, i); j++)
4152 clear_struct_flag (XVECEXP (x, i, j));
4153 break;
4155 case 'e':
4156 clear_struct_flag (XEXP (x, i));
4157 break;
4162 /* Return the number of RTX objects making up the expression X.
4163 But if we count more than MAX objects, stop counting. */
4165 static int
4166 count_sub_rtxs (x, max)
4167 rtx x;
4168 int max;
4170 register int i;
4171 register int j;
4172 register enum rtx_code code;
4173 register const char *fmt;
4174 int total = 0;
4176 code = GET_CODE (x);
4178 switch (code)
4180 case REG:
4181 case QUEUED:
4182 case CONST_INT:
4183 case CONST_DOUBLE:
4184 case SYMBOL_REF:
4185 case CODE_LABEL:
4186 case PC:
4187 case CC0:
4188 case EQ_ATTR:
4189 case ATTR_FLAG:
4190 return 1;
4192 default:
4193 break;
4196 /* Compare the elements. If any pair of corresponding elements
4197 fail to match, return 0 for the whole things. */
4199 fmt = GET_RTX_FORMAT (code);
4200 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4202 if (total >= max)
4203 return total;
4205 switch (fmt[i])
4207 case 'V':
4208 case 'E':
4209 for (j = 0; j < XVECLEN (x, i); j++)
4210 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4211 break;
4213 case 'e':
4214 total += count_sub_rtxs (XEXP (x, i), max);
4215 break;
4218 return total;
4222 /* Create table entries for DEFINE_ATTR. */
4224 static void
4225 gen_attr (exp, lineno)
4226 rtx exp;
4227 int lineno;
4229 struct attr_desc *attr;
4230 struct attr_value *av;
4231 const char *name_ptr;
4232 char *p;
4234 /* Make a new attribute structure. Check for duplicate by looking at
4235 attr->default_val, since it is initialized by this routine. */
4236 attr = find_attr (XSTR (exp, 0), 1);
4237 if (attr->default_val)
4239 message_with_line (lineno, "duplicate definition for attribute %s",
4240 attr->name);
4241 message_with_line (attr->lineno, "previous definition");
4242 have_error = 1;
4243 return;
4245 attr->lineno = lineno;
4247 if (*XSTR (exp, 1) == '\0')
4248 attr->is_numeric = 1;
4249 else
4251 name_ptr = XSTR (exp, 1);
4252 while ((p = next_comma_elt (&name_ptr)) != NULL)
4254 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4255 av->value = attr_rtx (CONST_STRING, p);
4256 av->next = attr->first_value;
4257 attr->first_value = av;
4258 av->first_insn = NULL;
4259 av->num_insns = 0;
4260 av->has_asm_insn = 0;
4264 if (GET_CODE (XEXP (exp, 2)) == CONST)
4266 attr->is_const = 1;
4267 if (attr->is_numeric)
4269 message_with_line (lineno,
4270 "constant attributes may not take numeric values");
4271 have_error = 1;
4274 /* Get rid of the CONST node. It is allowed only at top-level. */
4275 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4278 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4280 message_with_line (lineno,
4281 "`length' attribute must take numeric values");
4282 have_error = 1;
4285 /* Set up the default value. */
4286 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4287 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4290 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4291 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4292 number of alternatives as this should be checked elsewhere. */
4294 static int
4295 count_alternatives (exp)
4296 rtx exp;
4298 int i, j, n;
4299 const char *fmt;
4301 if (GET_CODE (exp) == MATCH_OPERAND)
4302 return n_comma_elts (XSTR (exp, 2));
4304 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4305 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4306 switch (*fmt++)
4308 case 'e':
4309 case 'u':
4310 n = count_alternatives (XEXP (exp, i));
4311 if (n)
4312 return n;
4313 break;
4315 case 'E':
4316 case 'V':
4317 if (XVEC (exp, i) != NULL)
4318 for (j = 0; j < XVECLEN (exp, i); j++)
4320 n = count_alternatives (XVECEXP (exp, i, j));
4321 if (n)
4322 return n;
4326 return 0;
4329 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4330 `alternative' attribute. */
4332 static int
4333 compares_alternatives_p (exp)
4334 rtx exp;
4336 int i, j;
4337 const char *fmt;
4339 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4340 return 1;
4342 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4343 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4344 switch (*fmt++)
4346 case 'e':
4347 case 'u':
4348 if (compares_alternatives_p (XEXP (exp, i)))
4349 return 1;
4350 break;
4352 case 'E':
4353 for (j = 0; j < XVECLEN (exp, i); j++)
4354 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4355 return 1;
4356 break;
4359 return 0;
4362 /* Returns non-zero is INNER is contained in EXP. */
4364 static int
4365 contained_in_p (inner, exp)
4366 rtx inner;
4367 rtx exp;
4369 int i, j;
4370 const char *fmt;
4372 if (rtx_equal_p (inner, exp))
4373 return 1;
4375 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4376 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4377 switch (*fmt++)
4379 case 'e':
4380 case 'u':
4381 if (contained_in_p (inner, XEXP (exp, i)))
4382 return 1;
4383 break;
4385 case 'E':
4386 for (j = 0; j < XVECLEN (exp, i); j++)
4387 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4388 return 1;
4389 break;
4392 return 0;
4395 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4397 static void
4398 gen_insn (exp, lineno)
4399 rtx exp;
4400 int lineno;
4402 struct insn_def *id;
4404 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4405 id->next = defs;
4406 defs = id;
4407 id->def = exp;
4408 id->lineno = lineno;
4410 switch (GET_CODE (exp))
4412 case DEFINE_INSN:
4413 id->insn_code = insn_code_number;
4414 id->insn_index = insn_index_number;
4415 id->num_alternatives = count_alternatives (exp);
4416 if (id->num_alternatives == 0)
4417 id->num_alternatives = 1;
4418 id->vec_idx = 4;
4419 break;
4421 case DEFINE_PEEPHOLE:
4422 id->insn_code = insn_code_number;
4423 id->insn_index = insn_index_number;
4424 id->num_alternatives = count_alternatives (exp);
4425 if (id->num_alternatives == 0)
4426 id->num_alternatives = 1;
4427 id->vec_idx = 3;
4428 break;
4430 case DEFINE_ASM_ATTRIBUTES:
4431 id->insn_code = -1;
4432 id->insn_index = -1;
4433 id->num_alternatives = 1;
4434 id->vec_idx = 0;
4435 got_define_asm_attributes = 1;
4436 break;
4438 default:
4439 abort ();
4443 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4444 true or annul false is specified, and make a `struct delay_desc'. */
4446 static void
4447 gen_delay (def, lineno)
4448 rtx def;
4449 int lineno;
4451 struct delay_desc *delay;
4452 int i;
4454 if (XVECLEN (def, 1) % 3 != 0)
4456 message_with_line (lineno,
4457 "number of elements in DEFINE_DELAY must be multiple of three");
4458 have_error = 1;
4459 return;
4462 for (i = 0; i < XVECLEN (def, 1); i += 3)
4464 if (XVECEXP (def, 1, i + 1))
4465 have_annul_true = 1;
4466 if (XVECEXP (def, 1, i + 2))
4467 have_annul_false = 1;
4470 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4471 delay->def = def;
4472 delay->num = ++num_delays;
4473 delay->next = delays;
4474 delay->lineno = lineno;
4475 delays = delay;
4478 /* Process a DEFINE_FUNCTION_UNIT.
4480 This gives information about a function unit contained in the CPU.
4481 We fill in a `struct function_unit_op' and a `struct function_unit'
4482 with information used later by `expand_unit'. */
4484 static void
4485 gen_unit (def, lineno)
4486 rtx def;
4487 int lineno;
4489 struct function_unit *unit;
4490 struct function_unit_op *op;
4491 const char *name = XSTR (def, 0);
4492 int multiplicity = XINT (def, 1);
4493 int simultaneity = XINT (def, 2);
4494 rtx condexp = XEXP (def, 3);
4495 int ready_cost = MAX (XINT (def, 4), 1);
4496 int issue_delay = MAX (XINT (def, 5), 1);
4498 /* See if we have already seen this function unit. If so, check that
4499 the multiplicity and simultaneity values are the same. If not, make
4500 a structure for this function unit. */
4501 for (unit = units; unit; unit = unit->next)
4502 if (! strcmp (unit->name, name))
4504 if (unit->multiplicity != multiplicity
4505 || unit->simultaneity != simultaneity)
4507 message_with_line (lineno,
4508 "differing specifications given for function unit %s",
4509 unit->name);
4510 message_with_line (unit->first_lineno, "previous definition");
4511 have_error = 1;
4512 return;
4514 break;
4517 if (unit == 0)
4519 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4520 unit->name = name;
4521 unit->multiplicity = multiplicity;
4522 unit->simultaneity = simultaneity;
4523 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4524 unit->num = num_units++;
4525 unit->num_opclasses = 0;
4526 unit->condexp = false_rtx;
4527 unit->ops = 0;
4528 unit->next = units;
4529 unit->first_lineno = lineno;
4530 units = unit;
4533 /* Make a new operation class structure entry and initialize it. */
4534 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4535 op->condexp = condexp;
4536 op->num = unit->num_opclasses++;
4537 op->ready = ready_cost;
4538 op->issue_delay = issue_delay;
4539 op->next = unit->ops;
4540 op->lineno = lineno;
4541 unit->ops = op;
4542 num_unit_opclasses++;
4544 /* Set our issue expression based on whether or not an optional conflict
4545 vector was specified. */
4546 if (XVEC (def, 6))
4548 /* Compute the IOR of all the specified expressions. */
4549 rtx orexp = false_rtx;
4550 int i;
4552 for (i = 0; i < XVECLEN (def, 6); i++)
4553 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4555 op->conflict_exp = orexp;
4556 extend_range (&unit->issue_delay, 1, issue_delay);
4558 else
4560 op->conflict_exp = true_rtx;
4561 extend_range (&unit->issue_delay, issue_delay, issue_delay);
4564 /* Merge our conditional into that of the function unit so we can determine
4565 which insns are used by the function unit. */
4566 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4569 /* Given a piece of RTX, print a C expression to test its truth value.
4570 We use AND and IOR both for logical and bit-wise operations, so
4571 interpret them as logical unless they are inside a comparison expression.
4572 The first bit of FLAGS will be non-zero in that case.
4574 Set the second bit of FLAGS to make references to attribute values use
4575 a cached local variable instead of calling a function. */
4577 static void
4578 write_test_expr (exp, flags)
4579 rtx exp;
4580 int flags;
4582 int comparison_operator = 0;
4583 RTX_CODE code;
4584 struct attr_desc *attr;
4586 /* In order not to worry about operator precedence, surround our part of
4587 the expression with parentheses. */
4589 printf ("(");
4590 code = GET_CODE (exp);
4591 switch (code)
4593 /* Binary operators. */
4594 case EQ: case NE:
4595 case GE: case GT: case GEU: case GTU:
4596 case LE: case LT: case LEU: case LTU:
4597 comparison_operator = 1;
4599 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4600 case AND: case IOR: case XOR:
4601 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4602 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
4603 switch (code)
4605 case EQ:
4606 printf (" == ");
4607 break;
4608 case NE:
4609 printf (" != ");
4610 break;
4611 case GE:
4612 printf (" >= ");
4613 break;
4614 case GT:
4615 printf (" > ");
4616 break;
4617 case GEU:
4618 printf (" >= (unsigned) ");
4619 break;
4620 case GTU:
4621 printf (" > (unsigned) ");
4622 break;
4623 case LE:
4624 printf (" <= ");
4625 break;
4626 case LT:
4627 printf (" < ");
4628 break;
4629 case LEU:
4630 printf (" <= (unsigned) ");
4631 break;
4632 case LTU:
4633 printf (" < (unsigned) ");
4634 break;
4635 case PLUS:
4636 printf (" + ");
4637 break;
4638 case MINUS:
4639 printf (" - ");
4640 break;
4641 case MULT:
4642 printf (" * ");
4643 break;
4644 case DIV:
4645 printf (" / ");
4646 break;
4647 case MOD:
4648 printf (" %% ");
4649 break;
4650 case AND:
4651 if (flags & 1)
4652 printf (" & ");
4653 else
4654 printf (" && ");
4655 break;
4656 case IOR:
4657 if (flags & 1)
4658 printf (" | ");
4659 else
4660 printf (" || ");
4661 break;
4662 case XOR:
4663 printf (" ^ ");
4664 break;
4665 case ASHIFT:
4666 printf (" << ");
4667 break;
4668 case LSHIFTRT:
4669 case ASHIFTRT:
4670 printf (" >> ");
4671 break;
4672 default:
4673 abort ();
4676 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
4677 break;
4679 case NOT:
4680 /* Special-case (not (eq_attrq "alternative" "x")) */
4681 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4682 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4684 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4685 break;
4688 /* Otherwise, fall through to normal unary operator. */
4690 /* Unary operators. */
4691 case ABS: case NEG:
4692 switch (code)
4694 case NOT:
4695 if (flags & 1)
4696 printf ("~ ");
4697 else
4698 printf ("! ");
4699 break;
4700 case ABS:
4701 printf ("abs ");
4702 break;
4703 case NEG:
4704 printf ("-");
4705 break;
4706 default:
4707 abort ();
4710 write_test_expr (XEXP (exp, 0), flags);
4711 break;
4713 /* Comparison test of an attribute with a value. Most of these will
4714 have been removed by optimization. Handle "alternative"
4715 specially and give error if EQ_ATTR present inside a comparison. */
4716 case EQ_ATTR:
4717 if (flags & 1)
4718 fatal ("EQ_ATTR not valid inside comparison");
4720 if (XSTR (exp, 0) == alternative_name)
4722 printf ("which_alternative == %s", XSTR (exp, 1));
4723 break;
4726 attr = find_attr (XSTR (exp, 0), 0);
4727 if (! attr)
4728 abort ();
4730 /* Now is the time to expand the value of a constant attribute. */
4731 if (attr->is_const)
4733 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4734 -2, -2),
4735 flags);
4737 else
4739 if (flags & 2)
4740 printf ("attr_%s", attr->name);
4741 else
4742 printf ("get_attr_%s (insn)", attr->name);
4743 printf (" == ");
4744 write_attr_valueq (attr, XSTR (exp, 1));
4746 break;
4748 /* Comparison test of flags for define_delays. */
4749 case ATTR_FLAG:
4750 if (flags & 1)
4751 fatal ("ATTR_FLAG not valid inside comparison");
4752 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4753 break;
4755 /* See if an operand matches a predicate. */
4756 case MATCH_OPERAND:
4757 /* If only a mode is given, just ensure the mode matches the operand.
4758 If neither a mode nor predicate is given, error. */
4759 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4761 if (GET_MODE (exp) == VOIDmode)
4762 fatal ("Null MATCH_OPERAND specified as test");
4763 else
4764 printf ("GET_MODE (operands[%d]) == %smode",
4765 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4767 else
4768 printf ("%s (operands[%d], %smode)",
4769 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4770 break;
4772 case MATCH_INSN:
4773 printf ("%s (insn)", XSTR (exp, 0));
4774 break;
4776 /* Constant integer. */
4777 case CONST_INT:
4778 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
4779 break;
4781 /* A random C expression. */
4782 case SYMBOL_REF:
4783 printf ("%s", XSTR (exp, 0));
4784 break;
4786 /* The address of the branch target. */
4787 case MATCH_DUP:
4788 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
4789 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4790 break;
4792 case PC:
4793 /* The address of the current insn. We implement this actually as the
4794 address of the current insn for backward branches, but the last
4795 address of the next insn for forward branches, and both with
4796 adjustments that account for the worst-case possible stretching of
4797 intervening alignments between this insn and its destination. */
4798 printf ("insn_current_reference_address (insn)");
4799 break;
4801 case CONST_STRING:
4802 printf ("%s", XSTR (exp, 0));
4803 break;
4805 case IF_THEN_ELSE:
4806 write_test_expr (XEXP (exp, 0), flags & 2);
4807 printf (" ? ");
4808 write_test_expr (XEXP (exp, 1), flags | 1);
4809 printf (" : ");
4810 write_test_expr (XEXP (exp, 2), flags | 1);
4811 break;
4813 default:
4814 fatal ("bad RTX code `%s' in attribute calculation\n",
4815 GET_RTX_NAME (code));
4818 printf (")");
4821 /* Given an attribute value, return the maximum CONST_STRING argument
4822 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
4824 static int
4825 max_attr_value (exp, unknownp)
4826 rtx exp;
4827 int *unknownp;
4829 int current_max;
4830 int i, n;
4832 switch (GET_CODE (exp))
4834 case CONST_STRING:
4835 current_max = atoi (XSTR (exp, 0));
4836 break;
4838 case COND:
4839 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4840 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4842 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4843 if (n > current_max)
4844 current_max = n;
4846 break;
4848 case IF_THEN_ELSE:
4849 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4850 n = max_attr_value (XEXP (exp, 2), unknownp);
4851 if (n > current_max)
4852 current_max = n;
4853 break;
4855 default:
4856 *unknownp = 1;
4857 current_max = INT_MAX;
4858 break;
4861 return current_max;
4864 /* Given an attribute value, return the result of ORing together all
4865 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4866 if the numeric value is not known. */
4868 static int
4869 or_attr_value (exp, unknownp)
4870 rtx exp;
4871 int *unknownp;
4873 int current_or;
4874 int i;
4876 switch (GET_CODE (exp))
4878 case CONST_STRING:
4879 current_or = atoi (XSTR (exp, 0));
4880 break;
4882 case COND:
4883 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4884 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4885 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4886 break;
4888 case IF_THEN_ELSE:
4889 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4890 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4891 break;
4893 default:
4894 *unknownp = 1;
4895 current_or = -1;
4896 break;
4899 return current_or;
4902 /* Scan an attribute value, possibly a conditional, and record what actions
4903 will be required to do any conditional tests in it.
4905 Specifically, set
4906 `must_extract' if we need to extract the insn operands
4907 `must_constrain' if we must compute `which_alternative'
4908 `address_used' if an address expression was used
4909 `length_used' if an (eq_attr "length" ...) was used
4912 static void
4913 walk_attr_value (exp)
4914 rtx exp;
4916 register int i, j;
4917 register const char *fmt;
4918 RTX_CODE code;
4920 if (exp == NULL)
4921 return;
4923 code = GET_CODE (exp);
4924 switch (code)
4926 case SYMBOL_REF:
4927 if (! RTX_UNCHANGING_P (exp))
4928 /* Since this is an arbitrary expression, it can look at anything.
4929 However, constant expressions do not depend on any particular
4930 insn. */
4931 must_extract = must_constrain = 1;
4932 return;
4934 case MATCH_OPERAND:
4935 must_extract = 1;
4936 return;
4938 case EQ_ATTR:
4939 if (XSTR (exp, 0) == alternative_name)
4940 must_extract = must_constrain = 1;
4941 else if (strcmp (XSTR (exp, 0), "length") == 0)
4942 length_used = 1;
4943 return;
4945 case MATCH_DUP:
4946 must_extract = 1;
4947 address_used = 1;
4948 return;
4950 case PC:
4951 address_used = 1;
4952 return;
4954 case ATTR_FLAG:
4955 return;
4957 default:
4958 break;
4961 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4962 switch (*fmt++)
4964 case 'e':
4965 case 'u':
4966 walk_attr_value (XEXP (exp, i));
4967 break;
4969 case 'E':
4970 if (XVEC (exp, i) != NULL)
4971 for (j = 0; j < XVECLEN (exp, i); j++)
4972 walk_attr_value (XVECEXP (exp, i, j));
4973 break;
4977 /* Write out a function to obtain the attribute for a given INSN. */
4979 static void
4980 write_attr_get (attr)
4981 struct attr_desc *attr;
4983 struct attr_value *av, *common_av;
4985 /* Find the most used attribute value. Handle that as the `default' of the
4986 switch we will generate. */
4987 common_av = find_most_used (attr);
4989 /* Write out prototype of function. */
4990 if (!attr->is_numeric)
4991 printf ("extern enum attr_%s ", attr->name);
4992 else if (attr->unsigned_p)
4993 printf ("extern unsigned int ");
4994 else
4995 printf ("extern int ");
4996 /* If the attribute name starts with a star, the remainder is the name of
4997 the subroutine to use, instead of `get_attr_...'. */
4998 if (attr->name[0] == '*')
4999 printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
5000 else
5001 printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
5002 (attr->is_const ? "void" : "rtx"));
5004 /* Write out start of function, then all values with explicit `case' lines,
5005 then a `default', then the value with the most uses. */
5006 if (!attr->is_numeric)
5007 printf ("enum attr_%s\n", attr->name);
5008 else if (attr->unsigned_p)
5009 printf ("unsigned int\n");
5010 else
5011 printf ("int\n");
5013 /* If the attribute name starts with a star, the remainder is the name of
5014 the subroutine to use, instead of `get_attr_...'. */
5015 if (attr->name[0] == '*')
5016 printf ("%s (insn)\n", &attr->name[1]);
5017 else if (attr->is_const == 0)
5018 printf ("get_attr_%s (insn)\n", attr->name);
5019 else
5021 printf ("get_attr_%s ()\n", attr->name);
5022 printf ("{\n");
5024 for (av = attr->first_value; av; av = av->next)
5025 if (av->num_insns != 0)
5026 write_attr_set (attr, 2, av->value, "return", ";",
5027 true_rtx, av->first_insn->insn_code,
5028 av->first_insn->insn_index);
5030 printf ("}\n\n");
5031 return;
5034 printf (" rtx insn;\n");
5035 printf ("{\n");
5037 if (GET_CODE (common_av->value) == FFS)
5039 rtx p = XEXP (common_av->value, 0);
5041 /* No need to emit code to abort if the insn is unrecognized; the
5042 other get_attr_foo functions will do that when we call them. */
5044 write_toplevel_expr (p);
5046 printf ("\n if (accum && accum == (accum & -accum))\n");
5047 printf (" {\n");
5048 printf (" int i;\n");
5049 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
5050 printf (" accum = i;\n");
5051 printf (" }\n else\n");
5052 printf (" accum = ~accum;\n");
5053 printf (" return accum;\n}\n\n");
5055 else
5057 printf (" switch (recog_memoized (insn))\n");
5058 printf (" {\n");
5060 for (av = attr->first_value; av; av = av->next)
5061 if (av != common_av)
5062 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5064 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5065 printf (" }\n}\n\n");
5069 /* Given an AND tree of known true terms (because we are inside an `if' with
5070 that as the condition or are in an `else' clause) and an expression,
5071 replace any known true terms with TRUE. Use `simplify_and_tree' to do
5072 the bulk of the work. */
5074 static rtx
5075 eliminate_known_true (known_true, exp, insn_code, insn_index)
5076 rtx known_true;
5077 rtx exp;
5078 int insn_code, insn_index;
5080 rtx term;
5082 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
5084 if (GET_CODE (known_true) == AND)
5086 exp = eliminate_known_true (XEXP (known_true, 0), exp,
5087 insn_code, insn_index);
5088 exp = eliminate_known_true (XEXP (known_true, 1), exp,
5089 insn_code, insn_index);
5091 else
5093 term = known_true;
5094 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
5097 return exp;
5100 /* Write out a series of tests and assignment statements to perform tests and
5101 sets of an attribute value. We are passed an indentation amount and prefix
5102 and suffix strings to write around each attribute value (e.g., "return"
5103 and ";"). */
5105 static void
5106 write_attr_set (attr, indent, value, prefix, suffix, known_true,
5107 insn_code, insn_index)
5108 struct attr_desc *attr;
5109 int indent;
5110 rtx value;
5111 const char *prefix;
5112 const char *suffix;
5113 rtx known_true;
5114 int insn_code, insn_index;
5116 if (GET_CODE (value) == COND)
5118 /* Assume the default value will be the default of the COND unless we
5119 find an always true expression. */
5120 rtx default_val = XEXP (value, 1);
5121 rtx our_known_true = known_true;
5122 rtx newexp;
5123 int first_if = 1;
5124 int i;
5126 for (i = 0; i < XVECLEN (value, 0); i += 2)
5128 rtx testexp;
5129 rtx inner_true;
5131 testexp = eliminate_known_true (our_known_true,
5132 XVECEXP (value, 0, i),
5133 insn_code, insn_index);
5134 newexp = attr_rtx (NOT, testexp);
5135 newexp = insert_right_side (AND, our_known_true, newexp,
5136 insn_code, insn_index);
5138 /* If the test expression is always true or if the next `known_true'
5139 expression is always false, this is the last case, so break
5140 out and let this value be the `else' case. */
5141 if (testexp == true_rtx || newexp == false_rtx)
5143 default_val = XVECEXP (value, 0, i + 1);
5144 break;
5147 /* Compute the expression to pass to our recursive call as being
5148 known true. */
5149 inner_true = insert_right_side (AND, our_known_true,
5150 testexp, insn_code, insn_index);
5152 /* If this is always false, skip it. */
5153 if (inner_true == false_rtx)
5154 continue;
5156 write_indent (indent);
5157 printf ("%sif ", first_if ? "" : "else ");
5158 first_if = 0;
5159 write_test_expr (testexp, 0);
5160 printf ("\n");
5161 write_indent (indent + 2);
5162 printf ("{\n");
5164 write_attr_set (attr, indent + 4,
5165 XVECEXP (value, 0, i + 1), prefix, suffix,
5166 inner_true, insn_code, insn_index);
5167 write_indent (indent + 2);
5168 printf ("}\n");
5169 our_known_true = newexp;
5172 if (! first_if)
5174 write_indent (indent);
5175 printf ("else\n");
5176 write_indent (indent + 2);
5177 printf ("{\n");
5180 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5181 prefix, suffix, our_known_true, insn_code, insn_index);
5183 if (! first_if)
5185 write_indent (indent + 2);
5186 printf ("}\n");
5189 else
5191 write_indent (indent);
5192 printf ("%s ", prefix);
5193 write_attr_value (attr, value);
5194 printf ("%s\n", suffix);
5198 /* Write out the computation for one attribute value. */
5200 static void
5201 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5202 known_true)
5203 struct attr_desc *attr;
5204 struct attr_value *av;
5205 int write_case_lines;
5206 const char *prefix, *suffix;
5207 int indent;
5208 rtx known_true;
5210 struct insn_ent *ie;
5212 if (av->num_insns == 0)
5213 return;
5215 if (av->has_asm_insn)
5217 write_indent (indent);
5218 printf ("case -1:\n");
5219 write_indent (indent + 2);
5220 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5221 write_indent (indent + 2);
5222 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5223 write_indent (indent + 2);
5224 printf (" fatal_insn_not_found (insn);\n");
5227 if (write_case_lines)
5229 for (ie = av->first_insn; ie; ie = ie->next)
5230 if (ie->insn_code != -1)
5232 write_indent (indent);
5233 printf ("case %d:\n", ie->insn_code);
5236 else
5238 write_indent (indent);
5239 printf ("default:\n");
5242 /* See what we have to do to output this value. */
5243 must_extract = must_constrain = address_used = 0;
5244 walk_attr_value (av->value);
5246 if (must_constrain)
5248 write_indent (indent + 2);
5249 printf ("extract_constrain_insn_cached (insn);\n");
5251 else if (must_extract)
5253 write_indent (indent + 2);
5254 printf ("extract_insn_cached (insn);\n");
5257 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5258 known_true, av->first_insn->insn_code,
5259 av->first_insn->insn_index);
5261 if (strncmp (prefix, "return", 6))
5263 write_indent (indent + 2);
5264 printf ("break;\n");
5266 printf ("\n");
5269 /* Search for uses of non-const attributes and write code to cache them. */
5271 static int
5272 write_expr_attr_cache (p, attr)
5273 rtx p;
5274 struct attr_desc *attr;
5276 const char *fmt;
5277 int i, ie, j, je;
5279 if (GET_CODE (p) == EQ_ATTR)
5281 if (XSTR (p, 0) != attr->name)
5282 return 0;
5284 if (!attr->is_numeric)
5285 printf (" register enum attr_%s ", attr->name);
5286 else if (attr->unsigned_p)
5287 printf (" register unsigned int ");
5288 else
5289 printf (" register int ");
5291 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5292 return 1;
5295 fmt = GET_RTX_FORMAT (GET_CODE (p));
5296 ie = GET_RTX_LENGTH (GET_CODE (p));
5297 for (i = 0; i < ie; i++)
5299 switch (*fmt++)
5301 case 'e':
5302 if (write_expr_attr_cache (XEXP (p, i), attr))
5303 return 1;
5304 break;
5306 case 'E':
5307 je = XVECLEN (p, i);
5308 for (j = 0; j < je; ++j)
5309 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5310 return 1;
5311 break;
5315 return 0;
5318 /* Evaluate an expression at top level. A front end to write_test_expr,
5319 in which we cache attribute values and break up excessively large
5320 expressions to cater to older compilers. */
5322 static void
5323 write_toplevel_expr (p)
5324 rtx p;
5326 struct attr_desc *attr;
5327 int i;
5329 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
5330 for (attr = attrs[i]; attr; attr = attr->next)
5331 if (!attr->is_const)
5332 write_expr_attr_cache (p, attr);
5334 printf (" register unsigned long accum = 0;\n\n");
5336 while (GET_CODE (p) == IOR)
5338 rtx e;
5339 if (GET_CODE (XEXP (p, 0)) == IOR)
5340 e = XEXP (p, 1), p = XEXP (p, 0);
5341 else
5342 e = XEXP (p, 0), p = XEXP (p, 1);
5344 printf (" accum |= ");
5345 write_test_expr (e, 3);
5346 printf (";\n");
5348 printf (" accum |= ");
5349 write_test_expr (p, 3);
5350 printf (";\n");
5353 /* Utilities to write names in various forms. */
5355 static void
5356 write_unit_name (prefix, num, suffix)
5357 const char *prefix;
5358 int num;
5359 const char *suffix;
5361 struct function_unit *unit;
5363 for (unit = units; unit; unit = unit->next)
5364 if (unit->num == num)
5366 printf ("%s%s%s", prefix, unit->name, suffix);
5367 return;
5370 printf ("%s<unknown>%s", prefix, suffix);
5373 static void
5374 write_attr_valueq (attr, s)
5375 struct attr_desc *attr;
5376 const char *s;
5378 if (attr->is_numeric)
5380 int num = atoi (s);
5382 printf ("%d", num);
5384 /* Make the blockage range values and function units used values easier
5385 to read. */
5386 if (attr->func_units_p)
5388 if (num == -1)
5389 printf (" /* units: none */");
5390 else if (num >= 0)
5391 write_unit_name (" /* units: ", num, " */");
5392 else
5394 int i;
5395 const char *sep = " /* units: ";
5396 for (i = 0, num = ~num; num; i++, num >>= 1)
5397 if (num & 1)
5399 write_unit_name (sep, i, (num == 1) ? " */" : "");
5400 sep = ", ";
5405 else if (attr->blockage_p)
5406 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5407 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5409 else if (num > 9 || num < 0)
5410 printf (" /* 0x%x */", num);
5412 else
5414 write_upcase (attr->name);
5415 printf ("_");
5416 write_upcase (s);
5420 static void
5421 write_attr_value (attr, value)
5422 struct attr_desc *attr;
5423 rtx value;
5425 int op;
5427 switch (GET_CODE (value))
5429 case CONST_STRING:
5430 write_attr_valueq (attr, XSTR (value, 0));
5431 break;
5433 case CONST_INT:
5434 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
5435 break;
5437 case SYMBOL_REF:
5438 fputs (XSTR (value, 0), stdout);
5439 break;
5441 case ATTR:
5443 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
5444 printf ("get_attr_%s (%s)", attr2->name,
5445 (attr2->is_const ? "" : "insn"));
5447 break;
5449 case PLUS:
5450 op = '+';
5451 goto do_operator;
5452 case MINUS:
5453 op = '-';
5454 goto do_operator;
5455 case MULT:
5456 op = '*';
5457 goto do_operator;
5458 case DIV:
5459 op = '/';
5460 goto do_operator;
5461 case MOD:
5462 op = '%';
5463 goto do_operator;
5465 do_operator:
5466 write_attr_value (attr, XEXP (value, 0));
5467 putchar (' ');
5468 putchar (op);
5469 putchar (' ');
5470 write_attr_value (attr, XEXP (value, 1));
5471 break;
5473 default:
5474 abort ();
5478 static void
5479 write_upcase (str)
5480 const char *str;
5482 while (*str)
5484 /* The argument of TOUPPER should not have side effects. */
5485 putchar (TOUPPER(*str));
5486 str++;
5490 static void
5491 write_indent (indent)
5492 int indent;
5494 for (; indent > 8; indent -= 8)
5495 printf ("\t");
5497 for (; indent; indent--)
5498 printf (" ");
5501 /* Write a subroutine that is given an insn that requires a delay slot, a
5502 delay slot ordinal, and a candidate insn. It returns non-zero if the
5503 candidate can be placed in the specified delay slot of the insn.
5505 We can write as many as three subroutines. `eligible_for_delay'
5506 handles normal delay slots, `eligible_for_annul_true' indicates that
5507 the specified insn can be annulled if the branch is true, and likewise
5508 for `eligible_for_annul_false'.
5510 KIND is a string distinguishing these three cases ("delay", "annul_true",
5511 or "annul_false"). */
5513 static void
5514 write_eligible_delay (kind)
5515 const char *kind;
5517 struct delay_desc *delay;
5518 int max_slots;
5519 char str[50];
5520 struct attr_desc *attr;
5521 struct attr_value *av, *common_av;
5522 int i;
5524 /* Compute the maximum number of delay slots required. We use the delay
5525 ordinal times this number plus one, plus the slot number as an index into
5526 the appropriate predicate to test. */
5528 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5529 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5530 max_slots = XVECLEN (delay->def, 1) / 3;
5532 /* Write function prelude. */
5534 printf ("int\n");
5535 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5536 kind);
5537 printf (" rtx delay_insn;\n");
5538 printf (" int slot;\n");
5539 printf (" rtx candidate_insn;\n");
5540 printf (" int flags ATTRIBUTE_UNUSED;\n");
5541 printf ("{\n");
5542 printf (" rtx insn;\n");
5543 printf ("\n");
5544 printf (" if (slot >= %d)\n", max_slots);
5545 printf (" abort ();\n");
5546 printf ("\n");
5548 /* If more than one delay type, find out which type the delay insn is. */
5550 if (num_delays > 1)
5552 attr = find_attr ("*delay_type", 0);
5553 if (! attr)
5554 abort ();
5555 common_av = find_most_used (attr);
5557 printf (" insn = delay_insn;\n");
5558 printf (" switch (recog_memoized (insn))\n");
5559 printf (" {\n");
5561 sprintf (str, " * %d;\n break;", max_slots);
5562 for (av = attr->first_value; av; av = av->next)
5563 if (av != common_av)
5564 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5566 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5567 printf (" }\n\n");
5569 /* Ensure matched. Otherwise, shouldn't have been called. */
5570 printf (" if (slot < %d)\n", max_slots);
5571 printf (" abort ();\n\n");
5574 /* If just one type of delay slot, write simple switch. */
5575 if (num_delays == 1 && max_slots == 1)
5577 printf (" insn = candidate_insn;\n");
5578 printf (" switch (recog_memoized (insn))\n");
5579 printf (" {\n");
5581 attr = find_attr ("*delay_1_0", 0);
5582 if (! attr)
5583 abort ();
5584 common_av = find_most_used (attr);
5586 for (av = attr->first_value; av; av = av->next)
5587 if (av != common_av)
5588 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5590 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5591 printf (" }\n");
5594 else
5596 /* Write a nested CASE. The first indicates which condition we need to
5597 test, and the inner CASE tests the condition. */
5598 printf (" insn = candidate_insn;\n");
5599 printf (" switch (slot)\n");
5600 printf (" {\n");
5602 for (delay = delays; delay; delay = delay->next)
5603 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5605 printf (" case %d:\n",
5606 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5607 printf (" switch (recog_memoized (insn))\n");
5608 printf ("\t{\n");
5610 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5611 attr = find_attr (str, 0);
5612 if (! attr)
5613 abort ();
5614 common_av = find_most_used (attr);
5616 for (av = attr->first_value; av; av = av->next)
5617 if (av != common_av)
5618 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5620 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5621 printf (" }\n");
5624 printf (" default:\n");
5625 printf (" abort ();\n");
5626 printf (" }\n");
5629 printf ("}\n\n");
5632 /* Write routines to compute conflict cost for function units. Then write a
5633 table describing the available function units. */
5635 static void
5636 write_function_unit_info ()
5638 struct function_unit *unit;
5639 int i;
5641 /* Write out conflict routines for function units. Don't bother writing
5642 one if there is only one issue delay value. */
5644 for (unit = units; unit; unit = unit->next)
5646 if (unit->needs_blockage_function)
5647 write_complex_function (unit, "blockage", "block");
5649 /* If the minimum and maximum conflict costs are the same, there
5650 is only one value, so we don't need a function. */
5651 if (! unit->needs_conflict_function)
5653 unit->default_cost = make_numeric_value (unit->issue_delay.max);
5654 continue;
5657 /* The function first computes the case from the candidate insn. */
5658 unit->default_cost = make_numeric_value (0);
5659 write_complex_function (unit, "conflict_cost", "cost");
5662 /* Now that all functions have been written, write the table describing
5663 the function units. The name is included for documentation purposes
5664 only. */
5666 printf ("struct function_unit_desc function_units[] = {\n");
5668 /* Write out the descriptions in numeric order, but don't force that order
5669 on the list. Doing so increases the runtime of genattrtab.c. */
5670 for (i = 0; i < num_units; i++)
5672 for (unit = units; unit; unit = unit->next)
5673 if (unit->num == i)
5674 break;
5676 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5677 unit->name, 1 << unit->num, unit->multiplicity,
5678 unit->simultaneity, XSTR (unit->default_cost, 0),
5679 unit->issue_delay.max, unit->name);
5681 if (unit->needs_conflict_function)
5682 printf ("%s_unit_conflict_cost, ", unit->name);
5683 else
5684 printf ("0, ");
5686 printf ("%d, ", unit->max_blockage);
5688 if (unit->needs_range_function)
5689 printf ("%s_unit_blockage_range, ", unit->name);
5690 else
5691 printf ("0, ");
5693 if (unit->needs_blockage_function)
5694 printf ("%s_unit_blockage", unit->name);
5695 else
5696 printf ("0");
5698 printf ("}, \n");
5701 printf ("};\n\n");
5704 static void
5705 write_complex_function (unit, name, connection)
5706 struct function_unit *unit;
5707 const char *name, *connection;
5709 struct attr_desc *case_attr, *attr;
5710 struct attr_value *av, *common_av;
5711 rtx value;
5712 char str[256];
5713 int using_case;
5714 int i;
5716 printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
5717 printf ("static int\n");
5718 printf ("%s_unit_%s (executing_insn, candidate_insn)\n", unit->name, name);
5719 printf (" rtx executing_insn;\n");
5720 printf (" rtx candidate_insn;\n");
5721 printf ("{\n");
5722 printf (" rtx insn;\n");
5723 printf (" int casenum;\n\n");
5724 printf (" insn = executing_insn;\n");
5725 printf (" switch (recog_memoized (insn))\n");
5726 printf (" {\n");
5728 /* Write the `switch' statement to get the case value. */
5729 if (strlen (unit->name) + sizeof "*_cases" > 256)
5730 abort ();
5731 sprintf (str, "*%s_cases", unit->name);
5732 case_attr = find_attr (str, 0);
5733 if (! case_attr)
5734 abort ();
5735 common_av = find_most_used (case_attr);
5737 for (av = case_attr->first_value; av; av = av->next)
5738 if (av != common_av)
5739 write_attr_case (case_attr, av, 1,
5740 "casenum =", ";", 4, unit->condexp);
5742 write_attr_case (case_attr, common_av, 0,
5743 "casenum =", ";", 4, unit->condexp);
5744 printf (" }\n\n");
5746 /* Now write an outer switch statement on each case. Then write
5747 the tests on the executing function within each. */
5748 printf (" insn = candidate_insn;\n");
5749 printf (" switch (casenum)\n");
5750 printf (" {\n");
5752 for (i = 0; i < unit->num_opclasses; i++)
5754 /* Ensure using this case. */
5755 using_case = 0;
5756 for (av = case_attr->first_value; av; av = av->next)
5757 if (av->num_insns
5758 && contained_in_p (make_numeric_value (i), av->value))
5759 using_case = 1;
5761 if (! using_case)
5762 continue;
5764 printf (" case %d:\n", i);
5765 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5766 attr = find_attr (str, 0);
5767 if (! attr)
5768 abort ();
5770 /* If single value, just write it. */
5771 value = find_single_value (attr);
5772 if (value)
5773 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5774 else
5776 common_av = find_most_used (attr);
5777 printf (" switch (recog_memoized (insn))\n");
5778 printf ("\t{\n");
5780 for (av = attr->first_value; av; av = av->next)
5781 if (av != common_av)
5782 write_attr_case (attr, av, 1,
5783 "return", ";", 8, unit->condexp);
5785 write_attr_case (attr, common_av, 0,
5786 "return", ";", 8, unit->condexp);
5787 printf (" }\n\n");
5791 /* This default case should not be needed, but gcc's analysis is not
5792 good enough to realize that the default case is not needed for the
5793 second switch statement. */
5794 printf (" default:\n abort ();\n");
5795 printf (" }\n}\n\n");
5798 /* This page contains miscellaneous utility routines. */
5800 /* Given a string, return the number of comma-separated elements in it.
5801 Return 0 for the null string. */
5803 static int
5804 n_comma_elts (s)
5805 const char *s;
5807 int n;
5809 if (*s == '\0')
5810 return 0;
5812 for (n = 1; *s; s++)
5813 if (*s == ',')
5814 n++;
5816 return n;
5819 /* Given a pointer to a (char *), return a malloc'ed string containing the
5820 next comma-separated element. Advance the pointer to after the string
5821 scanned, or the end-of-string. Return NULL if at end of string. */
5823 static char *
5824 next_comma_elt (pstr)
5825 const char **pstr;
5827 char *out_str;
5828 const char *p;
5830 if (**pstr == '\0')
5831 return NULL;
5833 /* Find end of string to compute length. */
5834 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5837 out_str = attr_string (*pstr, p - *pstr);
5838 *pstr = p;
5840 if (**pstr == ',')
5841 (*pstr)++;
5843 return out_str;
5846 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5847 is non-zero, build a new attribute, if one does not exist. */
5849 static struct attr_desc *
5850 find_attr (name, create)
5851 const char *name;
5852 int create;
5854 struct attr_desc *attr;
5855 int index;
5857 /* Before we resort to using `strcmp', see if the string address matches
5858 anywhere. In most cases, it should have been canonicalized to do so. */
5859 if (name == alternative_name)
5860 return NULL;
5862 index = name[0] & (MAX_ATTRS_INDEX - 1);
5863 for (attr = attrs[index]; attr; attr = attr->next)
5864 if (name == attr->name)
5865 return attr;
5867 /* Otherwise, do it the slow way. */
5868 for (attr = attrs[index]; attr; attr = attr->next)
5869 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5870 return attr;
5872 if (! create)
5873 return NULL;
5875 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5876 attr->name = attr_string (name, strlen (name));
5877 attr->first_value = attr->default_val = NULL;
5878 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5879 attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
5880 attr->next = attrs[index];
5881 attrs[index] = attr;
5883 return attr;
5886 /* Create internal attribute with the given default value. */
5888 static void
5889 make_internal_attr (name, value, special)
5890 const char *name;
5891 rtx value;
5892 int special;
5894 struct attr_desc *attr;
5896 attr = find_attr (name, 1);
5897 if (attr->default_val)
5898 abort ();
5900 attr->is_numeric = 1;
5901 attr->is_const = 0;
5902 attr->is_special = (special & 1) != 0;
5903 attr->negative_ok = (special & 2) != 0;
5904 attr->unsigned_p = (special & 4) != 0;
5905 attr->func_units_p = (special & 8) != 0;
5906 attr->blockage_p = (special & 16) != 0;
5907 attr->default_val = get_attr_value (value, attr, -2);
5910 /* Find the most used value of an attribute. */
5912 static struct attr_value *
5913 find_most_used (attr)
5914 struct attr_desc *attr;
5916 struct attr_value *av;
5917 struct attr_value *most_used;
5918 int nuses;
5920 most_used = NULL;
5921 nuses = -1;
5923 for (av = attr->first_value; av; av = av->next)
5924 if (av->num_insns > nuses)
5925 nuses = av->num_insns, most_used = av;
5927 return most_used;
5930 /* If an attribute only has a single value used, return it. Otherwise
5931 return NULL. */
5933 static rtx
5934 find_single_value (attr)
5935 struct attr_desc *attr;
5937 struct attr_value *av;
5938 rtx unique_value;
5940 unique_value = NULL;
5941 for (av = attr->first_value; av; av = av->next)
5942 if (av->num_insns)
5944 if (unique_value)
5945 return NULL;
5946 else
5947 unique_value = av->value;
5950 return unique_value;
5953 /* Return (attr_value "n") */
5955 static rtx
5956 make_numeric_value (n)
5957 int n;
5959 static rtx int_values[20];
5960 rtx exp;
5961 char *p;
5963 if (n < 0)
5964 abort ();
5966 if (n < 20 && int_values[n])
5967 return int_values[n];
5969 p = attr_printf (MAX_DIGITS, "%d", n);
5970 exp = attr_rtx (CONST_STRING, p);
5972 if (n < 20)
5973 int_values[n] = exp;
5975 return exp;
5978 static void
5979 extend_range (range, min, max)
5980 struct range *range;
5981 int min;
5982 int max;
5984 if (range->min > min)
5985 range->min = min;
5986 if (range->max < max)
5987 range->max = max;
5990 static rtx
5991 copy_rtx_unchanging (orig)
5992 register rtx orig;
5994 #if 0
5995 register rtx copy;
5996 register RTX_CODE code;
5997 #endif
5999 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
6000 return orig;
6002 MEM_IN_STRUCT_P (orig) = 1;
6003 return orig;
6005 #if 0
6006 code = GET_CODE (orig);
6007 switch (code)
6009 case CONST_INT:
6010 case CONST_DOUBLE:
6011 case SYMBOL_REF:
6012 case CODE_LABEL:
6013 return orig;
6015 default:
6016 break;
6019 copy = rtx_alloc (code);
6020 PUT_MODE (copy, GET_MODE (orig));
6021 RTX_UNCHANGING_P (copy) = 1;
6023 memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
6024 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
6025 return copy;
6026 #endif
6029 /* Determine if an insn has a constant number of delay slots, i.e., the
6030 number of delay slots is not a function of the length of the insn. */
6032 static void
6033 write_const_num_delay_slots ()
6035 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
6036 struct attr_value *av;
6037 struct insn_ent *ie;
6039 if (attr)
6041 printf ("int\nconst_num_delay_slots (insn)\n");
6042 printf (" rtx insn;\n");
6043 printf ("{\n");
6044 printf (" switch (recog_memoized (insn))\n");
6045 printf (" {\n");
6047 for (av = attr->first_value; av; av = av->next)
6049 length_used = 0;
6050 walk_attr_value (av->value);
6051 if (length_used)
6053 for (ie = av->first_insn; ie; ie = ie->next)
6054 if (ie->insn_code != -1)
6055 printf (" case %d:\n", ie->insn_code);
6056 printf (" return 0;\n");
6060 printf (" default:\n");
6061 printf (" return 1;\n");
6062 printf (" }\n}\n\n");
6066 extern int main PARAMS ((int, char **));
6069 main (argc, argv)
6070 int argc;
6071 char **argv;
6073 rtx desc;
6074 struct attr_desc *attr;
6075 struct insn_def *id;
6076 rtx tem;
6077 int i;
6079 progname = "genattrtab";
6081 if (argc <= 1)
6082 fatal ("No input file name.");
6084 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
6085 return (FATAL_EXIT_CODE);
6087 obstack_init (hash_obstack);
6088 obstack_init (temp_obstack);
6090 /* Set up true and false rtx's */
6091 true_rtx = rtx_alloc (CONST_INT);
6092 XWINT (true_rtx, 0) = 1;
6093 false_rtx = rtx_alloc (CONST_INT);
6094 XWINT (false_rtx, 0) = 0;
6095 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
6096 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
6098 alternative_name = attr_string ("alternative", strlen ("alternative"));
6100 printf ("/* Generated automatically by the program `genattrtab'\n\
6101 from the machine description file `md'. */\n\n");
6103 /* Read the machine description. */
6105 while (1)
6107 int lineno;
6109 desc = read_md_rtx (&lineno, &insn_code_number);
6110 if (desc == NULL)
6111 break;
6113 switch (GET_CODE (desc))
6115 case DEFINE_INSN:
6116 case DEFINE_PEEPHOLE:
6117 case DEFINE_ASM_ATTRIBUTES:
6118 gen_insn (desc, lineno);
6119 break;
6121 case DEFINE_ATTR:
6122 gen_attr (desc, lineno);
6123 break;
6125 case DEFINE_DELAY:
6126 gen_delay (desc, lineno);
6127 break;
6129 case DEFINE_FUNCTION_UNIT:
6130 gen_unit (desc, lineno);
6131 break;
6133 default:
6134 break;
6136 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
6137 insn_index_number++;
6140 if (have_error)
6141 return FATAL_EXIT_CODE;
6143 insn_code_number++;
6145 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6146 if (! got_define_asm_attributes)
6148 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6149 XVEC (tem, 0) = rtvec_alloc (0);
6150 gen_insn (tem, 0);
6153 /* Expand DEFINE_DELAY information into new attribute. */
6154 if (num_delays)
6155 expand_delays ();
6157 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6158 if (num_units)
6159 expand_units ();
6161 printf ("#include \"config.h\"\n");
6162 printf ("#include \"system.h\"\n");
6163 printf ("#include \"rtl.h\"\n");
6164 printf ("#include \"tm_p.h\"\n");
6165 printf ("#include \"insn-config.h\"\n");
6166 printf ("#include \"recog.h\"\n");
6167 printf ("#include \"regs.h\"\n");
6168 printf ("#include \"real.h\"\n");
6169 printf ("#include \"output.h\"\n");
6170 printf ("#include \"insn-attr.h\"\n");
6171 printf ("#include \"toplev.h\"\n");
6172 printf ("#include \"flags.h\"\n");
6173 printf ("\n");
6174 printf ("#define operands recog_data.operand\n\n");
6176 /* Make `insn_alternatives'. */
6177 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6178 for (id = defs; id; id = id->next)
6179 if (id->insn_code >= 0)
6180 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6182 /* Make `insn_n_alternatives'. */
6183 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6184 for (id = defs; id; id = id->next)
6185 if (id->insn_code >= 0)
6186 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6188 /* Prepare to write out attribute subroutines by checking everything stored
6189 away and building the attribute cases. */
6191 check_defs ();
6193 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6194 for (attr = attrs[i]; attr; attr = attr->next)
6195 attr->default_val->value
6196 = check_attr_value (attr->default_val->value, attr);
6198 if (have_error)
6199 return FATAL_EXIT_CODE;
6201 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6202 for (attr = attrs[i]; attr; attr = attr->next)
6203 fill_attr (attr);
6205 /* Construct extra attributes for `length'. */
6206 make_length_attrs ();
6208 /* Perform any possible optimizations to speed up compilation. */
6209 optimize_attrs ();
6211 /* Now write out all the `gen_attr_...' routines. Do these before the
6212 special routines (specifically before write_function_unit_info), so
6213 that they get defined before they are used. */
6215 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6216 for (attr = attrs[i]; attr; attr = attr->next)
6218 if (! attr->is_special && ! attr->is_const)
6219 write_attr_get (attr);
6222 /* Write out delay eligibility information, if DEFINE_DELAY present.
6223 (The function to compute the number of delay slots will be written
6224 below.) */
6225 if (num_delays)
6227 write_eligible_delay ("delay");
6228 if (have_annul_true)
6229 write_eligible_delay ("annul_true");
6230 if (have_annul_false)
6231 write_eligible_delay ("annul_false");
6234 /* Write out information about function units. */
6235 if (num_units)
6236 write_function_unit_info ();
6238 /* Write out constant delay slot info */
6239 write_const_num_delay_slots ();
6241 write_length_unit_log ();
6243 fflush (stdout);
6244 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6247 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
6248 const char *
6249 get_insn_name (code)
6250 int code ATTRIBUTE_UNUSED;
6252 return NULL;