* Makefile.in (rtlanal.o): Depend on $(TM_P_H).
[official-gcc.git] / gcc / genattrtab.c
blob4d19165d3a0153df0c2fcbdda826a3a6e3ac2e40
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 GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 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 ((unsigned 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 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 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 int i; /* Array indices... */
551 const char *fmt; /* Current rtx's format... */
552 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
553 int hashcode;
554 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 ((unsigned int len, const char *fmt, ...))
748 char str[256];
750 VA_OPEN (p, fmt);
751 VA_FIXEDARG (p, unsigned int, len);
752 VA_FIXEDARG (p, const char *, fmt);
754 if (len > sizeof str - 1) /* Leave room for \0. */
755 abort ();
757 vsprintf (str, fmt, p);
758 VA_CLOSE (p);
760 return attr_string (str, strlen (str));
763 static rtx
764 attr_eq (name, value)
765 const char *name, *value;
767 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
768 attr_string (value, strlen (value)));
771 static const char *
772 attr_numeral (n)
773 int n;
775 return XSTR (make_numeric_value (n), 0);
778 /* Return a permanent (possibly shared) copy of a string STR (not assumed
779 to be null terminated) with LEN bytes. */
781 static char *
782 attr_string (str, len)
783 const char *str;
784 int len;
786 struct attr_hash *h;
787 int hashcode;
788 int i;
789 char *new_str;
791 /* Compute the hash code. */
792 hashcode = (len + 1) * 613 + (unsigned) str[0];
793 for (i = 1; i <= len; i += 2)
794 hashcode = ((hashcode * 613) + (unsigned) str[i]);
795 if (hashcode < 0)
796 hashcode = -hashcode;
798 /* Search the table for the string. */
799 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
800 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
801 && !strncmp (h->u.str, str, len))
802 return h->u.str; /* <-- return if found. */
804 /* Not found; create a permanent copy and add it to the hash table. */
805 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
806 memcpy (new_str, str, len);
807 new_str[len] = '\0';
808 attr_hash_add_string (hashcode, new_str);
810 return new_str; /* Return the new string. */
813 /* Check two rtx's for equality of contents,
814 taking advantage of the fact that if both are hashed
815 then they can't be equal unless they are the same object. */
817 static int
818 attr_equal_p (x, y)
819 rtx x, y;
821 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
822 && rtx_equal_p (x, y)));
825 /* Copy an attribute value expression,
826 descending to all depths, but not copying any
827 permanent hashed subexpressions. */
829 static rtx
830 attr_copy_rtx (orig)
831 rtx orig;
833 rtx copy;
834 int i, j;
835 RTX_CODE code;
836 const char *format_ptr;
838 /* No need to copy a permanent object. */
839 if (RTX_INTEGRATED_P (orig))
840 return orig;
842 code = GET_CODE (orig);
844 switch (code)
846 case REG:
847 case QUEUED:
848 case CONST_INT:
849 case CONST_DOUBLE:
850 case SYMBOL_REF:
851 case CODE_LABEL:
852 case PC:
853 case CC0:
854 return orig;
856 default:
857 break;
860 copy = rtx_alloc (code);
861 PUT_MODE (copy, GET_MODE (orig));
862 copy->in_struct = orig->in_struct;
863 copy->volatil = orig->volatil;
864 copy->unchanging = orig->unchanging;
865 copy->integrated = orig->integrated;
867 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
869 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
871 switch (*format_ptr++)
873 case 'e':
874 XEXP (copy, i) = XEXP (orig, i);
875 if (XEXP (orig, i) != NULL)
876 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
877 break;
879 case 'E':
880 case 'V':
881 XVEC (copy, i) = XVEC (orig, i);
882 if (XVEC (orig, i) != NULL)
884 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
885 for (j = 0; j < XVECLEN (copy, i); j++)
886 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
888 break;
890 case 'n':
891 case 'i':
892 XINT (copy, i) = XINT (orig, i);
893 break;
895 case 'w':
896 XWINT (copy, i) = XWINT (orig, i);
897 break;
899 case 's':
900 case 'S':
901 XSTR (copy, i) = XSTR (orig, i);
902 break;
904 default:
905 abort ();
908 return copy;
911 /* Given a test expression for an attribute, ensure it is validly formed.
912 IS_CONST indicates whether the expression is constant for each compiler
913 run (a constant expression may not test any particular insn).
915 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
916 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
917 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
919 Update the string address in EQ_ATTR expression to be the same used
920 in the attribute (or `alternative_name') to speed up subsequent
921 `find_attr' calls and eliminate most `strcmp' calls.
923 Return the new expression, if any. */
925 static rtx
926 check_attr_test (exp, is_const, lineno)
927 rtx exp;
928 int is_const;
929 int lineno;
931 struct attr_desc *attr;
932 struct attr_value *av;
933 const char *name_ptr, *p;
934 rtx orexp, newexp;
936 switch (GET_CODE (exp))
938 case EQ_ATTR:
939 /* Handle negation test. */
940 if (XSTR (exp, 1)[0] == '!')
941 return check_attr_test (attr_rtx (NOT,
942 attr_eq (XSTR (exp, 0),
943 &XSTR (exp, 1)[1])),
944 is_const, lineno);
946 else if (n_comma_elts (XSTR (exp, 1)) == 1)
948 attr = find_attr (XSTR (exp, 0), 0);
949 if (attr == NULL)
951 if (! strcmp (XSTR (exp, 0), "alternative"))
953 XSTR (exp, 0) = alternative_name;
954 /* This can't be simplified any further. */
955 RTX_UNCHANGING_P (exp) = 1;
956 return exp;
958 else
959 fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
962 if (is_const && ! attr->is_const)
963 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
964 XSTR (exp, 0));
966 /* Copy this just to make it permanent,
967 so expressions using it can be permanent too. */
968 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
970 /* It shouldn't be possible to simplify the value given to a
971 constant attribute, so don't expand this until it's time to
972 write the test expression. */
973 if (attr->is_const)
974 RTX_UNCHANGING_P (exp) = 1;
976 if (attr->is_numeric)
978 for (p = XSTR (exp, 1); *p; p++)
979 if (*p < '0' || *p > '9')
980 fatal ("Attribute `%s' takes only numeric values",
981 XSTR (exp, 0));
983 else
985 for (av = attr->first_value; av; av = av->next)
986 if (GET_CODE (av->value) == CONST_STRING
987 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
988 break;
990 if (av == NULL)
991 fatal ("Unknown value `%s' for `%s' attribute",
992 XSTR (exp, 1), XSTR (exp, 0));
995 else
997 /* Make an IOR tree of the possible values. */
998 orexp = false_rtx;
999 name_ptr = XSTR (exp, 1);
1000 while ((p = next_comma_elt (&name_ptr)) != NULL)
1002 newexp = attr_eq (XSTR (exp, 0), p);
1003 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
1006 return check_attr_test (orexp, is_const, lineno);
1008 break;
1010 case ATTR_FLAG:
1011 break;
1013 case CONST_INT:
1014 /* Either TRUE or FALSE. */
1015 if (XWINT (exp, 0))
1016 return true_rtx;
1017 else
1018 return false_rtx;
1020 case IOR:
1021 case AND:
1022 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1023 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
1024 break;
1026 case NOT:
1027 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1028 break;
1030 case MATCH_INSN:
1031 case MATCH_OPERAND:
1032 if (is_const)
1033 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1034 GET_RTX_NAME (GET_CODE (exp)));
1035 /* These cases can't be simplified. */
1036 RTX_UNCHANGING_P (exp) = 1;
1037 break;
1039 case LE: case LT: case GT: case GE:
1040 case LEU: case LTU: case GTU: case GEU:
1041 case NE: case EQ:
1042 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1043 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1044 exp = attr_rtx (GET_CODE (exp),
1045 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1046 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
1047 /* These cases can't be simplified. */
1048 RTX_UNCHANGING_P (exp) = 1;
1049 break;
1051 case SYMBOL_REF:
1052 if (is_const)
1054 /* These cases are valid for constant attributes, but can't be
1055 simplified. */
1056 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1057 RTX_UNCHANGING_P (exp) = 1;
1058 break;
1060 default:
1061 fatal ("RTL operator \"%s\" not valid in attribute test",
1062 GET_RTX_NAME (GET_CODE (exp)));
1065 return exp;
1068 /* Given an expression, ensure that it is validly formed and that all named
1069 attribute values are valid for the given attribute. Issue a fatal error
1070 if not. If no attribute is specified, assume a numeric attribute.
1072 Return a perhaps modified replacement expression for the value. */
1074 static rtx
1075 check_attr_value (exp, attr)
1076 rtx exp;
1077 struct attr_desc *attr;
1079 struct attr_value *av;
1080 const char *p;
1081 int i;
1083 switch (GET_CODE (exp))
1085 case CONST_INT:
1086 if (attr && ! attr->is_numeric)
1088 message_with_line (attr->lineno,
1089 "CONST_INT not valid for non-numeric attribute %s",
1090 attr->name);
1091 have_error = 1;
1092 break;
1095 if (INTVAL (exp) < 0 && ! attr->negative_ok)
1097 message_with_line (attr->lineno,
1098 "negative numeric value specified for attribute %s",
1099 attr->name);
1100 have_error = 1;
1101 break;
1103 break;
1105 case CONST_STRING:
1106 if (! strcmp (XSTR (exp, 0), "*"))
1107 break;
1109 if (attr == 0 || attr->is_numeric)
1111 p = XSTR (exp, 0);
1112 if (attr && attr->negative_ok && *p == '-')
1113 p++;
1114 for (; *p; p++)
1115 if (*p > '9' || *p < '0')
1117 message_with_line (attr ? attr->lineno : 0,
1118 "non-numeric value for numeric attribute %s",
1119 attr ? attr->name : "internal");
1120 have_error = 1;
1121 break;
1123 break;
1126 for (av = attr->first_value; av; av = av->next)
1127 if (GET_CODE (av->value) == CONST_STRING
1128 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1129 break;
1131 if (av == NULL)
1133 message_with_line (attr->lineno,
1134 "unknown value `%s' for `%s' attribute",
1135 XSTR (exp, 0), attr ? attr->name : "internal");
1136 have_error = 1;
1138 break;
1140 case IF_THEN_ELSE:
1141 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1142 attr ? attr->is_const : 0,
1143 attr ? attr->lineno : 0);
1144 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1145 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1146 break;
1148 case PLUS:
1149 case MINUS:
1150 case MULT:
1151 case DIV:
1152 case MOD:
1153 if (attr && !attr->is_numeric)
1155 message_with_line (attr->lineno,
1156 "invalid operation `%s' for non-numeric attribute value",
1157 GET_RTX_NAME (GET_CODE (exp)));
1158 have_error = 1;
1159 break;
1161 /* FALLTHRU */
1163 case IOR:
1164 case AND:
1165 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1166 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1167 break;
1169 case FFS:
1170 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1171 break;
1173 case COND:
1174 if (XVECLEN (exp, 0) % 2 != 0)
1176 message_with_line (attr->lineno,
1177 "first operand of COND must have even length");
1178 have_error = 1;
1179 break;
1182 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1184 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1185 attr ? attr->is_const : 0,
1186 attr ? attr->lineno : 0);
1187 XVECEXP (exp, 0, i + 1)
1188 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1191 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1192 break;
1194 case ATTR:
1196 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
1197 if (attr2 == NULL)
1199 message_with_line (attr ? attr->lineno : 0,
1200 "unknown attribute `%s' in ATTR",
1201 XSTR (exp, 0));
1202 have_error = 1;
1204 else if (attr && attr->is_const && ! attr2->is_const)
1206 message_with_line (attr->lineno,
1207 "non-constant attribute `%s' referenced from `%s'",
1208 XSTR (exp, 0), attr->name);
1209 have_error = 1;
1211 else if (attr
1212 && (attr->is_numeric != attr2->is_numeric
1213 || (! attr->negative_ok && attr2->negative_ok)))
1215 message_with_line (attr->lineno,
1216 "numeric attribute mismatch calling `%s' from `%s'",
1217 XSTR (exp, 0), attr->name);
1218 have_error = 1;
1221 break;
1223 case SYMBOL_REF:
1224 /* A constant SYMBOL_REF is valid as a constant attribute test and
1225 is expanded later by make_canonical into a COND. In a non-constant
1226 attribute test, it is left be. */
1227 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1229 default:
1230 message_with_line (attr ? attr->lineno : 0,
1231 "invalid operation `%s' for attribute value",
1232 GET_RTX_NAME (GET_CODE (exp)));
1233 have_error = 1;
1234 break;
1237 return exp;
1240 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1241 It becomes a COND with each test being (eq_attr "alternative "n") */
1243 static rtx
1244 convert_set_attr_alternative (exp, id)
1245 rtx exp;
1246 struct insn_def *id;
1248 int num_alt = id->num_alternatives;
1249 rtx condexp;
1250 int i;
1252 if (XVECLEN (exp, 1) != num_alt)
1254 message_with_line (id->lineno,
1255 "bad number of entries in SET_ATTR_ALTERNATIVE");
1256 have_error = 1;
1257 return NULL_RTX;
1260 /* Make a COND with all tests but the last. Select the last value via the
1261 default. */
1262 condexp = rtx_alloc (COND);
1263 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1265 for (i = 0; i < num_alt - 1; i++)
1267 const char *p;
1268 p = attr_numeral (i);
1270 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1271 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1274 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1276 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1279 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1280 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1282 static rtx
1283 convert_set_attr (exp, id)
1284 rtx exp;
1285 struct insn_def *id;
1287 rtx newexp;
1288 const char *name_ptr;
1289 char *p;
1290 int n;
1292 /* See how many alternative specified. */
1293 n = n_comma_elts (XSTR (exp, 1));
1294 if (n == 1)
1295 return attr_rtx (SET,
1296 attr_rtx (ATTR, XSTR (exp, 0)),
1297 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1299 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1300 XSTR (newexp, 0) = XSTR (exp, 0);
1301 XVEC (newexp, 1) = rtvec_alloc (n);
1303 /* Process each comma-separated name. */
1304 name_ptr = XSTR (exp, 1);
1305 n = 0;
1306 while ((p = next_comma_elt (&name_ptr)) != NULL)
1307 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1309 return convert_set_attr_alternative (newexp, id);
1312 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1313 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1314 expressions. */
1316 static void
1317 check_defs ()
1319 struct insn_def *id;
1320 struct attr_desc *attr;
1321 int i;
1322 rtx value;
1324 for (id = defs; id; id = id->next)
1326 if (XVEC (id->def, id->vec_idx) == NULL)
1327 continue;
1329 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1331 value = XVECEXP (id->def, id->vec_idx, i);
1332 switch (GET_CODE (value))
1334 case SET:
1335 if (GET_CODE (XEXP (value, 0)) != ATTR)
1337 message_with_line (id->lineno, "bad attribute set");
1338 have_error = 1;
1339 value = NULL_RTX;
1341 break;
1343 case SET_ATTR_ALTERNATIVE:
1344 value = convert_set_attr_alternative (value, id);
1345 break;
1347 case SET_ATTR:
1348 value = convert_set_attr (value, id);
1349 break;
1351 default:
1352 message_with_line (id->lineno, "invalid attribute code %s",
1353 GET_RTX_NAME (GET_CODE (value)));
1354 have_error = 1;
1355 value = NULL_RTX;
1357 if (value == NULL_RTX)
1358 continue;
1360 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1362 message_with_line (id->lineno, "unknown attribute %s",
1363 XSTR (XEXP (value, 0), 0));
1364 have_error = 1;
1365 continue;
1368 XVECEXP (id->def, id->vec_idx, i) = value;
1369 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1374 #if 0
1375 /* Given a constant SYMBOL_REF expression, convert to a COND that
1376 explicitly tests each enumerated value. */
1378 static rtx
1379 convert_const_symbol_ref (exp, attr)
1380 rtx exp;
1381 struct attr_desc *attr;
1383 rtx condexp;
1384 struct attr_value *av;
1385 int i;
1386 int num_alt = 0;
1388 for (av = attr->first_value; av; av = av->next)
1389 num_alt++;
1391 /* Make a COND with all tests but the last, and in the original order.
1392 Select the last value via the default. Note that the attr values
1393 are constructed in reverse order. */
1395 condexp = rtx_alloc (COND);
1396 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1397 av = attr->first_value;
1398 XEXP (condexp, 1) = av->value;
1400 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1402 char *p, *string;
1403 rtx value;
1405 string = p = (char *) oballoc (2
1406 + strlen (attr->name)
1407 + strlen (XSTR (av->value, 0)));
1408 strcpy (p, attr->name);
1409 strcat (p, "_");
1410 strcat (p, XSTR (av->value, 0));
1411 for (; *p != '\0'; p++)
1412 *p = TOUPPER (*p);
1414 value = attr_rtx (SYMBOL_REF, string);
1415 RTX_UNCHANGING_P (value) = 1;
1417 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1419 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1422 return condexp;
1424 #endif
1426 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1427 expressions by converting them into a COND. This removes cases from this
1428 program. Also, replace an attribute value of "*" with the default attribute
1429 value. */
1431 static rtx
1432 make_canonical (attr, exp)
1433 struct attr_desc *attr;
1434 rtx exp;
1436 int i;
1437 rtx newexp;
1439 switch (GET_CODE (exp))
1441 case CONST_INT:
1442 exp = make_numeric_value (INTVAL (exp));
1443 break;
1445 case CONST_STRING:
1446 if (! strcmp (XSTR (exp, 0), "*"))
1448 if (attr == 0 || attr->default_val == 0)
1449 fatal ("(attr_value \"*\") used in invalid context.");
1450 exp = attr->default_val->value;
1453 break;
1455 case SYMBOL_REF:
1456 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1457 break;
1458 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1459 This makes the COND something that won't be considered an arbitrary
1460 expression by walk_attr_value. */
1461 RTX_UNCHANGING_P (exp) = 1;
1462 #if 0
1463 /* ??? Why do we do this? With attribute values { A B C D E }, this
1464 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1465 than (x==E). */
1466 exp = convert_const_symbol_ref (exp, attr);
1467 RTX_UNCHANGING_P (exp) = 1;
1468 exp = check_attr_value (exp, attr);
1469 /* Goto COND case since this is now a COND. Note that while the
1470 new expression is rescanned, all symbol_ref notes are marked as
1471 unchanging. */
1472 goto cond;
1473 #else
1474 exp = check_attr_value (exp, attr);
1475 break;
1476 #endif
1478 case IF_THEN_ELSE:
1479 newexp = rtx_alloc (COND);
1480 XVEC (newexp, 0) = rtvec_alloc (2);
1481 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1482 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1484 XEXP (newexp, 1) = XEXP (exp, 2);
1486 exp = newexp;
1487 /* Fall through to COND case since this is now a COND. */
1489 case COND:
1491 int allsame = 1;
1492 rtx defval;
1494 /* First, check for degenerate COND. */
1495 if (XVECLEN (exp, 0) == 0)
1496 return make_canonical (attr, XEXP (exp, 1));
1497 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1499 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1501 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1502 XVECEXP (exp, 0, i + 1)
1503 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1504 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1505 allsame = 0;
1507 if (allsame)
1508 return defval;
1510 break;
1512 default:
1513 break;
1516 return exp;
1519 static rtx
1520 copy_boolean (exp)
1521 rtx exp;
1523 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1524 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1525 copy_boolean (XEXP (exp, 1)));
1526 return exp;
1529 /* Given a value and an attribute description, return a `struct attr_value *'
1530 that represents that value. This is either an existing structure, if the
1531 value has been previously encountered, or a newly-created structure.
1533 `insn_code' is the code of an insn whose attribute has the specified
1534 value (-2 if not processing an insn). We ensure that all insns for
1535 a given value have the same number of alternatives if the value checks
1536 alternatives. */
1538 static struct attr_value *
1539 get_attr_value (value, attr, insn_code)
1540 rtx value;
1541 struct attr_desc *attr;
1542 int insn_code;
1544 struct attr_value *av;
1545 int num_alt = 0;
1547 value = make_canonical (attr, value);
1548 if (compares_alternatives_p (value))
1550 if (insn_code < 0 || insn_alternatives == NULL)
1551 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1552 else
1553 num_alt = insn_alternatives[insn_code];
1556 for (av = attr->first_value; av; av = av->next)
1557 if (rtx_equal_p (value, av->value)
1558 && (num_alt == 0 || av->first_insn == NULL
1559 || insn_alternatives[av->first_insn->insn_code]))
1560 return av;
1562 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1563 av->value = value;
1564 av->next = attr->first_value;
1565 attr->first_value = av;
1566 av->first_insn = NULL;
1567 av->num_insns = 0;
1568 av->has_asm_insn = 0;
1570 return av;
1573 /* After all DEFINE_DELAYs have been read in, create internal attributes
1574 to generate the required routines.
1576 First, we compute the number of delay slots for each insn (as a COND of
1577 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1578 delay type is specified, we compute a similar function giving the
1579 DEFINE_DELAY ordinal for each insn.
1581 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1582 tells whether a given insn can be in that delay slot.
1584 Normal attribute filling and optimization expands these to contain the
1585 information needed to handle delay slots. */
1587 static void
1588 expand_delays ()
1590 struct delay_desc *delay;
1591 rtx condexp;
1592 rtx newexp;
1593 int i;
1594 char *p;
1596 /* First, generate data for `num_delay_slots' function. */
1598 condexp = rtx_alloc (COND);
1599 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1600 XEXP (condexp, 1) = make_numeric_value (0);
1602 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1604 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1605 XVECEXP (condexp, 0, i + 1)
1606 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1609 make_internal_attr ("*num_delay_slots", condexp, 0);
1611 /* If more than one delay type, do the same for computing the delay type. */
1612 if (num_delays > 1)
1614 condexp = rtx_alloc (COND);
1615 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1616 XEXP (condexp, 1) = make_numeric_value (0);
1618 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1620 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1621 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1624 make_internal_attr ("*delay_type", condexp, 1);
1627 /* For each delay possibility and delay slot, compute an eligibility
1628 attribute for non-annulled insns and for each type of annulled (annul
1629 if true and annul if false). */
1630 for (delay = delays; delay; delay = delay->next)
1632 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1634 condexp = XVECEXP (delay->def, 1, i);
1635 if (condexp == 0)
1636 condexp = false_rtx;
1637 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1638 make_numeric_value (1), make_numeric_value (0));
1640 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1641 "*delay_%d_%d", delay->num, i / 3);
1642 make_internal_attr (p, newexp, 1);
1644 if (have_annul_true)
1646 condexp = XVECEXP (delay->def, 1, i + 1);
1647 if (condexp == 0) condexp = false_rtx;
1648 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1649 make_numeric_value (1),
1650 make_numeric_value (0));
1651 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1652 "*annul_true_%d_%d", delay->num, i / 3);
1653 make_internal_attr (p, newexp, 1);
1656 if (have_annul_false)
1658 condexp = XVECEXP (delay->def, 1, i + 2);
1659 if (condexp == 0) condexp = false_rtx;
1660 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1661 make_numeric_value (1),
1662 make_numeric_value (0));
1663 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1664 "*annul_false_%d_%d", delay->num, i / 3);
1665 make_internal_attr (p, newexp, 1);
1671 /* This function is given a left and right side expression and an operator.
1672 Each side is a conditional expression, each alternative of which has a
1673 numerical value. The function returns another conditional expression
1674 which, for every possible set of condition values, returns a value that is
1675 the operator applied to the values of the two sides.
1677 Since this is called early, it must also support IF_THEN_ELSE. */
1679 static rtx
1680 operate_exp (op, left, right)
1681 enum operator op;
1682 rtx left, right;
1684 int left_value, right_value;
1685 rtx newexp;
1686 int i;
1688 /* If left is a string, apply operator to it and the right side. */
1689 if (GET_CODE (left) == CONST_STRING)
1691 /* If right is also a string, just perform the operation. */
1692 if (GET_CODE (right) == CONST_STRING)
1694 left_value = atoi (XSTR (left, 0));
1695 right_value = atoi (XSTR (right, 0));
1696 switch (op)
1698 case PLUS_OP:
1699 i = left_value + right_value;
1700 break;
1702 case MINUS_OP:
1703 i = left_value - right_value;
1704 break;
1706 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1707 if (left_value > right_value)
1708 i = left_value - right_value;
1709 else
1710 i = 0;
1711 break;
1713 case OR_OP:
1714 case ORX_OP:
1715 i = left_value | right_value;
1716 break;
1718 case EQ_OP:
1719 i = left_value == right_value;
1720 break;
1722 case RANGE_OP:
1723 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1724 break;
1726 case MAX_OP:
1727 if (left_value > right_value)
1728 i = left_value;
1729 else
1730 i = right_value;
1731 break;
1733 case MIN_OP:
1734 if (left_value < right_value)
1735 i = left_value;
1736 else
1737 i = right_value;
1738 break;
1740 default:
1741 abort ();
1744 if (i == left_value)
1745 return left;
1746 if (i == right_value)
1747 return right;
1748 return make_numeric_value (i);
1750 else if (GET_CODE (right) == IF_THEN_ELSE)
1752 /* Apply recursively to all values within. */
1753 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1754 rtx newright = operate_exp (op, left, XEXP (right, 2));
1755 if (rtx_equal_p (newleft, newright))
1756 return newleft;
1757 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1759 else if (GET_CODE (right) == COND)
1761 int allsame = 1;
1762 rtx defval;
1764 newexp = rtx_alloc (COND);
1765 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1766 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1768 for (i = 0; i < XVECLEN (right, 0); i += 2)
1770 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1771 XVECEXP (newexp, 0, i + 1)
1772 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1773 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1774 defval))
1775 allsame = 0;
1778 /* If the resulting cond is trivial (all alternatives
1779 give the same value), optimize it away. */
1780 if (allsame)
1781 return operate_exp (op, left, XEXP (right, 1));
1783 return newexp;
1785 else
1786 fatal ("Badly formed attribute value");
1789 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1790 not associate through IF_THEN_ELSE. */
1791 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1793 return attr_rtx (IOR, left, right);
1796 /* Otherwise, do recursion the other way. */
1797 else if (GET_CODE (left) == IF_THEN_ELSE)
1799 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1800 rtx newright = operate_exp (op, XEXP (left, 2), right);
1801 if (rtx_equal_p (newleft, newright))
1802 return newleft;
1803 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1805 else if (GET_CODE (left) == COND)
1807 int allsame = 1;
1808 rtx defval;
1810 newexp = rtx_alloc (COND);
1811 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1812 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1814 for (i = 0; i < XVECLEN (left, 0); i += 2)
1816 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1817 XVECEXP (newexp, 0, i + 1)
1818 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1819 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1820 defval))
1821 allsame = 0;
1824 /* If the cond is trivial (all alternatives give the same value),
1825 optimize it away. */
1826 if (allsame)
1827 return operate_exp (op, XEXP (left, 1), right);
1829 /* If the result is the same as the LEFT operand,
1830 just use that. */
1831 if (rtx_equal_p (newexp, left))
1832 return left;
1834 return newexp;
1837 else
1838 fatal ("Badly formed attribute value.");
1839 /* NOTREACHED */
1840 return NULL;
1843 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1844 construct a number of attributes.
1846 The first produces a function `function_units_used' which is given an
1847 insn and produces an encoding showing which function units are required
1848 for the execution of that insn. If the value is non-negative, the insn
1849 uses that unit; otherwise, the value is a one's compliment mask of units
1850 used.
1852 The second produces a function `result_ready_cost' which is used to
1853 determine the time that the result of an insn will be ready and hence
1854 a worst-case schedule.
1856 Both of these produce quite complex expressions which are then set as the
1857 default value of internal attributes. Normal attribute simplification
1858 should produce reasonable expressions.
1860 For each unit, a `<name>_unit_ready_cost' function will take an
1861 insn and give the delay until that unit will be ready with the result
1862 and a `<name>_unit_conflict_cost' function is given an insn already
1863 executing on the unit and a candidate to execute and will give the
1864 cost from the time the executing insn started until the candidate
1865 can start (ignore limitations on the number of simultaneous insns).
1867 For each unit, a `<name>_unit_blockage' function is given an insn
1868 already executing on the unit and a candidate to execute and will
1869 give the delay incurred due to function unit conflicts. The range of
1870 blockage cost values for a given executing insn is given by the
1871 `<name>_unit_blockage_range' function. These values are encoded in
1872 an int where the upper half gives the minimum value and the lower
1873 half gives the maximum value. */
1875 static void
1876 expand_units ()
1878 struct function_unit *unit, **unit_num;
1879 struct function_unit_op *op, **op_array, ***unit_ops;
1880 rtx unitsmask;
1881 rtx readycost;
1882 rtx newexp;
1883 const char *str;
1884 int i, j, u, num, nvalues;
1886 /* Rebuild the condition for the unit to share the RTL expressions.
1887 Sharing is required by simplify_by_exploding. Build the issue delay
1888 expressions. Validate the expressions we were given for the conditions
1889 and conflict vector. Then make attributes for use in the conflict
1890 function. */
1892 for (unit = units; unit; unit = unit->next)
1894 unit->condexp = check_attr_test (unit->condexp, 0, unit->first_lineno);
1896 for (op = unit->ops; op; op = op->next)
1898 rtx issue_delay = make_numeric_value (op->issue_delay);
1899 rtx issue_exp = issue_delay;
1901 /* Build, validate, and simplify the issue delay expression. */
1902 if (op->conflict_exp != true_rtx)
1903 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1904 issue_exp, make_numeric_value (0));
1905 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1906 issue_exp),
1907 NULL_ATTR);
1908 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1909 op->issue_exp = issue_exp;
1911 /* Make an attribute for use in the conflict function if needed. */
1912 unit->needs_conflict_function = (unit->issue_delay.min
1913 != unit->issue_delay.max);
1914 if (unit->needs_conflict_function)
1916 str = attr_printf ((strlen (unit->name) + sizeof "*_cost_"
1917 + MAX_DIGITS),
1918 "*%s_cost_%d", unit->name, op->num);
1919 make_internal_attr (str, issue_exp, 1);
1922 /* Validate the condition. */
1923 op->condexp = check_attr_test (op->condexp, 0, op->lineno);
1927 /* Compute the mask of function units used. Initially, the unitsmask is
1928 zero. Set up a conditional to compute each unit's contribution. */
1929 unitsmask = make_numeric_value (0);
1930 newexp = rtx_alloc (IF_THEN_ELSE);
1931 XEXP (newexp, 2) = make_numeric_value (0);
1933 /* If we have just a few units, we may be all right expanding the whole
1934 thing. But the expansion is 2**N in space on the number of opclasses,
1935 so we can't do this for very long -- Alpha and MIPS in particular have
1936 problems with this. So in that situation, we fall back on an alternate
1937 implementation method. */
1938 #define NUM_UNITOP_CUTOFF 20
1940 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1942 /* Merge each function unit into the unit mask attributes. */
1943 for (unit = units; unit; unit = unit->next)
1945 XEXP (newexp, 0) = unit->condexp;
1946 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1947 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1950 else
1952 /* Merge each function unit into the unit mask attributes. */
1953 for (unit = units; unit; unit = unit->next)
1955 XEXP (newexp, 0) = unit->condexp;
1956 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1957 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1961 /* Simplify the unit mask expression, encode it, and make an attribute
1962 for the function_units_used function. */
1963 unitsmask = simplify_by_exploding (unitsmask);
1965 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1966 unitsmask = encode_units_mask (unitsmask);
1967 else
1969 /* We can no longer encode unitsmask at compile time, so emit code to
1970 calculate it at runtime. Rather, put a marker for where we'd do
1971 the code, and actually output it in write_attr_get(). */
1972 unitsmask = attr_rtx (FFS, unitsmask);
1975 make_internal_attr ("*function_units_used", unitsmask, 10);
1977 /* Create an array of ops for each unit. Add an extra unit for the
1978 result_ready_cost function that has the ops of all other units. */
1979 unit_ops = (struct function_unit_op ***)
1980 xmalloc ((num_units + 1) * sizeof (struct function_unit_op **));
1981 unit_num = (struct function_unit **)
1982 xmalloc ((num_units + 1) * sizeof (struct function_unit *));
1984 unit_num[num_units] = unit = (struct function_unit *)
1985 xmalloc (sizeof (struct function_unit));
1986 unit->num = num_units;
1987 unit->num_opclasses = 0;
1989 for (unit = units; unit; unit = unit->next)
1991 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1992 unit_num[unit->num] = unit;
1993 unit_ops[unit->num] = op_array = (struct function_unit_op **)
1994 xmalloc (unit->num_opclasses * sizeof (struct function_unit_op *));
1996 for (op = unit->ops; op; op = op->next)
1997 op_array[op->num] = op;
2000 /* Compose the array of ops for the extra unit. */
2001 unit_ops[num_units] = op_array = (struct function_unit_op **)
2002 xmalloc (unit_num[num_units]->num_opclasses
2003 * sizeof (struct function_unit_op *));
2005 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
2006 memcpy (&op_array[i], unit_ops[unit->num],
2007 unit->num_opclasses * sizeof (struct function_unit_op *));
2009 /* Compute the ready cost function for each unit by computing the
2010 condition for each non-default value. */
2011 for (u = 0; u <= num_units; u++)
2013 rtx orexp;
2014 int value;
2016 unit = unit_num[u];
2017 op_array = unit_ops[unit->num];
2018 num = unit->num_opclasses;
2020 /* Sort the array of ops into increasing ready cost order. */
2021 for (i = 0; i < num; i++)
2022 for (j = num - 1; j > i; j--)
2023 if (op_array[j - 1]->ready < op_array[j]->ready)
2025 op = op_array[j];
2026 op_array[j] = op_array[j - 1];
2027 op_array[j - 1] = op;
2030 /* Determine how many distinct non-default ready cost values there
2031 are. We use a default ready cost value of 1. */
2032 nvalues = 0; value = 1;
2033 for (i = num - 1; i >= 0; i--)
2034 if (op_array[i]->ready > value)
2036 value = op_array[i]->ready;
2037 nvalues++;
2040 if (nvalues == 0)
2041 readycost = make_numeric_value (1);
2042 else
2044 /* Construct the ready cost expression as a COND of each value from
2045 the largest to the smallest. */
2046 readycost = rtx_alloc (COND);
2047 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2048 XEXP (readycost, 1) = make_numeric_value (1);
2050 nvalues = 0;
2051 orexp = false_rtx;
2052 value = op_array[0]->ready;
2053 for (i = 0; i < num; i++)
2055 op = op_array[i];
2056 if (op->ready <= 1)
2057 break;
2058 else if (op->ready == value)
2059 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
2060 else
2062 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2063 XVECEXP (readycost, 0, nvalues * 2 + 1)
2064 = make_numeric_value (value);
2065 nvalues++;
2066 value = op->ready;
2067 orexp = op->condexp;
2070 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2071 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2074 if (u < num_units)
2076 rtx max_blockage = 0, min_blockage = 0;
2078 /* Simplify the readycost expression by only considering insns
2079 that use the unit. */
2080 readycost = simplify_knowing (readycost, unit->condexp);
2082 /* Determine the blockage cost the executing insn (E) given
2083 the candidate insn (C). This is the maximum of the issue
2084 delay, the pipeline delay, and the simultaneity constraint.
2085 Each function_unit_op represents the characteristics of the
2086 candidate insn, so in the expressions below, C is a known
2087 term and E is an unknown term.
2089 We compute the blockage cost for each E for every possible C.
2090 Thus OP represents E, and READYCOST is a list of values for
2091 every possible C.
2093 The issue delay function for C is op->issue_exp and is used to
2094 write the `<name>_unit_conflict_cost' function. Symbolicly
2095 this is "ISSUE-DELAY (E,C)".
2097 The pipeline delay results form the FIFO constraint on the
2098 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2100 The simultaneity constraint is based on how long it takes to
2101 fill the unit given the minimum issue delay. FILL-TIME is the
2102 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2103 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2104 if SIMULTANEITY is non-zero and zero otherwise.
2106 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2108 MAX (ISSUE-DELAY (E,C),
2109 READY-COST (E) - (READY-COST (C) - 1))
2111 and otherwise
2113 MAX (ISSUE-DELAY (E,C),
2114 READY-COST (E) - (READY-COST (C) - 1),
2115 READY-COST (E) - FILL-TIME)
2117 The `<name>_unit_blockage' function is computed by determining
2118 this value for each candidate insn. As these values are
2119 computed, we also compute the upper and lower bounds for
2120 BLOCKAGE (E,*). These are combined to form the function
2121 `<name>_unit_blockage_range'. Finally, the maximum blockage
2122 cost, MAX (BLOCKAGE (*,*)), is computed. */
2124 for (op = unit->ops; op; op = op->next)
2126 rtx blockage = op->issue_exp;
2127 blockage = simplify_knowing (blockage, unit->condexp);
2129 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2130 MIN (BLOCKAGE (E,*)). */
2131 if (max_blockage == 0)
2132 max_blockage = min_blockage = blockage;
2133 else
2135 max_blockage
2136 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2137 blockage),
2138 unit->condexp);
2139 min_blockage
2140 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2141 blockage),
2142 unit->condexp);
2145 /* Make an attribute for use in the blockage function. */
2146 str = attr_printf ((strlen (unit->name) + sizeof "*_block_"
2147 + MAX_DIGITS),
2148 "*%s_block_%d", unit->name, op->num);
2149 make_internal_attr (str, blockage, 1);
2152 /* Record MAX (BLOCKAGE (*,*)). */
2154 int unknown;
2155 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2158 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2159 same. If so, the blockage function carries no additional
2160 information and is not written. */
2161 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2162 newexp = simplify_knowing (newexp, unit->condexp);
2163 unit->needs_blockage_function
2164 = (GET_CODE (newexp) != CONST_STRING
2165 || atoi (XSTR (newexp, 0)) != 1);
2167 /* If the all values of BLOCKAGE (E,C) have the same value,
2168 neither blockage function is written. */
2169 unit->needs_range_function
2170 = (unit->needs_blockage_function
2171 || GET_CODE (max_blockage) != CONST_STRING);
2173 if (unit->needs_range_function)
2175 /* Compute the blockage range function and make an attribute
2176 for writing its value. */
2177 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2178 newexp = simplify_knowing (newexp, unit->condexp);
2180 str = attr_printf ((strlen (unit->name)
2181 + sizeof "*_unit_blockage_range"),
2182 "*%s_unit_blockage_range", unit->name);
2183 make_internal_attr (str, newexp, 20);
2186 str = attr_printf (strlen (unit->name) + sizeof "*_unit_ready_cost",
2187 "*%s_unit_ready_cost", unit->name);
2189 else
2190 str = "*result_ready_cost";
2192 /* Make an attribute for the ready_cost function. Simplifying
2193 further with simplify_by_exploding doesn't win. */
2194 make_internal_attr (str, readycost, 0);
2197 /* For each unit that requires a conflict cost function, make an attribute
2198 that maps insns to the operation number. */
2199 for (unit = units; unit; unit = unit->next)
2201 rtx caseexp;
2203 if (! unit->needs_conflict_function
2204 && ! unit->needs_blockage_function)
2205 continue;
2207 caseexp = rtx_alloc (COND);
2208 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2210 for (op = unit->ops; op; op = op->next)
2212 /* Make our adjustment to the COND being computed. If we are the
2213 last operation class, place our values into the default of the
2214 COND. */
2215 if (op->num == unit->num_opclasses - 1)
2217 XEXP (caseexp, 1) = make_numeric_value (op->num);
2219 else
2221 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2222 XVECEXP (caseexp, 0, op->num * 2 + 1)
2223 = make_numeric_value (op->num);
2227 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2228 str = attr_printf (strlen (unit->name) + sizeof "*_cases",
2229 "*%s_cases", unit->name);
2230 make_internal_attr (str, caseexp, 1);
2234 /* Simplify EXP given KNOWN_TRUE. */
2236 static rtx
2237 simplify_knowing (exp, known_true)
2238 rtx exp, known_true;
2240 if (GET_CODE (exp) != CONST_STRING)
2242 int unknown = 0, max;
2243 max = max_attr_value (exp, &unknown);
2244 if (! unknown)
2246 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2247 make_numeric_value (max));
2248 exp = simplify_by_exploding (exp);
2251 return exp;
2254 /* Translate the CONST_STRING expressions in X to change the encoding of
2255 value. On input, the value is a bitmask with a one bit for each unit
2256 used; on output, the value is the unit number (zero based) if one
2257 and only one unit is used or the one's compliment of the bitmask. */
2259 static rtx
2260 encode_units_mask (x)
2261 rtx x;
2263 int i;
2264 int j;
2265 enum rtx_code code;
2266 const char *fmt;
2268 code = GET_CODE (x);
2270 switch (code)
2272 case CONST_STRING:
2273 i = atoi (XSTR (x, 0));
2274 if (i < 0)
2275 /* The sign bit encodes a one's compliment mask. */
2276 abort ();
2277 else if (i != 0 && i == (i & -i))
2278 /* Only one bit is set, so yield that unit number. */
2279 for (j = 0; (i >>= 1) != 0; j++)
2281 else
2282 j = ~i;
2283 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2285 case REG:
2286 case QUEUED:
2287 case CONST_INT:
2288 case CONST_DOUBLE:
2289 case SYMBOL_REF:
2290 case CODE_LABEL:
2291 case PC:
2292 case CC0:
2293 case EQ_ATTR:
2294 return x;
2296 default:
2297 break;
2300 /* Compare the elements. If any pair of corresponding elements
2301 fail to match, return 0 for the whole things. */
2303 fmt = GET_RTX_FORMAT (code);
2304 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2306 switch (fmt[i])
2308 case 'V':
2309 case 'E':
2310 for (j = 0; j < XVECLEN (x, i); j++)
2311 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2312 break;
2314 case 'e':
2315 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2316 break;
2319 return x;
2322 /* Once all attributes and insns have been read and checked, we construct for
2323 each attribute value a list of all the insns that have that value for
2324 the attribute. */
2326 static void
2327 fill_attr (attr)
2328 struct attr_desc *attr;
2330 struct attr_value *av;
2331 struct insn_ent *ie;
2332 struct insn_def *id;
2333 int i;
2334 rtx value;
2336 /* Don't fill constant attributes. The value is independent of
2337 any particular insn. */
2338 if (attr->is_const)
2339 return;
2341 for (id = defs; id; id = id->next)
2343 /* If no value is specified for this insn for this attribute, use the
2344 default. */
2345 value = NULL;
2346 if (XVEC (id->def, id->vec_idx))
2347 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2348 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2349 attr->name))
2350 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2352 if (value == NULL)
2353 av = attr->default_val;
2354 else
2355 av = get_attr_value (value, attr, id->insn_code);
2357 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2358 ie->insn_code = id->insn_code;
2359 ie->insn_index = id->insn_code;
2360 insert_insn_ent (av, ie);
2364 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2365 test that checks relative positions of insns (uses MATCH_DUP or PC).
2366 If so, replace it with what is obtained by passing the expression to
2367 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2368 recursively on each value (including the default value). Otherwise,
2369 return the value returned by NO_ADDRESS_FN applied to EXP. */
2371 static rtx
2372 substitute_address (exp, no_address_fn, address_fn)
2373 rtx exp;
2374 rtx (*no_address_fn) PARAMS ((rtx));
2375 rtx (*address_fn) PARAMS ((rtx));
2377 int i;
2378 rtx newexp;
2380 if (GET_CODE (exp) == COND)
2382 /* See if any tests use addresses. */
2383 address_used = 0;
2384 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2385 walk_attr_value (XVECEXP (exp, 0, i));
2387 if (address_used)
2388 return (*address_fn) (exp);
2390 /* Make a new copy of this COND, replacing each element. */
2391 newexp = rtx_alloc (COND);
2392 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2393 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2395 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2396 XVECEXP (newexp, 0, i + 1)
2397 = substitute_address (XVECEXP (exp, 0, i + 1),
2398 no_address_fn, address_fn);
2401 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2402 no_address_fn, address_fn);
2404 return newexp;
2407 else if (GET_CODE (exp) == IF_THEN_ELSE)
2409 address_used = 0;
2410 walk_attr_value (XEXP (exp, 0));
2411 if (address_used)
2412 return (*address_fn) (exp);
2414 return attr_rtx (IF_THEN_ELSE,
2415 substitute_address (XEXP (exp, 0),
2416 no_address_fn, address_fn),
2417 substitute_address (XEXP (exp, 1),
2418 no_address_fn, address_fn),
2419 substitute_address (XEXP (exp, 2),
2420 no_address_fn, address_fn));
2423 return (*no_address_fn) (exp);
2426 /* Make new attributes from the `length' attribute. The following are made,
2427 each corresponding to a function called from `shorten_branches' or
2428 `get_attr_length':
2430 *insn_default_length This is the length of the insn to be returned
2431 by `get_attr_length' before `shorten_branches'
2432 has been called. In each case where the length
2433 depends on relative addresses, the largest
2434 possible is used. This routine is also used
2435 to compute the initial size of the insn.
2437 *insn_variable_length_p This returns 1 if the insn's length depends
2438 on relative addresses, zero otherwise.
2440 *insn_current_length This is only called when it is known that the
2441 insn has a variable length and returns the
2442 current length, based on relative addresses.
2445 static void
2446 make_length_attrs ()
2448 static const char *const new_names[] = {"*insn_default_length",
2449 "*insn_variable_length_p",
2450 "*insn_current_length"};
2451 static rtx (*const no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
2452 static rtx (*const address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
2453 size_t i;
2454 struct attr_desc *length_attr, *new_attr;
2455 struct attr_value *av, *new_av;
2456 struct insn_ent *ie, *new_ie;
2458 /* See if length attribute is defined. If so, it must be numeric. Make
2459 it special so we don't output anything for it. */
2460 length_attr = find_attr ("length", 0);
2461 if (length_attr == 0)
2462 return;
2464 if (! length_attr->is_numeric)
2465 fatal ("length attribute must be numeric.");
2467 length_attr->is_const = 0;
2468 length_attr->is_special = 1;
2470 /* Make each new attribute, in turn. */
2471 for (i = 0; i < ARRAY_SIZE (new_names); i++)
2473 make_internal_attr (new_names[i],
2474 substitute_address (length_attr->default_val->value,
2475 no_address_fn[i], address_fn[i]),
2477 new_attr = find_attr (new_names[i], 0);
2478 for (av = length_attr->first_value; av; av = av->next)
2479 for (ie = av->first_insn; ie; ie = ie->next)
2481 new_av = get_attr_value (substitute_address (av->value,
2482 no_address_fn[i],
2483 address_fn[i]),
2484 new_attr, ie->insn_code);
2485 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2486 new_ie->insn_code = ie->insn_code;
2487 new_ie->insn_index = ie->insn_index;
2488 insert_insn_ent (new_av, new_ie);
2493 /* Utility functions called from above routine. */
2495 static rtx
2496 identity_fn (exp)
2497 rtx exp;
2499 return exp;
2502 static rtx
2503 zero_fn (exp)
2504 rtx exp ATTRIBUTE_UNUSED;
2506 return make_numeric_value (0);
2509 static rtx
2510 one_fn (exp)
2511 rtx exp ATTRIBUTE_UNUSED;
2513 return make_numeric_value (1);
2516 static rtx
2517 max_fn (exp)
2518 rtx exp;
2520 int unknown;
2521 return make_numeric_value (max_attr_value (exp, &unknown));
2524 static void
2525 write_length_unit_log ()
2527 struct attr_desc *length_attr = find_attr ("length", 0);
2528 struct attr_value *av;
2529 struct insn_ent *ie;
2530 unsigned int length_unit_log, length_or;
2531 int unknown = 0;
2533 if (length_attr == 0)
2534 return;
2535 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2536 for (av = length_attr->first_value; av; av = av->next)
2537 for (ie = av->first_insn; ie; ie = ie->next)
2538 length_or |= or_attr_value (av->value, &unknown);
2540 if (unknown)
2541 length_unit_log = 0;
2542 else
2544 length_or = ~length_or;
2545 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
2546 length_unit_log++;
2548 printf ("int length_unit_log = %u;\n", length_unit_log);
2551 /* Take a COND expression and see if any of the conditions in it can be
2552 simplified. If any are known true or known false for the particular insn
2553 code, the COND can be further simplified.
2555 Also call ourselves on any COND operations that are values of this COND.
2557 We do not modify EXP; rather, we make and return a new rtx. */
2559 static rtx
2560 simplify_cond (exp, insn_code, insn_index)
2561 rtx exp;
2562 int insn_code, insn_index;
2564 int i, j;
2565 /* We store the desired contents here,
2566 then build a new expression if they don't match EXP. */
2567 rtx defval = XEXP (exp, 1);
2568 rtx new_defval = XEXP (exp, 1);
2569 int len = XVECLEN (exp, 0);
2570 rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
2571 int allsame = 1;
2572 char *first_spacer;
2573 rtx ret;
2575 /* This lets us free all storage allocated below, if appropriate. */
2576 first_spacer = (char *) obstack_finish (rtl_obstack);
2578 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
2580 /* See if default value needs simplification. */
2581 if (GET_CODE (defval) == COND)
2582 new_defval = simplify_cond (defval, insn_code, insn_index);
2584 /* Simplify the subexpressions, and see what tests we can get rid of. */
2586 for (i = 0; i < len; i += 2)
2588 rtx newtest, newval;
2590 /* Simplify this test. */
2591 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
2592 tests[i] = newtest;
2594 newval = tests[i + 1];
2595 /* See if this value may need simplification. */
2596 if (GET_CODE (newval) == COND)
2597 newval = simplify_cond (newval, insn_code, insn_index);
2599 /* Look for ways to delete or combine this test. */
2600 if (newtest == true_rtx)
2602 /* If test is true, make this value the default
2603 and discard this + any following tests. */
2604 len = i;
2605 defval = tests[i + 1];
2606 new_defval = newval;
2609 else if (newtest == false_rtx)
2611 /* If test is false, discard it and its value. */
2612 for (j = i; j < len - 2; j++)
2613 tests[j] = tests[j + 2];
2614 len -= 2;
2617 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
2619 /* If this value and the value for the prev test are the same,
2620 merge the tests. */
2622 tests[i - 2]
2623 = insert_right_side (IOR, tests[i - 2], newtest,
2624 insn_code, insn_index);
2626 /* Delete this test/value. */
2627 for (j = i; j < len - 2; j++)
2628 tests[j] = tests[j + 2];
2629 len -= 2;
2632 else
2633 tests[i + 1] = newval;
2636 /* If the last test in a COND has the same value
2637 as the default value, that test isn't needed. */
2639 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
2640 len -= 2;
2642 /* See if we changed anything. */
2643 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2644 allsame = 0;
2645 else
2646 for (i = 0; i < len; i++)
2647 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
2649 allsame = 0;
2650 break;
2653 if (len == 0)
2655 if (GET_CODE (defval) == COND)
2656 ret = simplify_cond (defval, insn_code, insn_index);
2657 else
2658 ret = defval;
2660 else if (allsame)
2661 ret = exp;
2662 else
2664 rtx newexp = rtx_alloc (COND);
2666 XVEC (newexp, 0) = rtvec_alloc (len);
2667 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
2668 XEXP (newexp, 1) = new_defval;
2669 ret = newexp;
2671 free (tests);
2672 return ret;
2675 /* Remove an insn entry from an attribute value. */
2677 static void
2678 remove_insn_ent (av, ie)
2679 struct attr_value *av;
2680 struct insn_ent *ie;
2682 struct insn_ent *previe;
2684 if (av->first_insn == ie)
2685 av->first_insn = ie->next;
2686 else
2688 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2690 previe->next = ie->next;
2693 av->num_insns--;
2694 if (ie->insn_code == -1)
2695 av->has_asm_insn = 0;
2697 num_insn_ents--;
2700 /* Insert an insn entry in an attribute value list. */
2702 static void
2703 insert_insn_ent (av, ie)
2704 struct attr_value *av;
2705 struct insn_ent *ie;
2707 ie->next = av->first_insn;
2708 av->first_insn = ie;
2709 av->num_insns++;
2710 if (ie->insn_code == -1)
2711 av->has_asm_insn = 1;
2713 num_insn_ents++;
2716 /* This is a utility routine to take an expression that is a tree of either
2717 AND or IOR expressions and insert a new term. The new term will be
2718 inserted at the right side of the first node whose code does not match
2719 the root. A new node will be created with the root's code. Its left
2720 side will be the old right side and its right side will be the new
2721 term.
2723 If the `term' is itself a tree, all its leaves will be inserted. */
2725 static rtx
2726 insert_right_side (code, exp, term, insn_code, insn_index)
2727 enum rtx_code code;
2728 rtx exp;
2729 rtx term;
2730 int insn_code, insn_index;
2732 rtx newexp;
2734 /* Avoid consing in some special cases. */
2735 if (code == AND && term == true_rtx)
2736 return exp;
2737 if (code == AND && term == false_rtx)
2738 return false_rtx;
2739 if (code == AND && exp == true_rtx)
2740 return term;
2741 if (code == AND && exp == false_rtx)
2742 return false_rtx;
2743 if (code == IOR && term == true_rtx)
2744 return true_rtx;
2745 if (code == IOR && term == false_rtx)
2746 return exp;
2747 if (code == IOR && exp == true_rtx)
2748 return true_rtx;
2749 if (code == IOR && exp == false_rtx)
2750 return term;
2751 if (attr_equal_p (exp, term))
2752 return exp;
2754 if (GET_CODE (term) == code)
2756 exp = insert_right_side (code, exp, XEXP (term, 0),
2757 insn_code, insn_index);
2758 exp = insert_right_side (code, exp, XEXP (term, 1),
2759 insn_code, insn_index);
2761 return exp;
2764 if (GET_CODE (exp) == code)
2766 rtx new = insert_right_side (code, XEXP (exp, 1),
2767 term, insn_code, insn_index);
2768 if (new != XEXP (exp, 1))
2769 /* Make a copy of this expression and call recursively. */
2770 newexp = attr_rtx (code, XEXP (exp, 0), new);
2771 else
2772 newexp = exp;
2774 else
2776 /* Insert the new term. */
2777 newexp = attr_rtx (code, exp, term);
2780 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2783 /* If we have an expression which AND's a bunch of
2784 (not (eq_attrq "alternative" "n"))
2785 terms, we may have covered all or all but one of the possible alternatives.
2786 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2788 This routine is passed an expression and either AND or IOR. It returns a
2789 bitmask indicating which alternatives are mentioned within EXP. */
2791 static int
2792 compute_alternative_mask (exp, code)
2793 rtx exp;
2794 enum rtx_code code;
2796 const char *string;
2797 if (GET_CODE (exp) == code)
2798 return compute_alternative_mask (XEXP (exp, 0), code)
2799 | compute_alternative_mask (XEXP (exp, 1), code);
2801 else if (code == AND && GET_CODE (exp) == NOT
2802 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2803 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2804 string = XSTR (XEXP (exp, 0), 1);
2806 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2807 && XSTR (exp, 0) == alternative_name)
2808 string = XSTR (exp, 1);
2810 else
2811 return 0;
2813 if (string[1] == 0)
2814 return 1 << (string[0] - '0');
2815 return 1 << atoi (string);
2818 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2819 attribute with the value represented by that bit. */
2821 static rtx
2822 make_alternative_compare (mask)
2823 int mask;
2825 rtx newexp;
2826 int i;
2828 /* Find the bit. */
2829 for (i = 0; (mask & (1 << i)) == 0; i++)
2832 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2833 RTX_UNCHANGING_P (newexp) = 1;
2835 return newexp;
2838 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2839 of "attr" for this insn code. From that value, we can compute a test
2840 showing when the EQ_ATTR will be true. This routine performs that
2841 computation. If a test condition involves an address, we leave the EQ_ATTR
2842 intact because addresses are only valid for the `length' attribute.
2844 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2845 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2847 static rtx
2848 evaluate_eq_attr (exp, value, insn_code, insn_index)
2849 rtx exp;
2850 rtx value;
2851 int insn_code, insn_index;
2853 rtx orexp, andexp;
2854 rtx right;
2855 rtx newexp;
2856 int i;
2858 if (GET_CODE (value) == CONST_STRING)
2860 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2861 newexp = true_rtx;
2862 else
2863 newexp = false_rtx;
2865 else if (GET_CODE (value) == SYMBOL_REF)
2867 char *p;
2868 char string[256];
2870 if (GET_CODE (exp) != EQ_ATTR)
2871 abort ();
2873 if (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 > 256)
2874 abort ();
2876 strcpy (string, XSTR (exp, 0));
2877 strcat (string, "_");
2878 strcat (string, XSTR (exp, 1));
2879 for (p = string; *p; p++)
2880 *p = TOUPPER (*p);
2882 newexp = attr_rtx (EQ, value,
2883 attr_rtx (SYMBOL_REF,
2884 attr_string (string, strlen (string))));
2886 else if (GET_CODE (value) == COND)
2888 /* We construct an IOR of all the cases for which the requested attribute
2889 value is present. Since we start with FALSE, if it is not present,
2890 FALSE will be returned.
2892 Each case is the AND of the NOT's of the previous conditions with the
2893 current condition; in the default case the current condition is TRUE.
2895 For each possible COND value, call ourselves recursively.
2897 The extra TRUE and FALSE expressions will be eliminated by another
2898 call to the simplification routine. */
2900 orexp = false_rtx;
2901 andexp = true_rtx;
2903 if (current_alternative_string)
2904 clear_struct_flag (value);
2906 for (i = 0; i < XVECLEN (value, 0); i += 2)
2908 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2909 insn_code, insn_index);
2911 SIMPLIFY_ALTERNATIVE (this);
2913 right = insert_right_side (AND, andexp, this,
2914 insn_code, insn_index);
2915 right = insert_right_side (AND, right,
2916 evaluate_eq_attr (exp,
2917 XVECEXP (value, 0,
2918 i + 1),
2919 insn_code, insn_index),
2920 insn_code, insn_index);
2921 orexp = insert_right_side (IOR, orexp, right,
2922 insn_code, insn_index);
2924 /* Add this condition into the AND expression. */
2925 newexp = attr_rtx (NOT, this);
2926 andexp = insert_right_side (AND, andexp, newexp,
2927 insn_code, insn_index);
2930 /* Handle the default case. */
2931 right = insert_right_side (AND, andexp,
2932 evaluate_eq_attr (exp, XEXP (value, 1),
2933 insn_code, insn_index),
2934 insn_code, insn_index);
2935 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2937 else
2938 abort ();
2940 /* If uses an address, must return original expression. But set the
2941 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2943 address_used = 0;
2944 walk_attr_value (newexp);
2946 if (address_used)
2948 /* This had `&& current_alternative_string', which seems to be wrong. */
2949 if (! RTX_UNCHANGING_P (exp))
2950 return copy_rtx_unchanging (exp);
2951 return exp;
2953 else
2954 return newexp;
2957 /* This routine is called when an AND of a term with a tree of AND's is
2958 encountered. If the term or its complement is present in the tree, it
2959 can be replaced with TRUE or FALSE, respectively.
2961 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2962 be true and hence are complementary.
2964 There is one special case: If we see
2965 (and (not (eq_attr "att" "v1"))
2966 (eq_attr "att" "v2"))
2967 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2968 replace the term, not anything in the AND tree. So we pass a pointer to
2969 the term. */
2971 static rtx
2972 simplify_and_tree (exp, pterm, insn_code, insn_index)
2973 rtx exp;
2974 rtx *pterm;
2975 int insn_code, insn_index;
2977 rtx left, right;
2978 rtx newexp;
2979 rtx temp;
2980 int left_eliminates_term, right_eliminates_term;
2982 if (GET_CODE (exp) == AND)
2984 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2985 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2986 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2988 newexp = attr_rtx (GET_CODE (exp), left, right);
2990 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2994 else if (GET_CODE (exp) == IOR)
2996 /* For the IOR case, we do the same as above, except that we can
2997 only eliminate `term' if both sides of the IOR would do so. */
2998 temp = *pterm;
2999 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3000 left_eliminates_term = (temp == true_rtx);
3002 temp = *pterm;
3003 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3004 right_eliminates_term = (temp == true_rtx);
3006 if (left_eliminates_term && right_eliminates_term)
3007 *pterm = true_rtx;
3009 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3011 newexp = attr_rtx (GET_CODE (exp), left, right);
3013 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3017 /* Check for simplifications. Do some extra checking here since this
3018 routine is called so many times. */
3020 if (exp == *pterm)
3021 return true_rtx;
3023 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
3024 return false_rtx;
3026 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
3027 return false_rtx;
3029 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
3031 if (XSTR (exp, 0) != XSTR (*pterm, 0))
3032 return exp;
3034 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
3035 return true_rtx;
3036 else
3037 return false_rtx;
3040 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3041 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3043 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3044 return exp;
3046 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3047 return false_rtx;
3048 else
3049 return true_rtx;
3052 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3053 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3055 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3056 return exp;
3058 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3059 return false_rtx;
3060 else
3061 *pterm = true_rtx;
3064 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3066 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
3067 return true_rtx;
3070 else if (GET_CODE (exp) == NOT)
3072 if (attr_equal_p (XEXP (exp, 0), *pterm))
3073 return false_rtx;
3076 else if (GET_CODE (*pterm) == NOT)
3078 if (attr_equal_p (XEXP (*pterm, 0), exp))
3079 return false_rtx;
3082 else if (attr_equal_p (exp, *pterm))
3083 return true_rtx;
3085 return exp;
3088 /* Similar to `simplify_and_tree', but for IOR trees. */
3090 static rtx
3091 simplify_or_tree (exp, pterm, insn_code, insn_index)
3092 rtx exp;
3093 rtx *pterm;
3094 int insn_code, insn_index;
3096 rtx left, right;
3097 rtx newexp;
3098 rtx temp;
3099 int left_eliminates_term, right_eliminates_term;
3101 if (GET_CODE (exp) == IOR)
3103 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
3104 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3105 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3107 newexp = attr_rtx (GET_CODE (exp), left, right);
3109 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3113 else if (GET_CODE (exp) == AND)
3115 /* For the AND case, we do the same as above, except that we can
3116 only eliminate `term' if both sides of the AND would do so. */
3117 temp = *pterm;
3118 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3119 left_eliminates_term = (temp == false_rtx);
3121 temp = *pterm;
3122 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3123 right_eliminates_term = (temp == false_rtx);
3125 if (left_eliminates_term && right_eliminates_term)
3126 *pterm = false_rtx;
3128 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3130 newexp = attr_rtx (GET_CODE (exp), left, right);
3132 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3136 if (attr_equal_p (exp, *pterm))
3137 return false_rtx;
3139 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
3140 return true_rtx;
3142 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
3143 return true_rtx;
3145 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3146 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3147 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3148 *pterm = false_rtx;
3150 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3151 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3152 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3153 return false_rtx;
3155 return exp;
3157 /* Compute approximate cost of the expression. Used to decide whether
3158 expression is cheap enought for inline. */
3159 static int
3160 attr_rtx_cost (x)
3161 rtx x;
3163 int cost = 0;
3164 enum rtx_code code;
3165 if (!x)
3166 return 0;
3167 code = GET_CODE (x);
3168 switch (code)
3170 case MATCH_OPERAND:
3171 if (XSTR (x, 1)[0])
3172 return 10;
3173 else
3174 return 0;
3175 case EQ_ATTR:
3176 /* Alternatives don't result into function call. */
3177 if (!strcmp (XSTR (x, 0), "alternative"))
3178 return 0;
3179 else
3180 return 5;
3181 default:
3183 int i, j;
3184 const char *fmt = GET_RTX_FORMAT (code);
3185 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3187 switch (fmt[i])
3189 case 'V':
3190 case 'E':
3191 for (j = 0; j < XVECLEN (x, i); j++)
3192 cost += attr_rtx_cost (XVECEXP (x, i, j));
3193 break;
3194 case 'e':
3195 cost += attr_rtx_cost (XEXP (x, i));
3196 break;
3200 break;
3202 return cost;
3206 /* Simplify test expression and use temporary obstack in order to avoid
3207 memory bloat. Use RTX_UNCHANGING_P to avoid unnecesary simplifications
3208 and avoid unnecesary copying if possible. */
3210 static rtx
3211 simplify_test_exp_in_temp (exp, insn_code, insn_index)
3212 rtx exp;
3213 int insn_code, insn_index;
3215 rtx x;
3216 struct obstack *old;
3217 if (RTX_UNCHANGING_P (exp))
3218 return exp;
3219 old = rtl_obstack;
3220 rtl_obstack = temp_obstack;
3221 x = simplify_test_exp (exp, insn_code, insn_index);
3222 rtl_obstack = old;
3223 if (x == exp || rtl_obstack == temp_obstack)
3224 return x;
3225 return attr_copy_rtx (x);
3228 /* Given an expression, see if it can be simplified for a particular insn
3229 code based on the values of other attributes being tested. This can
3230 eliminate nested get_attr_... calls.
3232 Note that if an endless recursion is specified in the patterns, the
3233 optimization will loop. However, it will do so in precisely the cases where
3234 an infinite recursion loop could occur during compilation. It's better that
3235 it occurs here! */
3237 static rtx
3238 simplify_test_exp (exp, insn_code, insn_index)
3239 rtx exp;
3240 int insn_code, insn_index;
3242 rtx left, right;
3243 struct attr_desc *attr;
3244 struct attr_value *av;
3245 struct insn_ent *ie;
3246 int i;
3247 rtx newexp = exp;
3249 /* Don't re-simplify something we already simplified. */
3250 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3251 return exp;
3253 switch (GET_CODE (exp))
3255 case AND:
3256 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3257 SIMPLIFY_ALTERNATIVE (left);
3258 if (left == false_rtx)
3259 return false_rtx;
3260 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3261 SIMPLIFY_ALTERNATIVE (right);
3262 if (left == false_rtx)
3263 return false_rtx;
3265 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3266 present on both sides, apply the distributive law since this will
3267 yield simplifications. */
3268 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3269 && compute_alternative_mask (left, IOR)
3270 && compute_alternative_mask (right, IOR))
3272 if (GET_CODE (left) == IOR)
3274 rtx tem = left;
3275 left = right;
3276 right = tem;
3279 newexp = attr_rtx (IOR,
3280 attr_rtx (AND, left, XEXP (right, 0)),
3281 attr_rtx (AND, left, XEXP (right, 1)));
3283 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3286 /* Try with the term on both sides. */
3287 right = simplify_and_tree (right, &left, insn_code, insn_index);
3288 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3289 left = simplify_and_tree (left, &right, insn_code, insn_index);
3291 if (left == false_rtx || right == false_rtx)
3292 return false_rtx;
3293 else if (left == true_rtx)
3295 return right;
3297 else if (right == true_rtx)
3299 return left;
3301 /* See if all or all but one of the insn's alternatives are specified
3302 in this tree. Optimize if so. */
3304 else if (insn_code >= 0
3305 && (GET_CODE (left) == AND
3306 || (GET_CODE (left) == NOT
3307 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3308 && XSTR (XEXP (left, 0), 0) == alternative_name)
3309 || GET_CODE (right) == AND
3310 || (GET_CODE (right) == NOT
3311 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3312 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3314 i = compute_alternative_mask (exp, AND);
3315 if (i & ~insn_alternatives[insn_code])
3316 fatal ("Invalid alternative specified for pattern number %d",
3317 insn_index);
3319 /* If all alternatives are excluded, this is false. */
3320 i ^= insn_alternatives[insn_code];
3321 if (i == 0)
3322 return false_rtx;
3323 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3325 /* If just one excluded, AND a comparison with that one to the
3326 front of the tree. The others will be eliminated by
3327 optimization. We do not want to do this if the insn has one
3328 alternative and we have tested none of them! */
3329 left = make_alternative_compare (i);
3330 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3331 newexp = attr_rtx (AND, left, right);
3333 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3337 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3339 newexp = attr_rtx (AND, left, right);
3340 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3342 break;
3344 case IOR:
3345 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3346 SIMPLIFY_ALTERNATIVE (left);
3347 if (left == true_rtx)
3348 return true_rtx;
3349 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3350 SIMPLIFY_ALTERNATIVE (right);
3351 if (right == true_rtx)
3352 return true_rtx;
3354 right = simplify_or_tree (right, &left, insn_code, insn_index);
3355 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3356 left = simplify_or_tree (left, &right, insn_code, insn_index);
3358 if (right == true_rtx || left == true_rtx)
3359 return true_rtx;
3360 else if (left == false_rtx)
3362 return right;
3364 else if (right == false_rtx)
3366 return left;
3369 /* Test for simple cases where the distributive law is useful. I.e.,
3370 convert (ior (and (x) (y))
3371 (and (x) (z)))
3372 to (and (x)
3373 (ior (y) (z)))
3376 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3377 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3379 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3381 left = XEXP (left, 0);
3382 right = newexp;
3383 newexp = attr_rtx (AND, left, right);
3384 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3387 /* See if all or all but one of the insn's alternatives are specified
3388 in this tree. Optimize if so. */
3390 else if (insn_code >= 0
3391 && (GET_CODE (left) == IOR
3392 || (GET_CODE (left) == EQ_ATTR
3393 && XSTR (left, 0) == alternative_name)
3394 || GET_CODE (right) == IOR
3395 || (GET_CODE (right) == EQ_ATTR
3396 && XSTR (right, 0) == alternative_name)))
3398 i = compute_alternative_mask (exp, IOR);
3399 if (i & ~insn_alternatives[insn_code])
3400 fatal ("Invalid alternative specified for pattern number %d",
3401 insn_index);
3403 /* If all alternatives are included, this is true. */
3404 i ^= insn_alternatives[insn_code];
3405 if (i == 0)
3406 return true_rtx;
3407 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3409 /* If just one excluded, IOR a comparison with that one to the
3410 front of the tree. The others will be eliminated by
3411 optimization. We do not want to do this if the insn has one
3412 alternative and we have tested none of them! */
3413 left = make_alternative_compare (i);
3414 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3415 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3417 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3421 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3423 newexp = attr_rtx (IOR, left, right);
3424 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3426 break;
3428 case NOT:
3429 if (GET_CODE (XEXP (exp, 0)) == NOT)
3431 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3432 insn_code, insn_index);
3433 SIMPLIFY_ALTERNATIVE (left);
3434 return left;
3437 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3438 SIMPLIFY_ALTERNATIVE (left);
3439 if (GET_CODE (left) == NOT)
3440 return XEXP (left, 0);
3442 if (left == false_rtx)
3443 return true_rtx;
3444 else if (left == true_rtx)
3445 return false_rtx;
3447 /* Try to apply De`Morgan's laws. */
3448 else if (GET_CODE (left) == IOR)
3450 newexp = attr_rtx (AND,
3451 attr_rtx (NOT, XEXP (left, 0)),
3452 attr_rtx (NOT, XEXP (left, 1)));
3454 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3456 else if (GET_CODE (left) == AND)
3458 newexp = attr_rtx (IOR,
3459 attr_rtx (NOT, XEXP (left, 0)),
3460 attr_rtx (NOT, XEXP (left, 1)));
3462 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3464 else if (left != XEXP (exp, 0))
3466 newexp = attr_rtx (NOT, left);
3468 break;
3470 case EQ_ATTR:
3471 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3472 return (XSTR (exp, 1) == current_alternative_string
3473 ? true_rtx : false_rtx);
3475 /* Look at the value for this insn code in the specified attribute.
3476 We normally can replace this comparison with the condition that
3477 would give this insn the values being tested for. */
3478 if (XSTR (exp, 0) != alternative_name
3479 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3480 for (av = attr->first_value; av; av = av->next)
3481 for (ie = av->first_insn; ie; ie = ie->next)
3482 if (ie->insn_code == insn_code)
3484 rtx x;
3485 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3486 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
3487 if (attr_rtx_cost(x) < 20)
3488 return x;
3490 break;
3492 default:
3493 break;
3496 /* We have already simplified this expression. Simplifying it again
3497 won't buy anything unless we weren't given a valid insn code
3498 to process (i.e., we are canonicalizing something.). */
3499 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3500 && ! RTX_UNCHANGING_P (newexp))
3501 return copy_rtx_unchanging (newexp);
3503 return newexp;
3506 /* Optimize the attribute lists by seeing if we can determine conditional
3507 values from the known values of other attributes. This will save subroutine
3508 calls during the compilation. */
3510 static void
3511 optimize_attrs ()
3513 struct attr_desc *attr;
3514 struct attr_value *av;
3515 struct insn_ent *ie;
3516 rtx newexp;
3517 int i;
3518 struct attr_value_list
3520 struct attr_value *av;
3521 struct insn_ent *ie;
3522 struct attr_desc *attr;
3523 struct attr_value_list *next;
3525 struct attr_value_list **insn_code_values;
3526 struct attr_value_list *ivbuf;
3527 struct attr_value_list *iv;
3529 /* For each insn code, make a list of all the insn_ent's for it,
3530 for all values for all attributes. */
3532 if (num_insn_ents == 0)
3533 return;
3535 /* Make 2 extra elements, for "code" values -2 and -1. */
3536 insn_code_values
3537 = (struct attr_value_list **) xmalloc ((insn_code_number + 2)
3538 * sizeof (struct attr_value_list *));
3539 memset ((char *) insn_code_values, 0,
3540 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3542 /* Offset the table address so we can index by -2 or -1. */
3543 insn_code_values += 2;
3545 iv = ivbuf = ((struct attr_value_list *)
3546 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3548 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3549 for (attr = attrs[i]; attr; attr = attr->next)
3550 for (av = attr->first_value; av; av = av->next)
3551 for (ie = av->first_insn; ie; ie = ie->next)
3553 iv->attr = attr;
3554 iv->av = av;
3555 iv->ie = ie;
3556 iv->next = insn_code_values[ie->insn_code];
3557 insn_code_values[ie->insn_code] = iv;
3558 iv++;
3561 /* Sanity check on num_insn_ents. */
3562 if (iv != ivbuf + num_insn_ents)
3563 abort ();
3565 /* Process one insn code at a time. */
3566 for (i = -2; i < insn_code_number; i++)
3568 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3569 We use it to mean "already simplified for this insn". */
3570 for (iv = insn_code_values[i]; iv; iv = iv->next)
3571 clear_struct_flag (iv->av->value);
3573 for (iv = insn_code_values[i]; iv; iv = iv->next)
3575 struct obstack *old = rtl_obstack;
3577 attr = iv->attr;
3578 av = iv->av;
3579 ie = iv->ie;
3580 if (GET_CODE (av->value) != COND)
3581 continue;
3583 rtl_obstack = temp_obstack;
3584 #if 0 /* This was intended as a speed up, but it was slower. */
3585 if (insn_n_alternatives[ie->insn_code] > 6
3586 && count_sub_rtxs (av->value, 200) >= 200)
3587 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3588 ie->insn_index);
3589 else
3590 #endif
3591 newexp = av->value;
3592 while (GET_CODE (newexp) == COND)
3594 rtx newexp2 = simplify_cond (newexp, ie->insn_code,
3595 ie->insn_index);
3596 if (newexp2 == newexp)
3597 break;
3598 newexp = newexp2;
3601 rtl_obstack = old;
3602 if (newexp != av->value)
3604 newexp = attr_copy_rtx (newexp);
3605 remove_insn_ent (av, ie);
3606 av = get_attr_value (newexp, attr, ie->insn_code);
3607 iv->av = av;
3608 insert_insn_ent (av, ie);
3613 free (ivbuf);
3614 free (insn_code_values - 2);
3617 #if 0
3618 static rtx
3619 simplify_by_alternatives (exp, insn_code, insn_index)
3620 rtx exp;
3621 int insn_code, insn_index;
3623 int i;
3624 int len = insn_n_alternatives[insn_code];
3625 rtx newexp = rtx_alloc (COND);
3626 rtx ultimate;
3628 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3630 /* It will not matter what value we use as the default value
3631 of the new COND, since that default will never be used.
3632 Choose something of the right type. */
3633 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3634 ultimate = XEXP (ultimate, 1);
3635 XEXP (newexp, 1) = ultimate;
3637 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3639 current_alternative_string = attr_numeral (i);
3640 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3641 XVECEXP (newexp, 0, i * 2 + 1)
3642 = simplify_cond (exp, insn_code, insn_index);
3645 current_alternative_string = 0;
3646 return simplify_cond (newexp, insn_code, insn_index);
3648 #endif
3650 /* If EXP is a suitable expression, reorganize it by constructing an
3651 equivalent expression that is a COND with the tests being all combinations
3652 of attribute values and the values being simple constants. */
3654 static rtx
3655 simplify_by_exploding (exp)
3656 rtx exp;
3658 rtx list = 0, link, condexp, defval = NULL_RTX;
3659 struct dimension *space;
3660 rtx *condtest, *condval;
3661 int i, j, total, ndim = 0;
3662 int most_tests, num_marks, new_marks;
3663 rtx ret;
3665 /* Locate all the EQ_ATTR expressions. */
3666 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3668 unmark_used_attributes (list, 0, 0);
3669 return exp;
3672 /* Create an attribute space from the list of used attributes. For each
3673 dimension in the attribute space, record the attribute, list of values
3674 used, and number of values used. Add members to the list of values to
3675 cover the domain of the attribute. This makes the expanded COND form
3676 order independent. */
3678 space = (struct dimension *) xmalloc (ndim * sizeof (struct dimension));
3680 total = 1;
3681 for (ndim = 0; list; ndim++)
3683 /* Pull the first attribute value from the list and record that
3684 attribute as another dimension in the attribute space. */
3685 const char *name = XSTR (XEXP (list, 0), 0);
3686 rtx *prev;
3688 if ((space[ndim].attr = find_attr (name, 0)) == 0
3689 || space[ndim].attr->is_numeric)
3691 unmark_used_attributes (list, space, ndim);
3692 return exp;
3695 /* Add all remaining attribute values that refer to this attribute. */
3696 space[ndim].num_values = 0;
3697 space[ndim].values = 0;
3698 prev = &list;
3699 for (link = list; link; link = *prev)
3700 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3702 space[ndim].num_values++;
3703 *prev = XEXP (link, 1);
3704 XEXP (link, 1) = space[ndim].values;
3705 space[ndim].values = link;
3707 else
3708 prev = &XEXP (link, 1);
3710 /* Add sufficient members to the list of values to make the list
3711 mutually exclusive and record the total size of the attribute
3712 space. */
3713 total *= add_values_to_cover (&space[ndim]);
3716 /* Sort the attribute space so that the attributes go from non-constant
3717 to constant and from most values to least values. */
3718 for (i = 0; i < ndim; i++)
3719 for (j = ndim - 1; j > i; j--)
3720 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3721 || space[j-1].num_values < space[j].num_values)
3723 struct dimension tmp;
3724 tmp = space[j];
3725 space[j] = space[j - 1];
3726 space[j - 1] = tmp;
3729 /* Establish the initial current value. */
3730 for (i = 0; i < ndim; i++)
3731 space[i].current_value = space[i].values;
3733 condtest = (rtx *) xmalloc (total * sizeof (rtx));
3734 condval = (rtx *) xmalloc (total * sizeof (rtx));
3736 /* Expand the tests and values by iterating over all values in the
3737 attribute space. */
3738 for (i = 0;; i++)
3740 condtest[i] = test_for_current_value (space, ndim);
3741 condval[i] = simplify_with_current_value (exp, space, ndim);
3742 if (! increment_current_value (space, ndim))
3743 break;
3745 if (i != total - 1)
3746 abort ();
3748 /* We are now finished with the original expression. */
3749 unmark_used_attributes (0, space, ndim);
3750 free (space);
3752 /* Find the most used constant value and make that the default. */
3753 most_tests = -1;
3754 for (i = num_marks = 0; i < total; i++)
3755 if (GET_CODE (condval[i]) == CONST_STRING
3756 && ! MEM_VOLATILE_P (condval[i]))
3758 /* Mark the unmarked constant value and count how many are marked. */
3759 MEM_VOLATILE_P (condval[i]) = 1;
3760 for (j = new_marks = 0; j < total; j++)
3761 if (GET_CODE (condval[j]) == CONST_STRING
3762 && MEM_VOLATILE_P (condval[j]))
3763 new_marks++;
3764 if (new_marks - num_marks > most_tests)
3766 most_tests = new_marks - num_marks;
3767 defval = condval[i];
3769 num_marks = new_marks;
3771 /* Clear all the marks. */
3772 for (i = 0; i < total; i++)
3773 MEM_VOLATILE_P (condval[i]) = 0;
3775 /* Give up if nothing is constant. */
3776 if (num_marks == 0)
3777 ret = exp;
3779 /* If all values are the default, use that. */
3780 else if (total == most_tests)
3781 ret = defval;
3783 /* Make a COND with the most common constant value the default. (A more
3784 complex method where tests with the same value were combined didn't
3785 seem to improve things.) */
3786 else
3788 condexp = rtx_alloc (COND);
3789 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3790 XEXP (condexp, 1) = defval;
3791 for (i = j = 0; i < total; i++)
3792 if (condval[i] != defval)
3794 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3795 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3796 j++;
3798 ret = condexp;
3800 free (condtest);
3801 free (condval);
3802 return ret;
3805 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3806 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3807 tests have known value. */
3809 static int
3810 find_and_mark_used_attributes (exp, terms, nterms)
3811 rtx exp, *terms;
3812 int *nterms;
3814 int i;
3816 switch (GET_CODE (exp))
3818 case EQ_ATTR:
3819 if (! MEM_VOLATILE_P (exp))
3821 rtx link = rtx_alloc (EXPR_LIST);
3822 XEXP (link, 0) = exp;
3823 XEXP (link, 1) = *terms;
3824 *terms = link;
3825 *nterms += 1;
3826 MEM_VOLATILE_P (exp) = 1;
3828 return 1;
3830 case CONST_STRING:
3831 case CONST_INT:
3832 return 1;
3834 case IF_THEN_ELSE:
3835 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3836 return 0;
3837 case IOR:
3838 case AND:
3839 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3840 return 0;
3841 case NOT:
3842 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3843 return 0;
3844 return 1;
3846 case COND:
3847 for (i = 0; i < XVECLEN (exp, 0); i++)
3848 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3849 return 0;
3850 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3851 return 0;
3852 return 1;
3854 default:
3855 return 0;
3859 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3860 in the values of the NDIM-dimensional attribute space SPACE. */
3862 static void
3863 unmark_used_attributes (list, space, ndim)
3864 rtx list;
3865 struct dimension *space;
3866 int ndim;
3868 rtx link, exp;
3869 int i;
3871 for (i = 0; i < ndim; i++)
3872 unmark_used_attributes (space[i].values, 0, 0);
3874 for (link = list; link; link = XEXP (link, 1))
3876 exp = XEXP (link, 0);
3877 if (GET_CODE (exp) == EQ_ATTR)
3878 MEM_VOLATILE_P (exp) = 0;
3882 /* Update the attribute dimension DIM so that all values of the attribute
3883 are tested. Return the updated number of values. */
3885 static int
3886 add_values_to_cover (dim)
3887 struct dimension *dim;
3889 struct attr_value *av;
3890 rtx exp, link, *prev;
3891 int nalt = 0;
3893 for (av = dim->attr->first_value; av; av = av->next)
3894 if (GET_CODE (av->value) == CONST_STRING)
3895 nalt++;
3897 if (nalt < dim->num_values)
3898 abort ();
3899 else if (nalt == dim->num_values)
3900 /* OK. */
3902 else if (nalt * 2 < dim->num_values * 3)
3904 /* Most all the values of the attribute are used, so add all the unused
3905 values. */
3906 prev = &dim->values;
3907 for (link = dim->values; link; link = *prev)
3908 prev = &XEXP (link, 1);
3910 for (av = dim->attr->first_value; av; av = av->next)
3911 if (GET_CODE (av->value) == CONST_STRING)
3913 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3914 if (MEM_VOLATILE_P (exp))
3915 continue;
3917 link = rtx_alloc (EXPR_LIST);
3918 XEXP (link, 0) = exp;
3919 XEXP (link, 1) = 0;
3920 *prev = link;
3921 prev = &XEXP (link, 1);
3923 dim->num_values = nalt;
3925 else
3927 rtx orexp = false_rtx;
3929 /* Very few values are used, so compute a mutually exclusive
3930 expression. (We could do this for numeric values if that becomes
3931 important.) */
3932 prev = &dim->values;
3933 for (link = dim->values; link; link = *prev)
3935 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3936 prev = &XEXP (link, 1);
3938 link = rtx_alloc (EXPR_LIST);
3939 XEXP (link, 0) = attr_rtx (NOT, orexp);
3940 XEXP (link, 1) = 0;
3941 *prev = link;
3942 dim->num_values++;
3944 return dim->num_values;
3947 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3948 and return FALSE if the increment overflowed. */
3950 static int
3951 increment_current_value (space, ndim)
3952 struct dimension *space;
3953 int ndim;
3955 int i;
3957 for (i = ndim - 1; i >= 0; i--)
3959 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3960 space[i].current_value = space[i].values;
3961 else
3962 return 1;
3964 return 0;
3967 /* Construct an expression corresponding to the current value for the
3968 NDIM-dimensional attribute space SPACE. */
3970 static rtx
3971 test_for_current_value (space, ndim)
3972 struct dimension *space;
3973 int ndim;
3975 int i;
3976 rtx exp = true_rtx;
3978 for (i = 0; i < ndim; i++)
3979 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3980 -2, -2);
3982 return exp;
3985 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3986 set the corresponding EQ_ATTR expressions to that value and reduce
3987 the expression EXP as much as possible. On input [and output], all
3988 known EQ_ATTR expressions are set to FALSE. */
3990 static rtx
3991 simplify_with_current_value (exp, space, ndim)
3992 rtx exp;
3993 struct dimension *space;
3994 int ndim;
3996 int i;
3997 rtx x;
3999 /* Mark each current value as TRUE. */
4000 for (i = 0; i < ndim; i++)
4002 x = XEXP (space[i].current_value, 0);
4003 if (GET_CODE (x) == EQ_ATTR)
4004 MEM_VOLATILE_P (x) = 0;
4007 exp = simplify_with_current_value_aux (exp);
4009 /* Change each current value back to FALSE. */
4010 for (i = 0; i < ndim; i++)
4012 x = XEXP (space[i].current_value, 0);
4013 if (GET_CODE (x) == EQ_ATTR)
4014 MEM_VOLATILE_P (x) = 1;
4017 return exp;
4020 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
4021 all EQ_ATTR expressions. */
4023 static rtx
4024 simplify_with_current_value_aux (exp)
4025 rtx exp;
4027 int i;
4028 rtx cond;
4030 switch (GET_CODE (exp))
4032 case EQ_ATTR:
4033 if (MEM_VOLATILE_P (exp))
4034 return false_rtx;
4035 else
4036 return true_rtx;
4037 case CONST_STRING:
4038 case CONST_INT:
4039 return exp;
4041 case IF_THEN_ELSE:
4042 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4043 if (cond == true_rtx)
4044 return simplify_with_current_value_aux (XEXP (exp, 1));
4045 else if (cond == false_rtx)
4046 return simplify_with_current_value_aux (XEXP (exp, 2));
4047 else
4048 return attr_rtx (IF_THEN_ELSE, cond,
4049 simplify_with_current_value_aux (XEXP (exp, 1)),
4050 simplify_with_current_value_aux (XEXP (exp, 2)));
4052 case IOR:
4053 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4054 if (cond == true_rtx)
4055 return cond;
4056 else if (cond == false_rtx)
4057 return simplify_with_current_value_aux (XEXP (exp, 0));
4058 else
4059 return attr_rtx (IOR, cond,
4060 simplify_with_current_value_aux (XEXP (exp, 0)));
4062 case AND:
4063 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4064 if (cond == true_rtx)
4065 return simplify_with_current_value_aux (XEXP (exp, 0));
4066 else if (cond == false_rtx)
4067 return cond;
4068 else
4069 return attr_rtx (AND, cond,
4070 simplify_with_current_value_aux (XEXP (exp, 0)));
4072 case NOT:
4073 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4074 if (cond == true_rtx)
4075 return false_rtx;
4076 else if (cond == false_rtx)
4077 return true_rtx;
4078 else
4079 return attr_rtx (NOT, cond);
4081 case COND:
4082 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4084 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
4085 if (cond == true_rtx)
4086 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4087 else if (cond == false_rtx)
4088 continue;
4089 else
4090 abort (); /* With all EQ_ATTR's of known value, a case should
4091 have been selected. */
4093 return simplify_with_current_value_aux (XEXP (exp, 1));
4095 default:
4096 abort ();
4100 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4102 static void
4103 clear_struct_flag (x)
4104 rtx x;
4106 int i;
4107 int j;
4108 enum rtx_code code;
4109 const char *fmt;
4111 MEM_IN_STRUCT_P (x) = 0;
4112 if (RTX_UNCHANGING_P (x))
4113 return;
4115 code = GET_CODE (x);
4117 switch (code)
4119 case REG:
4120 case QUEUED:
4121 case CONST_INT:
4122 case CONST_DOUBLE:
4123 case SYMBOL_REF:
4124 case CODE_LABEL:
4125 case PC:
4126 case CC0:
4127 case EQ_ATTR:
4128 case ATTR_FLAG:
4129 return;
4131 default:
4132 break;
4135 /* Compare the elements. If any pair of corresponding elements
4136 fail to match, return 0 for the whole things. */
4138 fmt = GET_RTX_FORMAT (code);
4139 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4141 switch (fmt[i])
4143 case 'V':
4144 case 'E':
4145 for (j = 0; j < XVECLEN (x, i); j++)
4146 clear_struct_flag (XVECEXP (x, i, j));
4147 break;
4149 case 'e':
4150 clear_struct_flag (XEXP (x, i));
4151 break;
4156 /* Return the number of RTX objects making up the expression X.
4157 But if we count more than MAX objects, stop counting. */
4159 static int
4160 count_sub_rtxs (x, max)
4161 rtx x;
4162 int max;
4164 int i;
4165 int j;
4166 enum rtx_code code;
4167 const char *fmt;
4168 int total = 0;
4170 code = GET_CODE (x);
4172 switch (code)
4174 case REG:
4175 case QUEUED:
4176 case CONST_INT:
4177 case CONST_DOUBLE:
4178 case SYMBOL_REF:
4179 case CODE_LABEL:
4180 case PC:
4181 case CC0:
4182 case EQ_ATTR:
4183 case ATTR_FLAG:
4184 return 1;
4186 default:
4187 break;
4190 /* Compare the elements. If any pair of corresponding elements
4191 fail to match, return 0 for the whole things. */
4193 fmt = GET_RTX_FORMAT (code);
4194 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4196 if (total >= max)
4197 return total;
4199 switch (fmt[i])
4201 case 'V':
4202 case 'E':
4203 for (j = 0; j < XVECLEN (x, i); j++)
4204 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4205 break;
4207 case 'e':
4208 total += count_sub_rtxs (XEXP (x, i), max);
4209 break;
4212 return total;
4216 /* Create table entries for DEFINE_ATTR. */
4218 static void
4219 gen_attr (exp, lineno)
4220 rtx exp;
4221 int lineno;
4223 struct attr_desc *attr;
4224 struct attr_value *av;
4225 const char *name_ptr;
4226 char *p;
4228 /* Make a new attribute structure. Check for duplicate by looking at
4229 attr->default_val, since it is initialized by this routine. */
4230 attr = find_attr (XSTR (exp, 0), 1);
4231 if (attr->default_val)
4233 message_with_line (lineno, "duplicate definition for attribute %s",
4234 attr->name);
4235 message_with_line (attr->lineno, "previous definition");
4236 have_error = 1;
4237 return;
4239 attr->lineno = lineno;
4241 if (*XSTR (exp, 1) == '\0')
4242 attr->is_numeric = 1;
4243 else
4245 name_ptr = XSTR (exp, 1);
4246 while ((p = next_comma_elt (&name_ptr)) != NULL)
4248 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4249 av->value = attr_rtx (CONST_STRING, p);
4250 av->next = attr->first_value;
4251 attr->first_value = av;
4252 av->first_insn = NULL;
4253 av->num_insns = 0;
4254 av->has_asm_insn = 0;
4258 if (GET_CODE (XEXP (exp, 2)) == CONST)
4260 attr->is_const = 1;
4261 if (attr->is_numeric)
4263 message_with_line (lineno,
4264 "constant attributes may not take numeric values");
4265 have_error = 1;
4268 /* Get rid of the CONST node. It is allowed only at top-level. */
4269 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4272 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4274 message_with_line (lineno,
4275 "`length' attribute must take numeric values");
4276 have_error = 1;
4279 /* Set up the default value. */
4280 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4281 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4284 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4285 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4286 number of alternatives as this should be checked elsewhere. */
4288 static int
4289 count_alternatives (exp)
4290 rtx exp;
4292 int i, j, n;
4293 const char *fmt;
4295 if (GET_CODE (exp) == MATCH_OPERAND)
4296 return n_comma_elts (XSTR (exp, 2));
4298 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4299 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4300 switch (*fmt++)
4302 case 'e':
4303 case 'u':
4304 n = count_alternatives (XEXP (exp, i));
4305 if (n)
4306 return n;
4307 break;
4309 case 'E':
4310 case 'V':
4311 if (XVEC (exp, i) != NULL)
4312 for (j = 0; j < XVECLEN (exp, i); j++)
4314 n = count_alternatives (XVECEXP (exp, i, j));
4315 if (n)
4316 return n;
4320 return 0;
4323 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4324 `alternative' attribute. */
4326 static int
4327 compares_alternatives_p (exp)
4328 rtx exp;
4330 int i, j;
4331 const char *fmt;
4333 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4334 return 1;
4336 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4337 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4338 switch (*fmt++)
4340 case 'e':
4341 case 'u':
4342 if (compares_alternatives_p (XEXP (exp, i)))
4343 return 1;
4344 break;
4346 case 'E':
4347 for (j = 0; j < XVECLEN (exp, i); j++)
4348 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4349 return 1;
4350 break;
4353 return 0;
4356 /* Returns non-zero is INNER is contained in EXP. */
4358 static int
4359 contained_in_p (inner, exp)
4360 rtx inner;
4361 rtx exp;
4363 int i, j;
4364 const char *fmt;
4366 if (rtx_equal_p (inner, exp))
4367 return 1;
4369 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4370 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4371 switch (*fmt++)
4373 case 'e':
4374 case 'u':
4375 if (contained_in_p (inner, XEXP (exp, i)))
4376 return 1;
4377 break;
4379 case 'E':
4380 for (j = 0; j < XVECLEN (exp, i); j++)
4381 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4382 return 1;
4383 break;
4386 return 0;
4389 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4391 static void
4392 gen_insn (exp, lineno)
4393 rtx exp;
4394 int lineno;
4396 struct insn_def *id;
4398 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4399 id->next = defs;
4400 defs = id;
4401 id->def = exp;
4402 id->lineno = lineno;
4404 switch (GET_CODE (exp))
4406 case DEFINE_INSN:
4407 id->insn_code = insn_code_number;
4408 id->insn_index = insn_index_number;
4409 id->num_alternatives = count_alternatives (exp);
4410 if (id->num_alternatives == 0)
4411 id->num_alternatives = 1;
4412 id->vec_idx = 4;
4413 break;
4415 case DEFINE_PEEPHOLE:
4416 id->insn_code = insn_code_number;
4417 id->insn_index = insn_index_number;
4418 id->num_alternatives = count_alternatives (exp);
4419 if (id->num_alternatives == 0)
4420 id->num_alternatives = 1;
4421 id->vec_idx = 3;
4422 break;
4424 case DEFINE_ASM_ATTRIBUTES:
4425 id->insn_code = -1;
4426 id->insn_index = -1;
4427 id->num_alternatives = 1;
4428 id->vec_idx = 0;
4429 got_define_asm_attributes = 1;
4430 break;
4432 default:
4433 abort ();
4437 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4438 true or annul false is specified, and make a `struct delay_desc'. */
4440 static void
4441 gen_delay (def, lineno)
4442 rtx def;
4443 int lineno;
4445 struct delay_desc *delay;
4446 int i;
4448 if (XVECLEN (def, 1) % 3 != 0)
4450 message_with_line (lineno,
4451 "number of elements in DEFINE_DELAY must be multiple of three");
4452 have_error = 1;
4453 return;
4456 for (i = 0; i < XVECLEN (def, 1); i += 3)
4458 if (XVECEXP (def, 1, i + 1))
4459 have_annul_true = 1;
4460 if (XVECEXP (def, 1, i + 2))
4461 have_annul_false = 1;
4464 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4465 delay->def = def;
4466 delay->num = ++num_delays;
4467 delay->next = delays;
4468 delay->lineno = lineno;
4469 delays = delay;
4472 /* Process a DEFINE_FUNCTION_UNIT.
4474 This gives information about a function unit contained in the CPU.
4475 We fill in a `struct function_unit_op' and a `struct function_unit'
4476 with information used later by `expand_unit'. */
4478 static void
4479 gen_unit (def, lineno)
4480 rtx def;
4481 int lineno;
4483 struct function_unit *unit;
4484 struct function_unit_op *op;
4485 const char *name = XSTR (def, 0);
4486 int multiplicity = XINT (def, 1);
4487 int simultaneity = XINT (def, 2);
4488 rtx condexp = XEXP (def, 3);
4489 int ready_cost = MAX (XINT (def, 4), 1);
4490 int issue_delay = MAX (XINT (def, 5), 1);
4492 /* See if we have already seen this function unit. If so, check that
4493 the multiplicity and simultaneity values are the same. If not, make
4494 a structure for this function unit. */
4495 for (unit = units; unit; unit = unit->next)
4496 if (! strcmp (unit->name, name))
4498 if (unit->multiplicity != multiplicity
4499 || unit->simultaneity != simultaneity)
4501 message_with_line (lineno,
4502 "differing specifications given for function unit %s",
4503 unit->name);
4504 message_with_line (unit->first_lineno, "previous definition");
4505 have_error = 1;
4506 return;
4508 break;
4511 if (unit == 0)
4513 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4514 unit->name = name;
4515 unit->multiplicity = multiplicity;
4516 unit->simultaneity = simultaneity;
4517 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4518 unit->num = num_units++;
4519 unit->num_opclasses = 0;
4520 unit->condexp = false_rtx;
4521 unit->ops = 0;
4522 unit->next = units;
4523 unit->first_lineno = lineno;
4524 units = unit;
4527 /* Make a new operation class structure entry and initialize it. */
4528 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4529 op->condexp = condexp;
4530 op->num = unit->num_opclasses++;
4531 op->ready = ready_cost;
4532 op->issue_delay = issue_delay;
4533 op->next = unit->ops;
4534 op->lineno = lineno;
4535 unit->ops = op;
4536 num_unit_opclasses++;
4538 /* Set our issue expression based on whether or not an optional conflict
4539 vector was specified. */
4540 if (XVEC (def, 6))
4542 /* Compute the IOR of all the specified expressions. */
4543 rtx orexp = false_rtx;
4544 int i;
4546 for (i = 0; i < XVECLEN (def, 6); i++)
4547 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4549 op->conflict_exp = orexp;
4550 extend_range (&unit->issue_delay, 1, issue_delay);
4552 else
4554 op->conflict_exp = true_rtx;
4555 extend_range (&unit->issue_delay, issue_delay, issue_delay);
4558 /* Merge our conditional into that of the function unit so we can determine
4559 which insns are used by the function unit. */
4560 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4563 /* Given a piece of RTX, print a C expression to test its truth value.
4564 We use AND and IOR both for logical and bit-wise operations, so
4565 interpret them as logical unless they are inside a comparison expression.
4566 The first bit of FLAGS will be non-zero in that case.
4568 Set the second bit of FLAGS to make references to attribute values use
4569 a cached local variable instead of calling a function. */
4571 static void
4572 write_test_expr (exp, flags)
4573 rtx exp;
4574 int flags;
4576 int comparison_operator = 0;
4577 RTX_CODE code;
4578 struct attr_desc *attr;
4580 /* In order not to worry about operator precedence, surround our part of
4581 the expression with parentheses. */
4583 printf ("(");
4584 code = GET_CODE (exp);
4585 switch (code)
4587 /* Binary operators. */
4588 case EQ: case NE:
4589 case GE: case GT: case GEU: case GTU:
4590 case LE: case LT: case LEU: case LTU:
4591 comparison_operator = 1;
4593 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4594 case AND: case IOR: case XOR:
4595 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4596 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
4597 switch (code)
4599 case EQ:
4600 printf (" == ");
4601 break;
4602 case NE:
4603 printf (" != ");
4604 break;
4605 case GE:
4606 printf (" >= ");
4607 break;
4608 case GT:
4609 printf (" > ");
4610 break;
4611 case GEU:
4612 printf (" >= (unsigned) ");
4613 break;
4614 case GTU:
4615 printf (" > (unsigned) ");
4616 break;
4617 case LE:
4618 printf (" <= ");
4619 break;
4620 case LT:
4621 printf (" < ");
4622 break;
4623 case LEU:
4624 printf (" <= (unsigned) ");
4625 break;
4626 case LTU:
4627 printf (" < (unsigned) ");
4628 break;
4629 case PLUS:
4630 printf (" + ");
4631 break;
4632 case MINUS:
4633 printf (" - ");
4634 break;
4635 case MULT:
4636 printf (" * ");
4637 break;
4638 case DIV:
4639 printf (" / ");
4640 break;
4641 case MOD:
4642 printf (" %% ");
4643 break;
4644 case AND:
4645 if (flags & 1)
4646 printf (" & ");
4647 else
4648 printf (" && ");
4649 break;
4650 case IOR:
4651 if (flags & 1)
4652 printf (" | ");
4653 else
4654 printf (" || ");
4655 break;
4656 case XOR:
4657 printf (" ^ ");
4658 break;
4659 case ASHIFT:
4660 printf (" << ");
4661 break;
4662 case LSHIFTRT:
4663 case ASHIFTRT:
4664 printf (" >> ");
4665 break;
4666 default:
4667 abort ();
4670 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
4671 break;
4673 case NOT:
4674 /* Special-case (not (eq_attrq "alternative" "x")) */
4675 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4676 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4678 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4679 break;
4682 /* Otherwise, fall through to normal unary operator. */
4684 /* Unary operators. */
4685 case ABS: case NEG:
4686 switch (code)
4688 case NOT:
4689 if (flags & 1)
4690 printf ("~ ");
4691 else
4692 printf ("! ");
4693 break;
4694 case ABS:
4695 printf ("abs ");
4696 break;
4697 case NEG:
4698 printf ("-");
4699 break;
4700 default:
4701 abort ();
4704 write_test_expr (XEXP (exp, 0), flags);
4705 break;
4707 /* Comparison test of an attribute with a value. Most of these will
4708 have been removed by optimization. Handle "alternative"
4709 specially and give error if EQ_ATTR present inside a comparison. */
4710 case EQ_ATTR:
4711 if (flags & 1)
4712 fatal ("EQ_ATTR not valid inside comparison");
4714 if (XSTR (exp, 0) == alternative_name)
4716 printf ("which_alternative == %s", XSTR (exp, 1));
4717 break;
4720 attr = find_attr (XSTR (exp, 0), 0);
4721 if (! attr)
4722 abort ();
4724 /* Now is the time to expand the value of a constant attribute. */
4725 if (attr->is_const)
4727 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4728 -2, -2),
4729 flags);
4731 else
4733 if (flags & 2)
4734 printf ("attr_%s", attr->name);
4735 else
4736 printf ("get_attr_%s (insn)", attr->name);
4737 printf (" == ");
4738 write_attr_valueq (attr, XSTR (exp, 1));
4740 break;
4742 /* Comparison test of flags for define_delays. */
4743 case ATTR_FLAG:
4744 if (flags & 1)
4745 fatal ("ATTR_FLAG not valid inside comparison");
4746 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4747 break;
4749 /* See if an operand matches a predicate. */
4750 case MATCH_OPERAND:
4751 /* If only a mode is given, just ensure the mode matches the operand.
4752 If neither a mode nor predicate is given, error. */
4753 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4755 if (GET_MODE (exp) == VOIDmode)
4756 fatal ("Null MATCH_OPERAND specified as test");
4757 else
4758 printf ("GET_MODE (operands[%d]) == %smode",
4759 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4761 else
4762 printf ("%s (operands[%d], %smode)",
4763 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4764 break;
4766 case MATCH_INSN:
4767 printf ("%s (insn)", XSTR (exp, 0));
4768 break;
4770 /* Constant integer. */
4771 case CONST_INT:
4772 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
4773 break;
4775 /* A random C expression. */
4776 case SYMBOL_REF:
4777 printf ("%s", XSTR (exp, 0));
4778 break;
4780 /* The address of the branch target. */
4781 case MATCH_DUP:
4782 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
4783 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4784 break;
4786 case PC:
4787 /* The address of the current insn. We implement this actually as the
4788 address of the current insn for backward branches, but the last
4789 address of the next insn for forward branches, and both with
4790 adjustments that account for the worst-case possible stretching of
4791 intervening alignments between this insn and its destination. */
4792 printf ("insn_current_reference_address (insn)");
4793 break;
4795 case CONST_STRING:
4796 printf ("%s", XSTR (exp, 0));
4797 break;
4799 case IF_THEN_ELSE:
4800 write_test_expr (XEXP (exp, 0), flags & 2);
4801 printf (" ? ");
4802 write_test_expr (XEXP (exp, 1), flags | 1);
4803 printf (" : ");
4804 write_test_expr (XEXP (exp, 2), flags | 1);
4805 break;
4807 default:
4808 fatal ("bad RTX code `%s' in attribute calculation\n",
4809 GET_RTX_NAME (code));
4812 printf (")");
4815 /* Given an attribute value, return the maximum CONST_STRING argument
4816 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
4818 static int
4819 max_attr_value (exp, unknownp)
4820 rtx exp;
4821 int *unknownp;
4823 int current_max;
4824 int i, n;
4826 switch (GET_CODE (exp))
4828 case CONST_STRING:
4829 current_max = atoi (XSTR (exp, 0));
4830 break;
4832 case COND:
4833 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4834 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4836 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4837 if (n > current_max)
4838 current_max = n;
4840 break;
4842 case IF_THEN_ELSE:
4843 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4844 n = max_attr_value (XEXP (exp, 2), unknownp);
4845 if (n > current_max)
4846 current_max = n;
4847 break;
4849 default:
4850 *unknownp = 1;
4851 current_max = INT_MAX;
4852 break;
4855 return current_max;
4858 /* Given an attribute value, return the result of ORing together all
4859 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4860 if the numeric value is not known. */
4862 static int
4863 or_attr_value (exp, unknownp)
4864 rtx exp;
4865 int *unknownp;
4867 int current_or;
4868 int i;
4870 switch (GET_CODE (exp))
4872 case CONST_STRING:
4873 current_or = atoi (XSTR (exp, 0));
4874 break;
4876 case COND:
4877 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4878 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4879 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4880 break;
4882 case IF_THEN_ELSE:
4883 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4884 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4885 break;
4887 default:
4888 *unknownp = 1;
4889 current_or = -1;
4890 break;
4893 return current_or;
4896 /* Scan an attribute value, possibly a conditional, and record what actions
4897 will be required to do any conditional tests in it.
4899 Specifically, set
4900 `must_extract' if we need to extract the insn operands
4901 `must_constrain' if we must compute `which_alternative'
4902 `address_used' if an address expression was used
4903 `length_used' if an (eq_attr "length" ...) was used
4906 static void
4907 walk_attr_value (exp)
4908 rtx exp;
4910 int i, j;
4911 const char *fmt;
4912 RTX_CODE code;
4914 if (exp == NULL)
4915 return;
4917 code = GET_CODE (exp);
4918 switch (code)
4920 case SYMBOL_REF:
4921 if (! RTX_UNCHANGING_P (exp))
4922 /* Since this is an arbitrary expression, it can look at anything.
4923 However, constant expressions do not depend on any particular
4924 insn. */
4925 must_extract = must_constrain = 1;
4926 return;
4928 case MATCH_OPERAND:
4929 must_extract = 1;
4930 return;
4932 case EQ_ATTR:
4933 if (XSTR (exp, 0) == alternative_name)
4934 must_extract = must_constrain = 1;
4935 else if (strcmp (XSTR (exp, 0), "length") == 0)
4936 length_used = 1;
4937 return;
4939 case MATCH_DUP:
4940 must_extract = 1;
4941 address_used = 1;
4942 return;
4944 case PC:
4945 address_used = 1;
4946 return;
4948 case ATTR_FLAG:
4949 return;
4951 default:
4952 break;
4955 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4956 switch (*fmt++)
4958 case 'e':
4959 case 'u':
4960 walk_attr_value (XEXP (exp, i));
4961 break;
4963 case 'E':
4964 if (XVEC (exp, i) != NULL)
4965 for (j = 0; j < XVECLEN (exp, i); j++)
4966 walk_attr_value (XVECEXP (exp, i, j));
4967 break;
4971 /* Write out a function to obtain the attribute for a given INSN. */
4973 static void
4974 write_attr_get (attr)
4975 struct attr_desc *attr;
4977 struct attr_value *av, *common_av;
4979 /* Find the most used attribute value. Handle that as the `default' of the
4980 switch we will generate. */
4981 common_av = find_most_used (attr);
4983 /* Write out prototype of function. */
4984 if (!attr->is_numeric)
4985 printf ("extern enum attr_%s ", attr->name);
4986 else if (attr->unsigned_p)
4987 printf ("extern unsigned int ");
4988 else
4989 printf ("extern int ");
4990 /* If the attribute name starts with a star, the remainder is the name of
4991 the subroutine to use, instead of `get_attr_...'. */
4992 if (attr->name[0] == '*')
4993 printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
4994 else
4995 printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
4996 (attr->is_const ? "void" : "rtx"));
4998 /* Write out start of function, then all values with explicit `case' lines,
4999 then a `default', then the value with the most uses. */
5000 if (!attr->is_numeric)
5001 printf ("enum attr_%s\n", attr->name);
5002 else if (attr->unsigned_p)
5003 printf ("unsigned int\n");
5004 else
5005 printf ("int\n");
5007 /* If the attribute name starts with a star, the remainder is the name of
5008 the subroutine to use, instead of `get_attr_...'. */
5009 if (attr->name[0] == '*')
5010 printf ("%s (insn)\n", &attr->name[1]);
5011 else if (attr->is_const == 0)
5012 printf ("get_attr_%s (insn)\n", attr->name);
5013 else
5015 printf ("get_attr_%s ()\n", attr->name);
5016 printf ("{\n");
5018 for (av = attr->first_value; av; av = av->next)
5019 if (av->num_insns != 0)
5020 write_attr_set (attr, 2, av->value, "return", ";",
5021 true_rtx, av->first_insn->insn_code,
5022 av->first_insn->insn_index);
5024 printf ("}\n\n");
5025 return;
5028 printf (" rtx insn;\n");
5029 printf ("{\n");
5031 if (GET_CODE (common_av->value) == FFS)
5033 rtx p = XEXP (common_av->value, 0);
5035 /* No need to emit code to abort if the insn is unrecognized; the
5036 other get_attr_foo functions will do that when we call them. */
5038 write_toplevel_expr (p);
5040 printf ("\n if (accum && accum == (accum & -accum))\n");
5041 printf (" {\n");
5042 printf (" int i;\n");
5043 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
5044 printf (" accum = i;\n");
5045 printf (" }\n else\n");
5046 printf (" accum = ~accum;\n");
5047 printf (" return accum;\n}\n\n");
5049 else
5051 printf (" switch (recog_memoized (insn))\n");
5052 printf (" {\n");
5054 for (av = attr->first_value; av; av = av->next)
5055 if (av != common_av)
5056 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5058 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5059 printf (" }\n}\n\n");
5063 /* Given an AND tree of known true terms (because we are inside an `if' with
5064 that as the condition or are in an `else' clause) and an expression,
5065 replace any known true terms with TRUE. Use `simplify_and_tree' to do
5066 the bulk of the work. */
5068 static rtx
5069 eliminate_known_true (known_true, exp, insn_code, insn_index)
5070 rtx known_true;
5071 rtx exp;
5072 int insn_code, insn_index;
5074 rtx term;
5076 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
5078 if (GET_CODE (known_true) == AND)
5080 exp = eliminate_known_true (XEXP (known_true, 0), exp,
5081 insn_code, insn_index);
5082 exp = eliminate_known_true (XEXP (known_true, 1), exp,
5083 insn_code, insn_index);
5085 else
5087 term = known_true;
5088 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
5091 return exp;
5094 /* Write out a series of tests and assignment statements to perform tests and
5095 sets of an attribute value. We are passed an indentation amount and prefix
5096 and suffix strings to write around each attribute value (e.g., "return"
5097 and ";"). */
5099 static void
5100 write_attr_set (attr, indent, value, prefix, suffix, known_true,
5101 insn_code, insn_index)
5102 struct attr_desc *attr;
5103 int indent;
5104 rtx value;
5105 const char *prefix;
5106 const char *suffix;
5107 rtx known_true;
5108 int insn_code, insn_index;
5110 if (GET_CODE (value) == COND)
5112 /* Assume the default value will be the default of the COND unless we
5113 find an always true expression. */
5114 rtx default_val = XEXP (value, 1);
5115 rtx our_known_true = known_true;
5116 rtx newexp;
5117 int first_if = 1;
5118 int i;
5120 for (i = 0; i < XVECLEN (value, 0); i += 2)
5122 rtx testexp;
5123 rtx inner_true;
5125 testexp = eliminate_known_true (our_known_true,
5126 XVECEXP (value, 0, i),
5127 insn_code, insn_index);
5128 newexp = attr_rtx (NOT, testexp);
5129 newexp = insert_right_side (AND, our_known_true, newexp,
5130 insn_code, insn_index);
5132 /* If the test expression is always true or if the next `known_true'
5133 expression is always false, this is the last case, so break
5134 out and let this value be the `else' case. */
5135 if (testexp == true_rtx || newexp == false_rtx)
5137 default_val = XVECEXP (value, 0, i + 1);
5138 break;
5141 /* Compute the expression to pass to our recursive call as being
5142 known true. */
5143 inner_true = insert_right_side (AND, our_known_true,
5144 testexp, insn_code, insn_index);
5146 /* If this is always false, skip it. */
5147 if (inner_true == false_rtx)
5148 continue;
5150 write_indent (indent);
5151 printf ("%sif ", first_if ? "" : "else ");
5152 first_if = 0;
5153 write_test_expr (testexp, 0);
5154 printf ("\n");
5155 write_indent (indent + 2);
5156 printf ("{\n");
5158 write_attr_set (attr, indent + 4,
5159 XVECEXP (value, 0, i + 1), prefix, suffix,
5160 inner_true, insn_code, insn_index);
5161 write_indent (indent + 2);
5162 printf ("}\n");
5163 our_known_true = newexp;
5166 if (! first_if)
5168 write_indent (indent);
5169 printf ("else\n");
5170 write_indent (indent + 2);
5171 printf ("{\n");
5174 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5175 prefix, suffix, our_known_true, insn_code, insn_index);
5177 if (! first_if)
5179 write_indent (indent + 2);
5180 printf ("}\n");
5183 else
5185 write_indent (indent);
5186 printf ("%s ", prefix);
5187 write_attr_value (attr, value);
5188 printf ("%s\n", suffix);
5192 /* Write out the computation for one attribute value. */
5194 static void
5195 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5196 known_true)
5197 struct attr_desc *attr;
5198 struct attr_value *av;
5199 int write_case_lines;
5200 const char *prefix, *suffix;
5201 int indent;
5202 rtx known_true;
5204 struct insn_ent *ie;
5206 if (av->num_insns == 0)
5207 return;
5209 if (av->has_asm_insn)
5211 write_indent (indent);
5212 printf ("case -1:\n");
5213 write_indent (indent + 2);
5214 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5215 write_indent (indent + 2);
5216 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5217 write_indent (indent + 2);
5218 printf (" fatal_insn_not_found (insn);\n");
5221 if (write_case_lines)
5223 for (ie = av->first_insn; ie; ie = ie->next)
5224 if (ie->insn_code != -1)
5226 write_indent (indent);
5227 printf ("case %d:\n", ie->insn_code);
5230 else
5232 write_indent (indent);
5233 printf ("default:\n");
5236 /* See what we have to do to output this value. */
5237 must_extract = must_constrain = address_used = 0;
5238 walk_attr_value (av->value);
5240 if (must_constrain)
5242 write_indent (indent + 2);
5243 printf ("extract_constrain_insn_cached (insn);\n");
5245 else if (must_extract)
5247 write_indent (indent + 2);
5248 printf ("extract_insn_cached (insn);\n");
5251 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5252 known_true, av->first_insn->insn_code,
5253 av->first_insn->insn_index);
5255 if (strncmp (prefix, "return", 6))
5257 write_indent (indent + 2);
5258 printf ("break;\n");
5260 printf ("\n");
5263 /* Search for uses of non-const attributes and write code to cache them. */
5265 static int
5266 write_expr_attr_cache (p, attr)
5267 rtx p;
5268 struct attr_desc *attr;
5270 const char *fmt;
5271 int i, ie, j, je;
5273 if (GET_CODE (p) == EQ_ATTR)
5275 if (XSTR (p, 0) != attr->name)
5276 return 0;
5278 if (!attr->is_numeric)
5279 printf (" enum attr_%s ", attr->name);
5280 else if (attr->unsigned_p)
5281 printf (" unsigned int ");
5282 else
5283 printf (" int ");
5285 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5286 return 1;
5289 fmt = GET_RTX_FORMAT (GET_CODE (p));
5290 ie = GET_RTX_LENGTH (GET_CODE (p));
5291 for (i = 0; i < ie; i++)
5293 switch (*fmt++)
5295 case 'e':
5296 if (write_expr_attr_cache (XEXP (p, i), attr))
5297 return 1;
5298 break;
5300 case 'E':
5301 je = XVECLEN (p, i);
5302 for (j = 0; j < je; ++j)
5303 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5304 return 1;
5305 break;
5309 return 0;
5312 /* Evaluate an expression at top level. A front end to write_test_expr,
5313 in which we cache attribute values and break up excessively large
5314 expressions to cater to older compilers. */
5316 static void
5317 write_toplevel_expr (p)
5318 rtx p;
5320 struct attr_desc *attr;
5321 int i;
5323 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
5324 for (attr = attrs[i]; attr; attr = attr->next)
5325 if (!attr->is_const)
5326 write_expr_attr_cache (p, attr);
5328 printf (" unsigned long accum = 0;\n\n");
5330 while (GET_CODE (p) == IOR)
5332 rtx e;
5333 if (GET_CODE (XEXP (p, 0)) == IOR)
5334 e = XEXP (p, 1), p = XEXP (p, 0);
5335 else
5336 e = XEXP (p, 0), p = XEXP (p, 1);
5338 printf (" accum |= ");
5339 write_test_expr (e, 3);
5340 printf (";\n");
5342 printf (" accum |= ");
5343 write_test_expr (p, 3);
5344 printf (";\n");
5347 /* Utilities to write names in various forms. */
5349 static void
5350 write_unit_name (prefix, num, suffix)
5351 const char *prefix;
5352 int num;
5353 const char *suffix;
5355 struct function_unit *unit;
5357 for (unit = units; unit; unit = unit->next)
5358 if (unit->num == num)
5360 printf ("%s%s%s", prefix, unit->name, suffix);
5361 return;
5364 printf ("%s<unknown>%s", prefix, suffix);
5367 static void
5368 write_attr_valueq (attr, s)
5369 struct attr_desc *attr;
5370 const char *s;
5372 if (attr->is_numeric)
5374 int num = atoi (s);
5376 printf ("%d", num);
5378 /* Make the blockage range values and function units used values easier
5379 to read. */
5380 if (attr->func_units_p)
5382 if (num == -1)
5383 printf (" /* units: none */");
5384 else if (num >= 0)
5385 write_unit_name (" /* units: ", num, " */");
5386 else
5388 int i;
5389 const char *sep = " /* units: ";
5390 for (i = 0, num = ~num; num; i++, num >>= 1)
5391 if (num & 1)
5393 write_unit_name (sep, i, (num == 1) ? " */" : "");
5394 sep = ", ";
5399 else if (attr->blockage_p)
5400 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5401 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5403 else if (num > 9 || num < 0)
5404 printf (" /* 0x%x */", num);
5406 else
5408 write_upcase (attr->name);
5409 printf ("_");
5410 write_upcase (s);
5414 static void
5415 write_attr_value (attr, value)
5416 struct attr_desc *attr;
5417 rtx value;
5419 int op;
5421 switch (GET_CODE (value))
5423 case CONST_STRING:
5424 write_attr_valueq (attr, XSTR (value, 0));
5425 break;
5427 case CONST_INT:
5428 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
5429 break;
5431 case SYMBOL_REF:
5432 fputs (XSTR (value, 0), stdout);
5433 break;
5435 case ATTR:
5437 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
5438 printf ("get_attr_%s (%s)", attr2->name,
5439 (attr2->is_const ? "" : "insn"));
5441 break;
5443 case PLUS:
5444 op = '+';
5445 goto do_operator;
5446 case MINUS:
5447 op = '-';
5448 goto do_operator;
5449 case MULT:
5450 op = '*';
5451 goto do_operator;
5452 case DIV:
5453 op = '/';
5454 goto do_operator;
5455 case MOD:
5456 op = '%';
5457 goto do_operator;
5459 do_operator:
5460 write_attr_value (attr, XEXP (value, 0));
5461 putchar (' ');
5462 putchar (op);
5463 putchar (' ');
5464 write_attr_value (attr, XEXP (value, 1));
5465 break;
5467 default:
5468 abort ();
5472 static void
5473 write_upcase (str)
5474 const char *str;
5476 while (*str)
5478 /* The argument of TOUPPER should not have side effects. */
5479 putchar (TOUPPER(*str));
5480 str++;
5484 static void
5485 write_indent (indent)
5486 int indent;
5488 for (; indent > 8; indent -= 8)
5489 printf ("\t");
5491 for (; indent; indent--)
5492 printf (" ");
5495 /* Write a subroutine that is given an insn that requires a delay slot, a
5496 delay slot ordinal, and a candidate insn. It returns non-zero if the
5497 candidate can be placed in the specified delay slot of the insn.
5499 We can write as many as three subroutines. `eligible_for_delay'
5500 handles normal delay slots, `eligible_for_annul_true' indicates that
5501 the specified insn can be annulled if the branch is true, and likewise
5502 for `eligible_for_annul_false'.
5504 KIND is a string distinguishing these three cases ("delay", "annul_true",
5505 or "annul_false"). */
5507 static void
5508 write_eligible_delay (kind)
5509 const char *kind;
5511 struct delay_desc *delay;
5512 int max_slots;
5513 char str[50];
5514 struct attr_desc *attr;
5515 struct attr_value *av, *common_av;
5516 int i;
5518 /* Compute the maximum number of delay slots required. We use the delay
5519 ordinal times this number plus one, plus the slot number as an index into
5520 the appropriate predicate to test. */
5522 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5523 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5524 max_slots = XVECLEN (delay->def, 1) / 3;
5526 /* Write function prelude. */
5528 printf ("int\n");
5529 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5530 kind);
5531 printf (" rtx delay_insn ATTRIBUTE_UNUSED;\n");
5532 printf (" int slot;\n");
5533 printf (" rtx candidate_insn;\n");
5534 printf (" int flags ATTRIBUTE_UNUSED;\n");
5535 printf ("{\n");
5536 printf (" rtx insn;\n");
5537 printf ("\n");
5538 printf (" if (slot >= %d)\n", max_slots);
5539 printf (" abort ();\n");
5540 printf ("\n");
5542 /* If more than one delay type, find out which type the delay insn is. */
5544 if (num_delays > 1)
5546 attr = find_attr ("*delay_type", 0);
5547 if (! attr)
5548 abort ();
5549 common_av = find_most_used (attr);
5551 printf (" insn = delay_insn;\n");
5552 printf (" switch (recog_memoized (insn))\n");
5553 printf (" {\n");
5555 sprintf (str, " * %d;\n break;", max_slots);
5556 for (av = attr->first_value; av; av = av->next)
5557 if (av != common_av)
5558 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5560 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5561 printf (" }\n\n");
5563 /* Ensure matched. Otherwise, shouldn't have been called. */
5564 printf (" if (slot < %d)\n", max_slots);
5565 printf (" abort ();\n\n");
5568 /* If just one type of delay slot, write simple switch. */
5569 if (num_delays == 1 && max_slots == 1)
5571 printf (" insn = candidate_insn;\n");
5572 printf (" switch (recog_memoized (insn))\n");
5573 printf (" {\n");
5575 attr = find_attr ("*delay_1_0", 0);
5576 if (! attr)
5577 abort ();
5578 common_av = find_most_used (attr);
5580 for (av = attr->first_value; av; av = av->next)
5581 if (av != common_av)
5582 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5584 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5585 printf (" }\n");
5588 else
5590 /* Write a nested CASE. The first indicates which condition we need to
5591 test, and the inner CASE tests the condition. */
5592 printf (" insn = candidate_insn;\n");
5593 printf (" switch (slot)\n");
5594 printf (" {\n");
5596 for (delay = delays; delay; delay = delay->next)
5597 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5599 printf (" case %d:\n",
5600 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5601 printf (" switch (recog_memoized (insn))\n");
5602 printf ("\t{\n");
5604 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5605 attr = find_attr (str, 0);
5606 if (! attr)
5607 abort ();
5608 common_av = find_most_used (attr);
5610 for (av = attr->first_value; av; av = av->next)
5611 if (av != common_av)
5612 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5614 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5615 printf (" }\n");
5618 printf (" default:\n");
5619 printf (" abort ();\n");
5620 printf (" }\n");
5623 printf ("}\n\n");
5626 /* Write routines to compute conflict cost for function units. Then write a
5627 table describing the available function units. */
5629 static void
5630 write_function_unit_info ()
5632 struct function_unit *unit;
5633 int i;
5635 /* Write out conflict routines for function units. Don't bother writing
5636 one if there is only one issue delay value. */
5638 for (unit = units; unit; unit = unit->next)
5640 if (unit->needs_blockage_function)
5641 write_complex_function (unit, "blockage", "block");
5643 /* If the minimum and maximum conflict costs are the same, there
5644 is only one value, so we don't need a function. */
5645 if (! unit->needs_conflict_function)
5647 unit->default_cost = make_numeric_value (unit->issue_delay.max);
5648 continue;
5651 /* The function first computes the case from the candidate insn. */
5652 unit->default_cost = make_numeric_value (0);
5653 write_complex_function (unit, "conflict_cost", "cost");
5656 /* Now that all functions have been written, write the table describing
5657 the function units. The name is included for documentation purposes
5658 only. */
5660 printf ("const struct function_unit_desc function_units[] = {\n");
5662 /* Write out the descriptions in numeric order, but don't force that order
5663 on the list. Doing so increases the runtime of genattrtab.c. */
5664 for (i = 0; i < num_units; i++)
5666 for (unit = units; unit; unit = unit->next)
5667 if (unit->num == i)
5668 break;
5670 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5671 unit->name, 1 << unit->num, unit->multiplicity,
5672 unit->simultaneity, XSTR (unit->default_cost, 0),
5673 unit->issue_delay.max, unit->name);
5675 if (unit->needs_conflict_function)
5676 printf ("%s_unit_conflict_cost, ", unit->name);
5677 else
5678 printf ("0, ");
5680 printf ("%d, ", unit->max_blockage);
5682 if (unit->needs_range_function)
5683 printf ("%s_unit_blockage_range, ", unit->name);
5684 else
5685 printf ("0, ");
5687 if (unit->needs_blockage_function)
5688 printf ("%s_unit_blockage", unit->name);
5689 else
5690 printf ("0");
5692 printf ("}, \n");
5695 printf ("};\n\n");
5698 static void
5699 write_complex_function (unit, name, connection)
5700 struct function_unit *unit;
5701 const char *name, *connection;
5703 struct attr_desc *case_attr, *attr;
5704 struct attr_value *av, *common_av;
5705 rtx value;
5706 char str[256];
5707 int using_case;
5708 int i;
5710 printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
5711 printf ("static int\n");
5712 printf ("%s_unit_%s (executing_insn, candidate_insn)\n", unit->name, name);
5713 printf (" rtx executing_insn;\n");
5714 printf (" rtx candidate_insn;\n");
5715 printf ("{\n");
5716 printf (" rtx insn;\n");
5717 printf (" int casenum;\n\n");
5718 printf (" insn = executing_insn;\n");
5719 printf (" switch (recog_memoized (insn))\n");
5720 printf (" {\n");
5722 /* Write the `switch' statement to get the case value. */
5723 if (strlen (unit->name) + sizeof "*_cases" > 256)
5724 abort ();
5725 sprintf (str, "*%s_cases", unit->name);
5726 case_attr = find_attr (str, 0);
5727 if (! case_attr)
5728 abort ();
5729 common_av = find_most_used (case_attr);
5731 for (av = case_attr->first_value; av; av = av->next)
5732 if (av != common_av)
5733 write_attr_case (case_attr, av, 1,
5734 "casenum =", ";", 4, unit->condexp);
5736 write_attr_case (case_attr, common_av, 0,
5737 "casenum =", ";", 4, unit->condexp);
5738 printf (" }\n\n");
5740 /* Now write an outer switch statement on each case. Then write
5741 the tests on the executing function within each. */
5742 printf (" insn = candidate_insn;\n");
5743 printf (" switch (casenum)\n");
5744 printf (" {\n");
5746 for (i = 0; i < unit->num_opclasses; i++)
5748 /* Ensure using this case. */
5749 using_case = 0;
5750 for (av = case_attr->first_value; av; av = av->next)
5751 if (av->num_insns
5752 && contained_in_p (make_numeric_value (i), av->value))
5753 using_case = 1;
5755 if (! using_case)
5756 continue;
5758 printf (" case %d:\n", i);
5759 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5760 attr = find_attr (str, 0);
5761 if (! attr)
5762 abort ();
5764 /* If single value, just write it. */
5765 value = find_single_value (attr);
5766 if (value)
5767 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5768 else
5770 common_av = find_most_used (attr);
5771 printf (" switch (recog_memoized (insn))\n");
5772 printf ("\t{\n");
5774 for (av = attr->first_value; av; av = av->next)
5775 if (av != common_av)
5776 write_attr_case (attr, av, 1,
5777 "return", ";", 8, unit->condexp);
5779 write_attr_case (attr, common_av, 0,
5780 "return", ";", 8, unit->condexp);
5781 printf (" }\n\n");
5785 /* This default case should not be needed, but gcc's analysis is not
5786 good enough to realize that the default case is not needed for the
5787 second switch statement. */
5788 printf (" default:\n abort ();\n");
5789 printf (" }\n}\n\n");
5792 /* This page contains miscellaneous utility routines. */
5794 /* Given a string, return the number of comma-separated elements in it.
5795 Return 0 for the null string. */
5797 static int
5798 n_comma_elts (s)
5799 const char *s;
5801 int n;
5803 if (*s == '\0')
5804 return 0;
5806 for (n = 1; *s; s++)
5807 if (*s == ',')
5808 n++;
5810 return n;
5813 /* Given a pointer to a (char *), return a malloc'ed string containing the
5814 next comma-separated element. Advance the pointer to after the string
5815 scanned, or the end-of-string. Return NULL if at end of string. */
5817 static char *
5818 next_comma_elt (pstr)
5819 const char **pstr;
5821 char *out_str;
5822 const char *p;
5824 if (**pstr == '\0')
5825 return NULL;
5827 /* Find end of string to compute length. */
5828 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5831 out_str = attr_string (*pstr, p - *pstr);
5832 *pstr = p;
5834 if (**pstr == ',')
5835 (*pstr)++;
5837 return out_str;
5840 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5841 is non-zero, build a new attribute, if one does not exist. */
5843 static struct attr_desc *
5844 find_attr (name, create)
5845 const char *name;
5846 int create;
5848 struct attr_desc *attr;
5849 int index;
5851 /* Before we resort to using `strcmp', see if the string address matches
5852 anywhere. In most cases, it should have been canonicalized to do so. */
5853 if (name == alternative_name)
5854 return NULL;
5856 index = name[0] & (MAX_ATTRS_INDEX - 1);
5857 for (attr = attrs[index]; attr; attr = attr->next)
5858 if (name == attr->name)
5859 return attr;
5861 /* Otherwise, do it the slow way. */
5862 for (attr = attrs[index]; attr; attr = attr->next)
5863 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5864 return attr;
5866 if (! create)
5867 return NULL;
5869 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5870 attr->name = attr_string (name, strlen (name));
5871 attr->first_value = attr->default_val = NULL;
5872 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5873 attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
5874 attr->next = attrs[index];
5875 attrs[index] = attr;
5877 return attr;
5880 /* Create internal attribute with the given default value. */
5882 static void
5883 make_internal_attr (name, value, special)
5884 const char *name;
5885 rtx value;
5886 int special;
5888 struct attr_desc *attr;
5890 attr = find_attr (name, 1);
5891 if (attr->default_val)
5892 abort ();
5894 attr->is_numeric = 1;
5895 attr->is_const = 0;
5896 attr->is_special = (special & 1) != 0;
5897 attr->negative_ok = (special & 2) != 0;
5898 attr->unsigned_p = (special & 4) != 0;
5899 attr->func_units_p = (special & 8) != 0;
5900 attr->blockage_p = (special & 16) != 0;
5901 attr->default_val = get_attr_value (value, attr, -2);
5904 /* Find the most used value of an attribute. */
5906 static struct attr_value *
5907 find_most_used (attr)
5908 struct attr_desc *attr;
5910 struct attr_value *av;
5911 struct attr_value *most_used;
5912 int nuses;
5914 most_used = NULL;
5915 nuses = -1;
5917 for (av = attr->first_value; av; av = av->next)
5918 if (av->num_insns > nuses)
5919 nuses = av->num_insns, most_used = av;
5921 return most_used;
5924 /* If an attribute only has a single value used, return it. Otherwise
5925 return NULL. */
5927 static rtx
5928 find_single_value (attr)
5929 struct attr_desc *attr;
5931 struct attr_value *av;
5932 rtx unique_value;
5934 unique_value = NULL;
5935 for (av = attr->first_value; av; av = av->next)
5936 if (av->num_insns)
5938 if (unique_value)
5939 return NULL;
5940 else
5941 unique_value = av->value;
5944 return unique_value;
5947 /* Return (attr_value "n") */
5949 static rtx
5950 make_numeric_value (n)
5951 int n;
5953 static rtx int_values[20];
5954 rtx exp;
5955 char *p;
5957 if (n < 0)
5958 abort ();
5960 if (n < 20 && int_values[n])
5961 return int_values[n];
5963 p = attr_printf (MAX_DIGITS, "%d", n);
5964 exp = attr_rtx (CONST_STRING, p);
5966 if (n < 20)
5967 int_values[n] = exp;
5969 return exp;
5972 static void
5973 extend_range (range, min, max)
5974 struct range *range;
5975 int min;
5976 int max;
5978 if (range->min > min)
5979 range->min = min;
5980 if (range->max < max)
5981 range->max = max;
5984 static rtx
5985 copy_rtx_unchanging (orig)
5986 rtx orig;
5988 #if 0
5989 rtx copy;
5990 RTX_CODE code;
5991 #endif
5993 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
5994 return orig;
5996 MEM_IN_STRUCT_P (orig) = 1;
5997 return orig;
5999 #if 0
6000 code = GET_CODE (orig);
6001 switch (code)
6003 case CONST_INT:
6004 case CONST_DOUBLE:
6005 case SYMBOL_REF:
6006 case CODE_LABEL:
6007 return orig;
6009 default:
6010 break;
6013 copy = rtx_alloc (code);
6014 PUT_MODE (copy, GET_MODE (orig));
6015 RTX_UNCHANGING_P (copy) = 1;
6017 memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
6018 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
6019 return copy;
6020 #endif
6023 /* Determine if an insn has a constant number of delay slots, i.e., the
6024 number of delay slots is not a function of the length of the insn. */
6026 static void
6027 write_const_num_delay_slots ()
6029 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
6030 struct attr_value *av;
6031 struct insn_ent *ie;
6033 if (attr)
6035 printf ("int\nconst_num_delay_slots (insn)\n");
6036 printf (" rtx insn;\n");
6037 printf ("{\n");
6038 printf (" switch (recog_memoized (insn))\n");
6039 printf (" {\n");
6041 for (av = attr->first_value; av; av = av->next)
6043 length_used = 0;
6044 walk_attr_value (av->value);
6045 if (length_used)
6047 for (ie = av->first_insn; ie; ie = ie->next)
6048 if (ie->insn_code != -1)
6049 printf (" case %d:\n", ie->insn_code);
6050 printf (" return 0;\n");
6054 printf (" default:\n");
6055 printf (" return 1;\n");
6056 printf (" }\n}\n\n");
6060 extern int main PARAMS ((int, char **));
6063 main (argc, argv)
6064 int argc;
6065 char **argv;
6067 rtx desc;
6068 struct attr_desc *attr;
6069 struct insn_def *id;
6070 rtx tem;
6071 int i;
6073 progname = "genattrtab";
6075 if (argc <= 1)
6076 fatal ("No input file name.");
6078 if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
6079 return (FATAL_EXIT_CODE);
6081 obstack_init (hash_obstack);
6082 obstack_init (temp_obstack);
6084 /* Set up true and false rtx's */
6085 true_rtx = rtx_alloc (CONST_INT);
6086 XWINT (true_rtx, 0) = 1;
6087 false_rtx = rtx_alloc (CONST_INT);
6088 XWINT (false_rtx, 0) = 0;
6089 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
6090 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
6092 alternative_name = attr_string ("alternative", strlen ("alternative"));
6094 printf ("/* Generated automatically by the program `genattrtab'\n\
6095 from the machine description file `md'. */\n\n");
6097 /* Read the machine description. */
6099 while (1)
6101 int lineno;
6103 desc = read_md_rtx (&lineno, &insn_code_number);
6104 if (desc == NULL)
6105 break;
6107 switch (GET_CODE (desc))
6109 case DEFINE_INSN:
6110 case DEFINE_PEEPHOLE:
6111 case DEFINE_ASM_ATTRIBUTES:
6112 gen_insn (desc, lineno);
6113 break;
6115 case DEFINE_ATTR:
6116 gen_attr (desc, lineno);
6117 break;
6119 case DEFINE_DELAY:
6120 gen_delay (desc, lineno);
6121 break;
6123 case DEFINE_FUNCTION_UNIT:
6124 gen_unit (desc, lineno);
6125 break;
6127 default:
6128 break;
6130 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
6131 insn_index_number++;
6134 if (have_error)
6135 return FATAL_EXIT_CODE;
6137 insn_code_number++;
6139 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6140 if (! got_define_asm_attributes)
6142 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6143 XVEC (tem, 0) = rtvec_alloc (0);
6144 gen_insn (tem, 0);
6147 /* Expand DEFINE_DELAY information into new attribute. */
6148 if (num_delays)
6149 expand_delays ();
6151 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6152 if (num_units)
6153 expand_units ();
6155 printf ("#include \"config.h\"\n");
6156 printf ("#include \"system.h\"\n");
6157 printf ("#include \"rtl.h\"\n");
6158 printf ("#include \"tm_p.h\"\n");
6159 printf ("#include \"insn-config.h\"\n");
6160 printf ("#include \"recog.h\"\n");
6161 printf ("#include \"regs.h\"\n");
6162 printf ("#include \"real.h\"\n");
6163 printf ("#include \"output.h\"\n");
6164 printf ("#include \"insn-attr.h\"\n");
6165 printf ("#include \"toplev.h\"\n");
6166 printf ("#include \"flags.h\"\n");
6167 printf ("\n");
6168 printf ("#define operands recog_data.operand\n\n");
6170 /* Make `insn_alternatives'. */
6171 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6172 for (id = defs; id; id = id->next)
6173 if (id->insn_code >= 0)
6174 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6176 /* Make `insn_n_alternatives'. */
6177 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6178 for (id = defs; id; id = id->next)
6179 if (id->insn_code >= 0)
6180 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6182 /* Prepare to write out attribute subroutines by checking everything stored
6183 away and building the attribute cases. */
6185 check_defs ();
6187 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6188 for (attr = attrs[i]; attr; attr = attr->next)
6189 attr->default_val->value
6190 = check_attr_value (attr->default_val->value, attr);
6192 if (have_error)
6193 return FATAL_EXIT_CODE;
6195 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6196 for (attr = attrs[i]; attr; attr = attr->next)
6197 fill_attr (attr);
6199 /* Construct extra attributes for `length'. */
6200 make_length_attrs ();
6202 /* Perform any possible optimizations to speed up compilation. */
6203 optimize_attrs ();
6205 /* Now write out all the `gen_attr_...' routines. Do these before the
6206 special routines (specifically before write_function_unit_info), so
6207 that they get defined before they are used. */
6209 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6210 for (attr = attrs[i]; attr; attr = attr->next)
6212 if (! attr->is_special && ! attr->is_const)
6213 write_attr_get (attr);
6216 /* Write out delay eligibility information, if DEFINE_DELAY present.
6217 (The function to compute the number of delay slots will be written
6218 below.) */
6219 if (num_delays)
6221 write_eligible_delay ("delay");
6222 if (have_annul_true)
6223 write_eligible_delay ("annul_true");
6224 if (have_annul_false)
6225 write_eligible_delay ("annul_false");
6228 /* Write out information about function units. */
6229 if (num_units)
6230 write_function_unit_info ();
6232 /* Write out constant delay slot info */
6233 write_const_num_delay_slots ();
6235 write_length_unit_log ();
6237 fflush (stdout);
6238 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6241 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
6242 const char *
6243 get_insn_name (code)
6244 int code ATTRIBUTE_UNUSED;
6246 return NULL;