Use MODE_BASE_REG_CLASS in legitimize macros.
[official-gcc.git] / gcc / genattrtab.c
blobf1f383c31e37d29a6cbfb19bf7b124d6ba874490
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 rtx attr_rtx_1 PARAMS ((enum rtx_code, va_list));
369 static char *attr_printf PARAMS ((unsigned int, const char *, ...))
370 ATTRIBUTE_PRINTF_2;
371 static char *attr_string PARAMS ((const char *, int));
372 static rtx check_attr_test PARAMS ((rtx, int, int));
373 static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
374 static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
375 static rtx convert_set_attr PARAMS ((rtx, struct insn_def *));
376 static void check_defs PARAMS ((void));
377 #if 0
378 static rtx convert_const_symbol_ref PARAMS ((rtx, struct attr_desc *));
379 #endif
380 static rtx make_canonical PARAMS ((struct attr_desc *, rtx));
381 static struct attr_value *get_attr_value PARAMS ((rtx, struct attr_desc *, int));
382 static rtx copy_rtx_unchanging PARAMS ((rtx));
383 static rtx copy_boolean PARAMS ((rtx));
384 static void expand_delays PARAMS ((void));
385 static rtx operate_exp PARAMS ((enum operator, rtx, rtx));
386 static void expand_units PARAMS ((void));
387 static rtx simplify_knowing PARAMS ((rtx, rtx));
388 static rtx encode_units_mask PARAMS ((rtx));
389 static void fill_attr PARAMS ((struct attr_desc *));
390 /* dpx2 compiler chokes if we specify the arg types of the args. */
391 static rtx substitute_address PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
392 static void make_length_attrs PARAMS ((void));
393 static rtx identity_fn PARAMS ((rtx));
394 static rtx zero_fn PARAMS ((rtx));
395 static rtx one_fn PARAMS ((rtx));
396 static rtx max_fn PARAMS ((rtx));
397 static void write_length_unit_log PARAMS ((void));
398 static rtx simplify_cond PARAMS ((rtx, int, int));
399 #if 0
400 static rtx simplify_by_alternatives PARAMS ((rtx, int, int));
401 #endif
402 static rtx simplify_by_exploding PARAMS ((rtx));
403 static int find_and_mark_used_attributes PARAMS ((rtx, rtx *, int *));
404 static void unmark_used_attributes PARAMS ((rtx, struct dimension *, int));
405 static int add_values_to_cover PARAMS ((struct dimension *));
406 static int increment_current_value PARAMS ((struct dimension *, int));
407 static rtx test_for_current_value PARAMS ((struct dimension *, int));
408 static rtx simplify_with_current_value PARAMS ((rtx, struct dimension *, int));
409 static rtx simplify_with_current_value_aux PARAMS ((rtx));
410 static void clear_struct_flag PARAMS ((rtx));
411 static int count_sub_rtxs PARAMS ((rtx, int));
412 static void remove_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
413 static void insert_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
414 static rtx insert_right_side PARAMS ((enum rtx_code, rtx, rtx, int, int));
415 static rtx make_alternative_compare PARAMS ((int));
416 static int compute_alternative_mask PARAMS ((rtx, enum rtx_code));
417 static rtx evaluate_eq_attr PARAMS ((rtx, rtx, int, int));
418 static rtx simplify_and_tree PARAMS ((rtx, rtx *, int, int));
419 static rtx simplify_or_tree PARAMS ((rtx, rtx *, int, int));
420 static rtx simplify_test_exp PARAMS ((rtx, int, int));
421 static rtx simplify_test_exp_in_temp PARAMS ((rtx, int, int));
422 static void optimize_attrs PARAMS ((void));
423 static void gen_attr PARAMS ((rtx, int));
424 static int count_alternatives PARAMS ((rtx));
425 static int compares_alternatives_p PARAMS ((rtx));
426 static int contained_in_p PARAMS ((rtx, rtx));
427 static void gen_insn PARAMS ((rtx, int));
428 static void gen_delay PARAMS ((rtx, int));
429 static void gen_unit PARAMS ((rtx, int));
430 static void write_test_expr PARAMS ((rtx, int));
431 static int max_attr_value PARAMS ((rtx, int*));
432 static int or_attr_value PARAMS ((rtx, int*));
433 static void walk_attr_value PARAMS ((rtx));
434 static void write_attr_get PARAMS ((struct attr_desc *));
435 static rtx eliminate_known_true PARAMS ((rtx, rtx, int, int));
436 static void write_attr_set PARAMS ((struct attr_desc *, int, rtx,
437 const char *, const char *, rtx,
438 int, int));
439 static void write_attr_case PARAMS ((struct attr_desc *, struct attr_value *,
440 int, const char *, const char *, int, rtx));
441 static void write_unit_name PARAMS ((const char *, int, const char *));
442 static void write_attr_valueq PARAMS ((struct attr_desc *, const char *));
443 static void write_attr_value PARAMS ((struct attr_desc *, rtx));
444 static void write_upcase PARAMS ((const char *));
445 static void write_indent PARAMS ((int));
446 static void write_eligible_delay PARAMS ((const char *));
447 static void write_function_unit_info PARAMS ((void));
448 static void write_complex_function PARAMS ((struct function_unit *, const char *,
449 const char *));
450 static int write_expr_attr_cache PARAMS ((rtx, struct attr_desc *));
451 static void write_toplevel_expr PARAMS ((rtx));
452 static void write_const_num_delay_slots PARAMS ((void));
453 static int n_comma_elts PARAMS ((const char *));
454 static char *next_comma_elt PARAMS ((const char **));
455 static struct attr_desc *find_attr PARAMS ((const char *, int));
456 static void make_internal_attr PARAMS ((const char *, rtx, int));
457 static struct attr_value *find_most_used PARAMS ((struct attr_desc *));
458 static rtx find_single_value PARAMS ((struct attr_desc *));
459 static rtx make_numeric_value PARAMS ((int));
460 static void extend_range PARAMS ((struct range *, int, int));
461 static rtx attr_eq PARAMS ((const char *, const char *));
462 static const char *attr_numeral PARAMS ((int));
463 static int attr_equal_p PARAMS ((rtx, rtx));
464 static rtx attr_copy_rtx PARAMS ((rtx));
465 static int attr_rtx_cost PARAMS ((rtx));
467 #define oballoc(size) obstack_alloc (hash_obstack, size)
469 /* Hash table for sharing RTL and strings. */
471 /* Each hash table slot is a bucket containing a chain of these structures.
472 Strings are given negative hash codes; RTL expressions are given positive
473 hash codes. */
475 struct attr_hash
477 struct attr_hash *next; /* Next structure in the bucket. */
478 int hashcode; /* Hash code of this rtx or string. */
479 union
481 char *str; /* The string (negative hash codes) */
482 rtx rtl; /* or the RTL recorded here. */
483 } u;
486 /* Now here is the hash table. When recording an RTL, it is added to
487 the slot whose index is the hash code mod the table size. Note
488 that the hash table is used for several kinds of RTL (see attr_rtx)
489 and for strings. While all these live in the same table, they are
490 completely independent, and the hash code is computed differently
491 for each. */
493 #define RTL_HASH_SIZE 4093
494 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
496 /* Here is how primitive or already-shared RTL's hash
497 codes are made. */
498 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
500 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
502 static void
503 attr_hash_add_rtx (hashcode, rtl)
504 int hashcode;
505 rtx rtl;
507 struct attr_hash *h;
509 h = (struct attr_hash *) obstack_alloc (hash_obstack,
510 sizeof (struct attr_hash));
511 h->hashcode = hashcode;
512 h->u.rtl = rtl;
513 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
514 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
517 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
519 static void
520 attr_hash_add_string (hashcode, str)
521 int hashcode;
522 char *str;
524 struct attr_hash *h;
526 h = (struct attr_hash *) obstack_alloc (hash_obstack,
527 sizeof (struct attr_hash));
528 h->hashcode = -hashcode;
529 h->u.str = str;
530 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
531 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
534 /* Generate an RTL expression, but avoid duplicates.
535 Set the RTX_INTEGRATED_P flag for these permanent objects.
537 In some cases we cannot uniquify; then we return an ordinary
538 impermanent rtx with RTX_INTEGRATED_P clear.
540 Args are like gen_rtx, but without the mode:
542 rtx attr_rtx (code, [element1, ..., elementn]) */
544 static rtx
545 attr_rtx_1 (code, p)
546 enum rtx_code code;
547 va_list p;
549 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
550 int hashcode;
551 struct attr_hash *h;
552 struct obstack *old_obstack = rtl_obstack;
554 /* For each of several cases, search the hash table for an existing entry.
555 Use that entry if one is found; otherwise create a new RTL and add it
556 to the table. */
558 if (GET_RTX_CLASS (code) == '1')
560 rtx arg0 = va_arg (p, rtx);
562 /* A permanent object cannot point to impermanent ones. */
563 if (! RTX_INTEGRATED_P (arg0))
565 rt_val = rtx_alloc (code);
566 XEXP (rt_val, 0) = arg0;
567 return rt_val;
570 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
571 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
572 if (h->hashcode == hashcode
573 && GET_CODE (h->u.rtl) == code
574 && XEXP (h->u.rtl, 0) == arg0)
575 return h->u.rtl;
577 if (h == 0)
579 rtl_obstack = hash_obstack;
580 rt_val = rtx_alloc (code);
581 XEXP (rt_val, 0) = arg0;
584 else if (GET_RTX_CLASS (code) == 'c'
585 || GET_RTX_CLASS (code) == '2'
586 || GET_RTX_CLASS (code) == '<')
588 rtx arg0 = va_arg (p, rtx);
589 rtx arg1 = va_arg (p, rtx);
591 /* A permanent object cannot point to impermanent ones. */
592 if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
594 rt_val = rtx_alloc (code);
595 XEXP (rt_val, 0) = arg0;
596 XEXP (rt_val, 1) = arg1;
597 return rt_val;
600 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
601 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
602 if (h->hashcode == hashcode
603 && GET_CODE (h->u.rtl) == code
604 && XEXP (h->u.rtl, 0) == arg0
605 && XEXP (h->u.rtl, 1) == arg1)
606 return h->u.rtl;
608 if (h == 0)
610 rtl_obstack = hash_obstack;
611 rt_val = rtx_alloc (code);
612 XEXP (rt_val, 0) = arg0;
613 XEXP (rt_val, 1) = arg1;
616 else if (GET_RTX_LENGTH (code) == 1
617 && GET_RTX_FORMAT (code)[0] == 's')
619 char *arg0 = va_arg (p, char *);
621 if (code == SYMBOL_REF)
622 arg0 = attr_string (arg0, strlen (arg0));
624 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
625 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
626 if (h->hashcode == hashcode
627 && GET_CODE (h->u.rtl) == code
628 && XSTR (h->u.rtl, 0) == arg0)
629 return h->u.rtl;
631 if (h == 0)
633 rtl_obstack = hash_obstack;
634 rt_val = rtx_alloc (code);
635 XSTR (rt_val, 0) = arg0;
638 else if (GET_RTX_LENGTH (code) == 2
639 && GET_RTX_FORMAT (code)[0] == 's'
640 && GET_RTX_FORMAT (code)[1] == 's')
642 char *arg0 = va_arg (p, char *);
643 char *arg1 = va_arg (p, char *);
645 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
646 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
647 if (h->hashcode == hashcode
648 && GET_CODE (h->u.rtl) == code
649 && XSTR (h->u.rtl, 0) == arg0
650 && XSTR (h->u.rtl, 1) == arg1)
651 return h->u.rtl;
653 if (h == 0)
655 rtl_obstack = hash_obstack;
656 rt_val = rtx_alloc (code);
657 XSTR (rt_val, 0) = arg0;
658 XSTR (rt_val, 1) = arg1;
661 else if (code == CONST_INT)
663 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
664 if (arg0 == 0)
665 return false_rtx;
666 else if (arg0 == 1)
667 return true_rtx;
668 else
669 goto nohash;
671 else
673 int i; /* Array indices... */
674 const char *fmt; /* Current rtx's format... */
675 nohash:
676 rt_val = rtx_alloc (code); /* Allocate the storage space. */
678 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
679 for (i = 0; i < GET_RTX_LENGTH (code); i++)
681 switch (*fmt++)
683 case '0': /* Unused field. */
684 break;
686 case 'i': /* An integer? */
687 XINT (rt_val, i) = va_arg (p, int);
688 break;
690 case 'w': /* A wide integer? */
691 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
692 break;
694 case 's': /* A string? */
695 XSTR (rt_val, i) = va_arg (p, char *);
696 break;
698 case 'e': /* An expression? */
699 case 'u': /* An insn? Same except when printing. */
700 XEXP (rt_val, i) = va_arg (p, rtx);
701 break;
703 case 'E': /* An RTX vector? */
704 XVEC (rt_val, i) = va_arg (p, rtvec);
705 break;
707 default:
708 abort ();
711 return rt_val;
714 rtl_obstack = old_obstack;
715 attr_hash_add_rtx (hashcode, rt_val);
716 RTX_INTEGRATED_P (rt_val) = 1;
717 return rt_val;
720 static rtx
721 attr_rtx VPARAMS ((enum rtx_code code, ...))
723 rtx result;
725 VA_OPEN (p, code);
726 VA_FIXEDARG (p, enum rtx_code, code);
727 result = attr_rtx_1 (code, p);
728 VA_CLOSE (p);
729 return result;
732 /* Create a new string printed with the printf line arguments into a space
733 of at most LEN bytes:
735 rtx attr_printf (len, format, [arg1, ..., argn]) */
737 static char *
738 attr_printf VPARAMS ((unsigned int len, const char *fmt, ...))
740 char str[256];
742 VA_OPEN (p, fmt);
743 VA_FIXEDARG (p, unsigned int, len);
744 VA_FIXEDARG (p, const char *, fmt);
746 if (len > sizeof str - 1) /* Leave room for \0. */
747 abort ();
749 vsprintf (str, fmt, p);
750 VA_CLOSE (p);
752 return attr_string (str, strlen (str));
755 static rtx
756 attr_eq (name, value)
757 const char *name, *value;
759 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
760 attr_string (value, strlen (value)));
763 static const char *
764 attr_numeral (n)
765 int n;
767 return XSTR (make_numeric_value (n), 0);
770 /* Return a permanent (possibly shared) copy of a string STR (not assumed
771 to be null terminated) with LEN bytes. */
773 static char *
774 attr_string (str, len)
775 const char *str;
776 int len;
778 struct attr_hash *h;
779 int hashcode;
780 int i;
781 char *new_str;
783 /* Compute the hash code. */
784 hashcode = (len + 1) * 613 + (unsigned) str[0];
785 for (i = 1; i <= len; i += 2)
786 hashcode = ((hashcode * 613) + (unsigned) str[i]);
787 if (hashcode < 0)
788 hashcode = -hashcode;
790 /* Search the table for the string. */
791 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
792 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
793 && !strncmp (h->u.str, str, len))
794 return h->u.str; /* <-- return if found. */
796 /* Not found; create a permanent copy and add it to the hash table. */
797 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
798 memcpy (new_str, str, len);
799 new_str[len] = '\0';
800 attr_hash_add_string (hashcode, new_str);
802 return new_str; /* Return the new string. */
805 /* Check two rtx's for equality of contents,
806 taking advantage of the fact that if both are hashed
807 then they can't be equal unless they are the same object. */
809 static int
810 attr_equal_p (x, y)
811 rtx x, y;
813 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
814 && rtx_equal_p (x, y)));
817 /* Copy an attribute value expression,
818 descending to all depths, but not copying any
819 permanent hashed subexpressions. */
821 static rtx
822 attr_copy_rtx (orig)
823 rtx orig;
825 rtx copy;
826 int i, j;
827 RTX_CODE code;
828 const char *format_ptr;
830 /* No need to copy a permanent object. */
831 if (RTX_INTEGRATED_P (orig))
832 return orig;
834 code = GET_CODE (orig);
836 switch (code)
838 case REG:
839 case QUEUED:
840 case CONST_INT:
841 case CONST_DOUBLE:
842 case SYMBOL_REF:
843 case CODE_LABEL:
844 case PC:
845 case CC0:
846 return orig;
848 default:
849 break;
852 copy = rtx_alloc (code);
853 PUT_MODE (copy, GET_MODE (orig));
854 copy->in_struct = orig->in_struct;
855 copy->volatil = orig->volatil;
856 copy->unchanging = orig->unchanging;
857 copy->integrated = orig->integrated;
859 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
861 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
863 switch (*format_ptr++)
865 case 'e':
866 XEXP (copy, i) = XEXP (orig, i);
867 if (XEXP (orig, i) != NULL)
868 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
869 break;
871 case 'E':
872 case 'V':
873 XVEC (copy, i) = XVEC (orig, i);
874 if (XVEC (orig, i) != NULL)
876 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
877 for (j = 0; j < XVECLEN (copy, i); j++)
878 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
880 break;
882 case 'n':
883 case 'i':
884 XINT (copy, i) = XINT (orig, i);
885 break;
887 case 'w':
888 XWINT (copy, i) = XWINT (orig, i);
889 break;
891 case 's':
892 case 'S':
893 XSTR (copy, i) = XSTR (orig, i);
894 break;
896 default:
897 abort ();
900 return copy;
903 /* Given a test expression for an attribute, ensure it is validly formed.
904 IS_CONST indicates whether the expression is constant for each compiler
905 run (a constant expression may not test any particular insn).
907 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
908 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
909 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
911 Update the string address in EQ_ATTR expression to be the same used
912 in the attribute (or `alternative_name') to speed up subsequent
913 `find_attr' calls and eliminate most `strcmp' calls.
915 Return the new expression, if any. */
917 static rtx
918 check_attr_test (exp, is_const, lineno)
919 rtx exp;
920 int is_const;
921 int lineno;
923 struct attr_desc *attr;
924 struct attr_value *av;
925 const char *name_ptr, *p;
926 rtx orexp, newexp;
928 switch (GET_CODE (exp))
930 case EQ_ATTR:
931 /* Handle negation test. */
932 if (XSTR (exp, 1)[0] == '!')
933 return check_attr_test (attr_rtx (NOT,
934 attr_eq (XSTR (exp, 0),
935 &XSTR (exp, 1)[1])),
936 is_const, lineno);
938 else if (n_comma_elts (XSTR (exp, 1)) == 1)
940 attr = find_attr (XSTR (exp, 0), 0);
941 if (attr == NULL)
943 if (! strcmp (XSTR (exp, 0), "alternative"))
945 XSTR (exp, 0) = alternative_name;
946 /* This can't be simplified any further. */
947 RTX_UNCHANGING_P (exp) = 1;
948 return exp;
950 else
951 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
954 if (is_const && ! attr->is_const)
955 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
956 XSTR (exp, 0));
958 /* Copy this just to make it permanent,
959 so expressions using it can be permanent too. */
960 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
962 /* It shouldn't be possible to simplify the value given to a
963 constant attribute, so don't expand this until it's time to
964 write the test expression. */
965 if (attr->is_const)
966 RTX_UNCHANGING_P (exp) = 1;
968 if (attr->is_numeric)
970 for (p = XSTR (exp, 1); *p; p++)
971 if (! ISDIGIT (*p))
972 fatal ("attribute `%s' takes only numeric values",
973 XSTR (exp, 0));
975 else
977 for (av = attr->first_value; av; av = av->next)
978 if (GET_CODE (av->value) == CONST_STRING
979 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
980 break;
982 if (av == NULL)
983 fatal ("unknown value `%s' for `%s' attribute",
984 XSTR (exp, 1), XSTR (exp, 0));
987 else
989 /* Make an IOR tree of the possible values. */
990 orexp = false_rtx;
991 name_ptr = XSTR (exp, 1);
992 while ((p = next_comma_elt (&name_ptr)) != NULL)
994 newexp = attr_eq (XSTR (exp, 0), p);
995 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
998 return check_attr_test (orexp, is_const, lineno);
1000 break;
1002 case ATTR_FLAG:
1003 break;
1005 case CONST_INT:
1006 /* Either TRUE or FALSE. */
1007 if (XWINT (exp, 0))
1008 return true_rtx;
1009 else
1010 return false_rtx;
1012 case IOR:
1013 case AND:
1014 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1015 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
1016 break;
1018 case NOT:
1019 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1020 break;
1022 case MATCH_INSN:
1023 case MATCH_OPERAND:
1024 if (is_const)
1025 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1026 GET_RTX_NAME (GET_CODE (exp)));
1027 /* These cases can't be simplified. */
1028 RTX_UNCHANGING_P (exp) = 1;
1029 break;
1031 case LE: case LT: case GT: case GE:
1032 case LEU: case LTU: case GTU: case GEU:
1033 case NE: case EQ:
1034 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1035 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1036 exp = attr_rtx (GET_CODE (exp),
1037 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1038 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
1039 /* These cases can't be simplified. */
1040 RTX_UNCHANGING_P (exp) = 1;
1041 break;
1043 case SYMBOL_REF:
1044 if (is_const)
1046 /* These cases are valid for constant attributes, but can't be
1047 simplified. */
1048 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1049 RTX_UNCHANGING_P (exp) = 1;
1050 break;
1052 default:
1053 fatal ("RTL operator \"%s\" not valid in attribute test",
1054 GET_RTX_NAME (GET_CODE (exp)));
1057 return exp;
1060 /* Given an expression, ensure that it is validly formed and that all named
1061 attribute values are valid for the given attribute. Issue a fatal error
1062 if not. If no attribute is specified, assume a numeric attribute.
1064 Return a perhaps modified replacement expression for the value. */
1066 static rtx
1067 check_attr_value (exp, attr)
1068 rtx exp;
1069 struct attr_desc *attr;
1071 struct attr_value *av;
1072 const char *p;
1073 int i;
1075 switch (GET_CODE (exp))
1077 case CONST_INT:
1078 if (attr && ! attr->is_numeric)
1080 message_with_line (attr->lineno,
1081 "CONST_INT not valid for non-numeric attribute %s",
1082 attr->name);
1083 have_error = 1;
1084 break;
1087 if (INTVAL (exp) < 0 && ! attr->negative_ok)
1089 message_with_line (attr->lineno,
1090 "negative numeric value specified for attribute %s",
1091 attr->name);
1092 have_error = 1;
1093 break;
1095 break;
1097 case CONST_STRING:
1098 if (! strcmp (XSTR (exp, 0), "*"))
1099 break;
1101 if (attr == 0 || attr->is_numeric)
1103 p = XSTR (exp, 0);
1104 if (attr && attr->negative_ok && *p == '-')
1105 p++;
1106 for (; *p; p++)
1107 if (! ISDIGIT (*p))
1109 message_with_line (attr ? attr->lineno : 0,
1110 "non-numeric value for numeric attribute %s",
1111 attr ? attr->name : "internal");
1112 have_error = 1;
1113 break;
1115 break;
1118 for (av = attr->first_value; av; av = av->next)
1119 if (GET_CODE (av->value) == CONST_STRING
1120 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1121 break;
1123 if (av == NULL)
1125 message_with_line (attr->lineno,
1126 "unknown value `%s' for `%s' attribute",
1127 XSTR (exp, 0), attr ? attr->name : "internal");
1128 have_error = 1;
1130 break;
1132 case IF_THEN_ELSE:
1133 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1134 attr ? attr->is_const : 0,
1135 attr ? attr->lineno : 0);
1136 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1137 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1138 break;
1140 case PLUS:
1141 case MINUS:
1142 case MULT:
1143 case DIV:
1144 case MOD:
1145 if (attr && !attr->is_numeric)
1147 message_with_line (attr->lineno,
1148 "invalid operation `%s' for non-numeric attribute value",
1149 GET_RTX_NAME (GET_CODE (exp)));
1150 have_error = 1;
1151 break;
1153 /* FALLTHRU */
1155 case IOR:
1156 case AND:
1157 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1158 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1159 break;
1161 case FFS:
1162 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1163 break;
1165 case COND:
1166 if (XVECLEN (exp, 0) % 2 != 0)
1168 message_with_line (attr->lineno,
1169 "first operand of COND must have even length");
1170 have_error = 1;
1171 break;
1174 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1176 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1177 attr ? attr->is_const : 0,
1178 attr ? attr->lineno : 0);
1179 XVECEXP (exp, 0, i + 1)
1180 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1183 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1184 break;
1186 case ATTR:
1188 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
1189 if (attr2 == NULL)
1191 message_with_line (attr ? attr->lineno : 0,
1192 "unknown attribute `%s' in ATTR",
1193 XSTR (exp, 0));
1194 have_error = 1;
1196 else if (attr && attr->is_const && ! attr2->is_const)
1198 message_with_line (attr->lineno,
1199 "non-constant attribute `%s' referenced from `%s'",
1200 XSTR (exp, 0), attr->name);
1201 have_error = 1;
1203 else if (attr
1204 && (attr->is_numeric != attr2->is_numeric
1205 || (! attr->negative_ok && attr2->negative_ok)))
1207 message_with_line (attr->lineno,
1208 "numeric attribute mismatch calling `%s' from `%s'",
1209 XSTR (exp, 0), attr->name);
1210 have_error = 1;
1213 break;
1215 case SYMBOL_REF:
1216 /* A constant SYMBOL_REF is valid as a constant attribute test and
1217 is expanded later by make_canonical into a COND. In a non-constant
1218 attribute test, it is left be. */
1219 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1221 default:
1222 message_with_line (attr ? attr->lineno : 0,
1223 "invalid operation `%s' for attribute value",
1224 GET_RTX_NAME (GET_CODE (exp)));
1225 have_error = 1;
1226 break;
1229 return exp;
1232 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1233 It becomes a COND with each test being (eq_attr "alternative "n") */
1235 static rtx
1236 convert_set_attr_alternative (exp, id)
1237 rtx exp;
1238 struct insn_def *id;
1240 int num_alt = id->num_alternatives;
1241 rtx condexp;
1242 int i;
1244 if (XVECLEN (exp, 1) != num_alt)
1246 message_with_line (id->lineno,
1247 "bad number of entries in SET_ATTR_ALTERNATIVE");
1248 have_error = 1;
1249 return NULL_RTX;
1252 /* Make a COND with all tests but the last. Select the last value via the
1253 default. */
1254 condexp = rtx_alloc (COND);
1255 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1257 for (i = 0; i < num_alt - 1; i++)
1259 const char *p;
1260 p = attr_numeral (i);
1262 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1263 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1266 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1268 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1271 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1272 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1274 static rtx
1275 convert_set_attr (exp, id)
1276 rtx exp;
1277 struct insn_def *id;
1279 rtx newexp;
1280 const char *name_ptr;
1281 char *p;
1282 int n;
1284 /* See how many alternative specified. */
1285 n = n_comma_elts (XSTR (exp, 1));
1286 if (n == 1)
1287 return attr_rtx (SET,
1288 attr_rtx (ATTR, XSTR (exp, 0)),
1289 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1291 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1292 XSTR (newexp, 0) = XSTR (exp, 0);
1293 XVEC (newexp, 1) = rtvec_alloc (n);
1295 /* Process each comma-separated name. */
1296 name_ptr = XSTR (exp, 1);
1297 n = 0;
1298 while ((p = next_comma_elt (&name_ptr)) != NULL)
1299 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1301 return convert_set_attr_alternative (newexp, id);
1304 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1305 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1306 expressions. */
1308 static void
1309 check_defs ()
1311 struct insn_def *id;
1312 struct attr_desc *attr;
1313 int i;
1314 rtx value;
1316 for (id = defs; id; id = id->next)
1318 if (XVEC (id->def, id->vec_idx) == NULL)
1319 continue;
1321 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1323 value = XVECEXP (id->def, id->vec_idx, i);
1324 switch (GET_CODE (value))
1326 case SET:
1327 if (GET_CODE (XEXP (value, 0)) != ATTR)
1329 message_with_line (id->lineno, "bad attribute set");
1330 have_error = 1;
1331 value = NULL_RTX;
1333 break;
1335 case SET_ATTR_ALTERNATIVE:
1336 value = convert_set_attr_alternative (value, id);
1337 break;
1339 case SET_ATTR:
1340 value = convert_set_attr (value, id);
1341 break;
1343 default:
1344 message_with_line (id->lineno, "invalid attribute code %s",
1345 GET_RTX_NAME (GET_CODE (value)));
1346 have_error = 1;
1347 value = NULL_RTX;
1349 if (value == NULL_RTX)
1350 continue;
1352 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1354 message_with_line (id->lineno, "unknown attribute %s",
1355 XSTR (XEXP (value, 0), 0));
1356 have_error = 1;
1357 continue;
1360 XVECEXP (id->def, id->vec_idx, i) = value;
1361 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1366 #if 0
1367 /* Given a constant SYMBOL_REF expression, convert to a COND that
1368 explicitly tests each enumerated value. */
1370 static rtx
1371 convert_const_symbol_ref (exp, attr)
1372 rtx exp;
1373 struct attr_desc *attr;
1375 rtx condexp;
1376 struct attr_value *av;
1377 int i;
1378 int num_alt = 0;
1380 for (av = attr->first_value; av; av = av->next)
1381 num_alt++;
1383 /* Make a COND with all tests but the last, and in the original order.
1384 Select the last value via the default. Note that the attr values
1385 are constructed in reverse order. */
1387 condexp = rtx_alloc (COND);
1388 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1389 av = attr->first_value;
1390 XEXP (condexp, 1) = av->value;
1392 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1394 char *p, *string;
1395 rtx value;
1397 string = p = (char *) oballoc (2
1398 + strlen (attr->name)
1399 + strlen (XSTR (av->value, 0)));
1400 strcpy (p, attr->name);
1401 strcat (p, "_");
1402 strcat (p, XSTR (av->value, 0));
1403 for (; *p != '\0'; p++)
1404 *p = TOUPPER (*p);
1406 value = attr_rtx (SYMBOL_REF, string);
1407 RTX_UNCHANGING_P (value) = 1;
1409 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1411 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1414 return condexp;
1416 #endif
1418 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1419 expressions by converting them into a COND. This removes cases from this
1420 program. Also, replace an attribute value of "*" with the default attribute
1421 value. */
1423 static rtx
1424 make_canonical (attr, exp)
1425 struct attr_desc *attr;
1426 rtx exp;
1428 int i;
1429 rtx newexp;
1431 switch (GET_CODE (exp))
1433 case CONST_INT:
1434 exp = make_numeric_value (INTVAL (exp));
1435 break;
1437 case CONST_STRING:
1438 if (! strcmp (XSTR (exp, 0), "*"))
1440 if (attr == 0 || attr->default_val == 0)
1441 fatal ("(attr_value \"*\") used in invalid context");
1442 exp = attr->default_val->value;
1445 break;
1447 case SYMBOL_REF:
1448 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1449 break;
1450 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1451 This makes the COND something that won't be considered an arbitrary
1452 expression by walk_attr_value. */
1453 RTX_UNCHANGING_P (exp) = 1;
1454 #if 0
1455 /* ??? Why do we do this? With attribute values { A B C D E }, this
1456 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1457 than (x==E). */
1458 exp = convert_const_symbol_ref (exp, attr);
1459 RTX_UNCHANGING_P (exp) = 1;
1460 exp = check_attr_value (exp, attr);
1461 /* Goto COND case since this is now a COND. Note that while the
1462 new expression is rescanned, all symbol_ref notes are marked as
1463 unchanging. */
1464 goto cond;
1465 #else
1466 exp = check_attr_value (exp, attr);
1467 break;
1468 #endif
1470 case IF_THEN_ELSE:
1471 newexp = rtx_alloc (COND);
1472 XVEC (newexp, 0) = rtvec_alloc (2);
1473 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1474 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1476 XEXP (newexp, 1) = XEXP (exp, 2);
1478 exp = newexp;
1479 /* Fall through to COND case since this is now a COND. */
1481 case COND:
1483 int allsame = 1;
1484 rtx defval;
1486 /* First, check for degenerate COND. */
1487 if (XVECLEN (exp, 0) == 0)
1488 return make_canonical (attr, XEXP (exp, 1));
1489 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1491 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1493 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1494 XVECEXP (exp, 0, i + 1)
1495 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1496 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1497 allsame = 0;
1499 if (allsame)
1500 return defval;
1502 break;
1504 default:
1505 break;
1508 return exp;
1511 static rtx
1512 copy_boolean (exp)
1513 rtx exp;
1515 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1516 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1517 copy_boolean (XEXP (exp, 1)));
1518 return exp;
1521 /* Given a value and an attribute description, return a `struct attr_value *'
1522 that represents that value. This is either an existing structure, if the
1523 value has been previously encountered, or a newly-created structure.
1525 `insn_code' is the code of an insn whose attribute has the specified
1526 value (-2 if not processing an insn). We ensure that all insns for
1527 a given value have the same number of alternatives if the value checks
1528 alternatives. */
1530 static struct attr_value *
1531 get_attr_value (value, attr, insn_code)
1532 rtx value;
1533 struct attr_desc *attr;
1534 int insn_code;
1536 struct attr_value *av;
1537 int num_alt = 0;
1539 value = make_canonical (attr, value);
1540 if (compares_alternatives_p (value))
1542 if (insn_code < 0 || insn_alternatives == NULL)
1543 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1544 else
1545 num_alt = insn_alternatives[insn_code];
1548 for (av = attr->first_value; av; av = av->next)
1549 if (rtx_equal_p (value, av->value)
1550 && (num_alt == 0 || av->first_insn == NULL
1551 || insn_alternatives[av->first_insn->insn_code]))
1552 return av;
1554 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1555 av->value = value;
1556 av->next = attr->first_value;
1557 attr->first_value = av;
1558 av->first_insn = NULL;
1559 av->num_insns = 0;
1560 av->has_asm_insn = 0;
1562 return av;
1565 /* After all DEFINE_DELAYs have been read in, create internal attributes
1566 to generate the required routines.
1568 First, we compute the number of delay slots for each insn (as a COND of
1569 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1570 delay type is specified, we compute a similar function giving the
1571 DEFINE_DELAY ordinal for each insn.
1573 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1574 tells whether a given insn can be in that delay slot.
1576 Normal attribute filling and optimization expands these to contain the
1577 information needed to handle delay slots. */
1579 static void
1580 expand_delays ()
1582 struct delay_desc *delay;
1583 rtx condexp;
1584 rtx newexp;
1585 int i;
1586 char *p;
1588 /* First, generate data for `num_delay_slots' function. */
1590 condexp = rtx_alloc (COND);
1591 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1592 XEXP (condexp, 1) = make_numeric_value (0);
1594 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1596 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1597 XVECEXP (condexp, 0, i + 1)
1598 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1601 make_internal_attr ("*num_delay_slots", condexp, 0);
1603 /* If more than one delay type, do the same for computing the delay type. */
1604 if (num_delays > 1)
1606 condexp = rtx_alloc (COND);
1607 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1608 XEXP (condexp, 1) = make_numeric_value (0);
1610 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1612 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1613 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1616 make_internal_attr ("*delay_type", condexp, 1);
1619 /* For each delay possibility and delay slot, compute an eligibility
1620 attribute for non-annulled insns and for each type of annulled (annul
1621 if true and annul if false). */
1622 for (delay = delays; delay; delay = delay->next)
1624 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1626 condexp = XVECEXP (delay->def, 1, i);
1627 if (condexp == 0)
1628 condexp = false_rtx;
1629 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1630 make_numeric_value (1), make_numeric_value (0));
1632 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1633 "*delay_%d_%d", delay->num, i / 3);
1634 make_internal_attr (p, newexp, 1);
1636 if (have_annul_true)
1638 condexp = XVECEXP (delay->def, 1, i + 1);
1639 if (condexp == 0) condexp = false_rtx;
1640 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1641 make_numeric_value (1),
1642 make_numeric_value (0));
1643 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1644 "*annul_true_%d_%d", delay->num, i / 3);
1645 make_internal_attr (p, newexp, 1);
1648 if (have_annul_false)
1650 condexp = XVECEXP (delay->def, 1, i + 2);
1651 if (condexp == 0) condexp = false_rtx;
1652 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1653 make_numeric_value (1),
1654 make_numeric_value (0));
1655 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1656 "*annul_false_%d_%d", delay->num, i / 3);
1657 make_internal_attr (p, newexp, 1);
1663 /* This function is given a left and right side expression and an operator.
1664 Each side is a conditional expression, each alternative of which has a
1665 numerical value. The function returns another conditional expression
1666 which, for every possible set of condition values, returns a value that is
1667 the operator applied to the values of the two sides.
1669 Since this is called early, it must also support IF_THEN_ELSE. */
1671 static rtx
1672 operate_exp (op, left, right)
1673 enum operator op;
1674 rtx left, right;
1676 int left_value, right_value;
1677 rtx newexp;
1678 int i;
1680 /* If left is a string, apply operator to it and the right side. */
1681 if (GET_CODE (left) == CONST_STRING)
1683 /* If right is also a string, just perform the operation. */
1684 if (GET_CODE (right) == CONST_STRING)
1686 left_value = atoi (XSTR (left, 0));
1687 right_value = atoi (XSTR (right, 0));
1688 switch (op)
1690 case PLUS_OP:
1691 i = left_value + right_value;
1692 break;
1694 case MINUS_OP:
1695 i = left_value - right_value;
1696 break;
1698 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1699 if (left_value > right_value)
1700 i = left_value - right_value;
1701 else
1702 i = 0;
1703 break;
1705 case OR_OP:
1706 case ORX_OP:
1707 i = left_value | right_value;
1708 break;
1710 case EQ_OP:
1711 i = left_value == right_value;
1712 break;
1714 case RANGE_OP:
1715 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1716 break;
1718 case MAX_OP:
1719 if (left_value > right_value)
1720 i = left_value;
1721 else
1722 i = right_value;
1723 break;
1725 case MIN_OP:
1726 if (left_value < right_value)
1727 i = left_value;
1728 else
1729 i = right_value;
1730 break;
1732 default:
1733 abort ();
1736 if (i == left_value)
1737 return left;
1738 if (i == right_value)
1739 return right;
1740 return make_numeric_value (i);
1742 else if (GET_CODE (right) == IF_THEN_ELSE)
1744 /* Apply recursively to all values within. */
1745 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1746 rtx newright = operate_exp (op, left, XEXP (right, 2));
1747 if (rtx_equal_p (newleft, newright))
1748 return newleft;
1749 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1751 else if (GET_CODE (right) == COND)
1753 int allsame = 1;
1754 rtx defval;
1756 newexp = rtx_alloc (COND);
1757 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1758 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1760 for (i = 0; i < XVECLEN (right, 0); i += 2)
1762 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1763 XVECEXP (newexp, 0, i + 1)
1764 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1765 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1766 defval))
1767 allsame = 0;
1770 /* If the resulting cond is trivial (all alternatives
1771 give the same value), optimize it away. */
1772 if (allsame)
1773 return operate_exp (op, left, XEXP (right, 1));
1775 return newexp;
1777 else
1778 fatal ("badly formed attribute value");
1781 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1782 not associate through IF_THEN_ELSE. */
1783 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1785 return attr_rtx (IOR, left, right);
1788 /* Otherwise, do recursion the other way. */
1789 else if (GET_CODE (left) == IF_THEN_ELSE)
1791 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1792 rtx newright = operate_exp (op, XEXP (left, 2), right);
1793 if (rtx_equal_p (newleft, newright))
1794 return newleft;
1795 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1797 else if (GET_CODE (left) == COND)
1799 int allsame = 1;
1800 rtx defval;
1802 newexp = rtx_alloc (COND);
1803 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1804 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1806 for (i = 0; i < XVECLEN (left, 0); i += 2)
1808 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1809 XVECEXP (newexp, 0, i + 1)
1810 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1811 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1812 defval))
1813 allsame = 0;
1816 /* If the cond is trivial (all alternatives give the same value),
1817 optimize it away. */
1818 if (allsame)
1819 return operate_exp (op, XEXP (left, 1), right);
1821 /* If the result is the same as the LEFT operand,
1822 just use that. */
1823 if (rtx_equal_p (newexp, left))
1824 return left;
1826 return newexp;
1829 else
1830 fatal ("badly formed attribute value");
1831 /* NOTREACHED */
1832 return NULL;
1835 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1836 construct a number of attributes.
1838 The first produces a function `function_units_used' which is given an
1839 insn and produces an encoding showing which function units are required
1840 for the execution of that insn. If the value is non-negative, the insn
1841 uses that unit; otherwise, the value is a one's compliment mask of units
1842 used.
1844 The second produces a function `result_ready_cost' which is used to
1845 determine the time that the result of an insn will be ready and hence
1846 a worst-case schedule.
1848 Both of these produce quite complex expressions which are then set as the
1849 default value of internal attributes. Normal attribute simplification
1850 should produce reasonable expressions.
1852 For each unit, a `<name>_unit_ready_cost' function will take an
1853 insn and give the delay until that unit will be ready with the result
1854 and a `<name>_unit_conflict_cost' function is given an insn already
1855 executing on the unit and a candidate to execute and will give the
1856 cost from the time the executing insn started until the candidate
1857 can start (ignore limitations on the number of simultaneous insns).
1859 For each unit, a `<name>_unit_blockage' function is given an insn
1860 already executing on the unit and a candidate to execute and will
1861 give the delay incurred due to function unit conflicts. The range of
1862 blockage cost values for a given executing insn is given by the
1863 `<name>_unit_blockage_range' function. These values are encoded in
1864 an int where the upper half gives the minimum value and the lower
1865 half gives the maximum value. */
1867 static void
1868 expand_units ()
1870 struct function_unit *unit, **unit_num;
1871 struct function_unit_op *op, **op_array, ***unit_ops;
1872 rtx unitsmask;
1873 rtx readycost;
1874 rtx newexp;
1875 const char *str;
1876 int i, j, u, num, nvalues;
1878 /* Rebuild the condition for the unit to share the RTL expressions.
1879 Sharing is required by simplify_by_exploding. Build the issue delay
1880 expressions. Validate the expressions we were given for the conditions
1881 and conflict vector. Then make attributes for use in the conflict
1882 function. */
1884 for (unit = units; unit; unit = unit->next)
1886 unit->condexp = check_attr_test (unit->condexp, 0, unit->first_lineno);
1888 for (op = unit->ops; op; op = op->next)
1890 rtx issue_delay = make_numeric_value (op->issue_delay);
1891 rtx issue_exp = issue_delay;
1893 /* Build, validate, and simplify the issue delay expression. */
1894 if (op->conflict_exp != true_rtx)
1895 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1896 issue_exp, make_numeric_value (0));
1897 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1898 issue_exp),
1899 NULL_ATTR);
1900 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1901 op->issue_exp = issue_exp;
1903 /* Make an attribute for use in the conflict function if needed. */
1904 unit->needs_conflict_function = (unit->issue_delay.min
1905 != unit->issue_delay.max);
1906 if (unit->needs_conflict_function)
1908 str = attr_printf ((strlen (unit->name) + sizeof "*_cost_"
1909 + MAX_DIGITS),
1910 "*%s_cost_%d", unit->name, op->num);
1911 make_internal_attr (str, issue_exp, 1);
1914 /* Validate the condition. */
1915 op->condexp = check_attr_test (op->condexp, 0, op->lineno);
1919 /* Compute the mask of function units used. Initially, the unitsmask is
1920 zero. Set up a conditional to compute each unit's contribution. */
1921 unitsmask = make_numeric_value (0);
1922 newexp = rtx_alloc (IF_THEN_ELSE);
1923 XEXP (newexp, 2) = make_numeric_value (0);
1925 /* If we have just a few units, we may be all right expanding the whole
1926 thing. But the expansion is 2**N in space on the number of opclasses,
1927 so we can't do this for very long -- Alpha and MIPS in particular have
1928 problems with this. So in that situation, we fall back on an alternate
1929 implementation method. */
1930 #define NUM_UNITOP_CUTOFF 20
1932 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1934 /* Merge each function unit into the unit mask attributes. */
1935 for (unit = units; unit; unit = unit->next)
1937 XEXP (newexp, 0) = unit->condexp;
1938 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1939 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1942 else
1944 /* Merge each function unit into the unit mask attributes. */
1945 for (unit = units; unit; unit = unit->next)
1947 XEXP (newexp, 0) = unit->condexp;
1948 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1949 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1953 /* Simplify the unit mask expression, encode it, and make an attribute
1954 for the function_units_used function. */
1955 unitsmask = simplify_by_exploding (unitsmask);
1957 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1958 unitsmask = encode_units_mask (unitsmask);
1959 else
1961 /* We can no longer encode unitsmask at compile time, so emit code to
1962 calculate it at runtime. Rather, put a marker for where we'd do
1963 the code, and actually output it in write_attr_get(). */
1964 unitsmask = attr_rtx (FFS, unitsmask);
1967 make_internal_attr ("*function_units_used", unitsmask, 10);
1969 /* Create an array of ops for each unit. Add an extra unit for the
1970 result_ready_cost function that has the ops of all other units. */
1971 unit_ops = (struct function_unit_op ***)
1972 xmalloc ((num_units + 1) * sizeof (struct function_unit_op **));
1973 unit_num = (struct function_unit **)
1974 xmalloc ((num_units + 1) * sizeof (struct function_unit *));
1976 unit_num[num_units] = unit = (struct function_unit *)
1977 xmalloc (sizeof (struct function_unit));
1978 unit->num = num_units;
1979 unit->num_opclasses = 0;
1981 for (unit = units; unit; unit = unit->next)
1983 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1984 unit_num[unit->num] = unit;
1985 unit_ops[unit->num] = op_array = (struct function_unit_op **)
1986 xmalloc (unit->num_opclasses * sizeof (struct function_unit_op *));
1988 for (op = unit->ops; op; op = op->next)
1989 op_array[op->num] = op;
1992 /* Compose the array of ops for the extra unit. */
1993 unit_ops[num_units] = op_array = (struct function_unit_op **)
1994 xmalloc (unit_num[num_units]->num_opclasses
1995 * sizeof (struct function_unit_op *));
1997 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
1998 memcpy (&op_array[i], unit_ops[unit->num],
1999 unit->num_opclasses * sizeof (struct function_unit_op *));
2001 /* Compute the ready cost function for each unit by computing the
2002 condition for each non-default value. */
2003 for (u = 0; u <= num_units; u++)
2005 rtx orexp;
2006 int value;
2008 unit = unit_num[u];
2009 op_array = unit_ops[unit->num];
2010 num = unit->num_opclasses;
2012 /* Sort the array of ops into increasing ready cost order. */
2013 for (i = 0; i < num; i++)
2014 for (j = num - 1; j > i; j--)
2015 if (op_array[j - 1]->ready < op_array[j]->ready)
2017 op = op_array[j];
2018 op_array[j] = op_array[j - 1];
2019 op_array[j - 1] = op;
2022 /* Determine how many distinct non-default ready cost values there
2023 are. We use a default ready cost value of 1. */
2024 nvalues = 0; value = 1;
2025 for (i = num - 1; i >= 0; i--)
2026 if (op_array[i]->ready > value)
2028 value = op_array[i]->ready;
2029 nvalues++;
2032 if (nvalues == 0)
2033 readycost = make_numeric_value (1);
2034 else
2036 /* Construct the ready cost expression as a COND of each value from
2037 the largest to the smallest. */
2038 readycost = rtx_alloc (COND);
2039 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2040 XEXP (readycost, 1) = make_numeric_value (1);
2042 nvalues = 0;
2043 orexp = false_rtx;
2044 value = op_array[0]->ready;
2045 for (i = 0; i < num; i++)
2047 op = op_array[i];
2048 if (op->ready <= 1)
2049 break;
2050 else if (op->ready == value)
2051 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
2052 else
2054 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2055 XVECEXP (readycost, 0, nvalues * 2 + 1)
2056 = make_numeric_value (value);
2057 nvalues++;
2058 value = op->ready;
2059 orexp = op->condexp;
2062 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2063 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2066 if (u < num_units)
2068 rtx max_blockage = 0, min_blockage = 0;
2070 /* Simplify the readycost expression by only considering insns
2071 that use the unit. */
2072 readycost = simplify_knowing (readycost, unit->condexp);
2074 /* Determine the blockage cost the executing insn (E) given
2075 the candidate insn (C). This is the maximum of the issue
2076 delay, the pipeline delay, and the simultaneity constraint.
2077 Each function_unit_op represents the characteristics of the
2078 candidate insn, so in the expressions below, C is a known
2079 term and E is an unknown term.
2081 We compute the blockage cost for each E for every possible C.
2082 Thus OP represents E, and READYCOST is a list of values for
2083 every possible C.
2085 The issue delay function for C is op->issue_exp and is used to
2086 write the `<name>_unit_conflict_cost' function. Symbolicly
2087 this is "ISSUE-DELAY (E,C)".
2089 The pipeline delay results form the FIFO constraint on the
2090 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2092 The simultaneity constraint is based on how long it takes to
2093 fill the unit given the minimum issue delay. FILL-TIME is the
2094 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2095 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2096 if SIMULTANEITY is non-zero and zero otherwise.
2098 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2100 MAX (ISSUE-DELAY (E,C),
2101 READY-COST (E) - (READY-COST (C) - 1))
2103 and otherwise
2105 MAX (ISSUE-DELAY (E,C),
2106 READY-COST (E) - (READY-COST (C) - 1),
2107 READY-COST (E) - FILL-TIME)
2109 The `<name>_unit_blockage' function is computed by determining
2110 this value for each candidate insn. As these values are
2111 computed, we also compute the upper and lower bounds for
2112 BLOCKAGE (E,*). These are combined to form the function
2113 `<name>_unit_blockage_range'. Finally, the maximum blockage
2114 cost, MAX (BLOCKAGE (*,*)), is computed. */
2116 for (op = unit->ops; op; op = op->next)
2118 rtx blockage = op->issue_exp;
2119 blockage = simplify_knowing (blockage, unit->condexp);
2121 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2122 MIN (BLOCKAGE (E,*)). */
2123 if (max_blockage == 0)
2124 max_blockage = min_blockage = blockage;
2125 else
2127 max_blockage
2128 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2129 blockage),
2130 unit->condexp);
2131 min_blockage
2132 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2133 blockage),
2134 unit->condexp);
2137 /* Make an attribute for use in the blockage function. */
2138 str = attr_printf ((strlen (unit->name) + sizeof "*_block_"
2139 + MAX_DIGITS),
2140 "*%s_block_%d", unit->name, op->num);
2141 make_internal_attr (str, blockage, 1);
2144 /* Record MAX (BLOCKAGE (*,*)). */
2146 int unknown;
2147 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2150 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2151 same. If so, the blockage function carries no additional
2152 information and is not written. */
2153 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2154 newexp = simplify_knowing (newexp, unit->condexp);
2155 unit->needs_blockage_function
2156 = (GET_CODE (newexp) != CONST_STRING
2157 || atoi (XSTR (newexp, 0)) != 1);
2159 /* If the all values of BLOCKAGE (E,C) have the same value,
2160 neither blockage function is written. */
2161 unit->needs_range_function
2162 = (unit->needs_blockage_function
2163 || GET_CODE (max_blockage) != CONST_STRING);
2165 if (unit->needs_range_function)
2167 /* Compute the blockage range function and make an attribute
2168 for writing its value. */
2169 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2170 newexp = simplify_knowing (newexp, unit->condexp);
2172 str = attr_printf ((strlen (unit->name)
2173 + sizeof "*_unit_blockage_range"),
2174 "*%s_unit_blockage_range", unit->name);
2175 make_internal_attr (str, newexp, 20);
2178 str = attr_printf (strlen (unit->name) + sizeof "*_unit_ready_cost",
2179 "*%s_unit_ready_cost", unit->name);
2181 else
2182 str = "*result_ready_cost";
2184 /* Make an attribute for the ready_cost function. Simplifying
2185 further with simplify_by_exploding doesn't win. */
2186 make_internal_attr (str, readycost, 0);
2189 /* For each unit that requires a conflict cost function, make an attribute
2190 that maps insns to the operation number. */
2191 for (unit = units; unit; unit = unit->next)
2193 rtx caseexp;
2195 if (! unit->needs_conflict_function
2196 && ! unit->needs_blockage_function)
2197 continue;
2199 caseexp = rtx_alloc (COND);
2200 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2202 for (op = unit->ops; op; op = op->next)
2204 /* Make our adjustment to the COND being computed. If we are the
2205 last operation class, place our values into the default of the
2206 COND. */
2207 if (op->num == unit->num_opclasses - 1)
2209 XEXP (caseexp, 1) = make_numeric_value (op->num);
2211 else
2213 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2214 XVECEXP (caseexp, 0, op->num * 2 + 1)
2215 = make_numeric_value (op->num);
2219 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2220 str = attr_printf (strlen (unit->name) + sizeof "*_cases",
2221 "*%s_cases", unit->name);
2222 make_internal_attr (str, caseexp, 1);
2226 /* Simplify EXP given KNOWN_TRUE. */
2228 static rtx
2229 simplify_knowing (exp, known_true)
2230 rtx exp, known_true;
2232 if (GET_CODE (exp) != CONST_STRING)
2234 int unknown = 0, max;
2235 max = max_attr_value (exp, &unknown);
2236 if (! unknown)
2238 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2239 make_numeric_value (max));
2240 exp = simplify_by_exploding (exp);
2243 return exp;
2246 /* Translate the CONST_STRING expressions in X to change the encoding of
2247 value. On input, the value is a bitmask with a one bit for each unit
2248 used; on output, the value is the unit number (zero based) if one
2249 and only one unit is used or the one's compliment of the bitmask. */
2251 static rtx
2252 encode_units_mask (x)
2253 rtx x;
2255 int i;
2256 int j;
2257 enum rtx_code code;
2258 const char *fmt;
2260 code = GET_CODE (x);
2262 switch (code)
2264 case CONST_STRING:
2265 i = atoi (XSTR (x, 0));
2266 if (i < 0)
2267 /* The sign bit encodes a one's compliment mask. */
2268 abort ();
2269 else if (i != 0 && i == (i & -i))
2270 /* Only one bit is set, so yield that unit number. */
2271 for (j = 0; (i >>= 1) != 0; j++)
2273 else
2274 j = ~i;
2275 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2277 case REG:
2278 case QUEUED:
2279 case CONST_INT:
2280 case CONST_DOUBLE:
2281 case SYMBOL_REF:
2282 case CODE_LABEL:
2283 case PC:
2284 case CC0:
2285 case EQ_ATTR:
2286 return x;
2288 default:
2289 break;
2292 /* Compare the elements. If any pair of corresponding elements
2293 fail to match, return 0 for the whole things. */
2295 fmt = GET_RTX_FORMAT (code);
2296 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2298 switch (fmt[i])
2300 case 'V':
2301 case 'E':
2302 for (j = 0; j < XVECLEN (x, i); j++)
2303 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2304 break;
2306 case 'e':
2307 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2308 break;
2311 return x;
2314 /* Once all attributes and insns have been read and checked, we construct for
2315 each attribute value a list of all the insns that have that value for
2316 the attribute. */
2318 static void
2319 fill_attr (attr)
2320 struct attr_desc *attr;
2322 struct attr_value *av;
2323 struct insn_ent *ie;
2324 struct insn_def *id;
2325 int i;
2326 rtx value;
2328 /* Don't fill constant attributes. The value is independent of
2329 any particular insn. */
2330 if (attr->is_const)
2331 return;
2333 for (id = defs; id; id = id->next)
2335 /* If no value is specified for this insn for this attribute, use the
2336 default. */
2337 value = NULL;
2338 if (XVEC (id->def, id->vec_idx))
2339 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2340 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2341 attr->name))
2342 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2344 if (value == NULL)
2345 av = attr->default_val;
2346 else
2347 av = get_attr_value (value, attr, id->insn_code);
2349 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2350 ie->insn_code = id->insn_code;
2351 ie->insn_index = id->insn_code;
2352 insert_insn_ent (av, ie);
2356 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2357 test that checks relative positions of insns (uses MATCH_DUP or PC).
2358 If so, replace it with what is obtained by passing the expression to
2359 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2360 recursively on each value (including the default value). Otherwise,
2361 return the value returned by NO_ADDRESS_FN applied to EXP. */
2363 static rtx
2364 substitute_address (exp, no_address_fn, address_fn)
2365 rtx exp;
2366 rtx (*no_address_fn) PARAMS ((rtx));
2367 rtx (*address_fn) PARAMS ((rtx));
2369 int i;
2370 rtx newexp;
2372 if (GET_CODE (exp) == COND)
2374 /* See if any tests use addresses. */
2375 address_used = 0;
2376 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2377 walk_attr_value (XVECEXP (exp, 0, i));
2379 if (address_used)
2380 return (*address_fn) (exp);
2382 /* Make a new copy of this COND, replacing each element. */
2383 newexp = rtx_alloc (COND);
2384 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2385 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2387 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2388 XVECEXP (newexp, 0, i + 1)
2389 = substitute_address (XVECEXP (exp, 0, i + 1),
2390 no_address_fn, address_fn);
2393 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2394 no_address_fn, address_fn);
2396 return newexp;
2399 else if (GET_CODE (exp) == IF_THEN_ELSE)
2401 address_used = 0;
2402 walk_attr_value (XEXP (exp, 0));
2403 if (address_used)
2404 return (*address_fn) (exp);
2406 return attr_rtx (IF_THEN_ELSE,
2407 substitute_address (XEXP (exp, 0),
2408 no_address_fn, address_fn),
2409 substitute_address (XEXP (exp, 1),
2410 no_address_fn, address_fn),
2411 substitute_address (XEXP (exp, 2),
2412 no_address_fn, address_fn));
2415 return (*no_address_fn) (exp);
2418 /* Make new attributes from the `length' attribute. The following are made,
2419 each corresponding to a function called from `shorten_branches' or
2420 `get_attr_length':
2422 *insn_default_length This is the length of the insn to be returned
2423 by `get_attr_length' before `shorten_branches'
2424 has been called. In each case where the length
2425 depends on relative addresses, the largest
2426 possible is used. This routine is also used
2427 to compute the initial size of the insn.
2429 *insn_variable_length_p This returns 1 if the insn's length depends
2430 on relative addresses, zero otherwise.
2432 *insn_current_length This is only called when it is known that the
2433 insn has a variable length and returns the
2434 current length, based on relative addresses.
2437 static void
2438 make_length_attrs ()
2440 static const char *const new_names[] = {"*insn_default_length",
2441 "*insn_variable_length_p",
2442 "*insn_current_length"};
2443 static rtx (*const no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
2444 static rtx (*const address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
2445 size_t i;
2446 struct attr_desc *length_attr, *new_attr;
2447 struct attr_value *av, *new_av;
2448 struct insn_ent *ie, *new_ie;
2450 /* See if length attribute is defined. If so, it must be numeric. Make
2451 it special so we don't output anything for it. */
2452 length_attr = find_attr ("length", 0);
2453 if (length_attr == 0)
2454 return;
2456 if (! length_attr->is_numeric)
2457 fatal ("length attribute must be numeric");
2459 length_attr->is_const = 0;
2460 length_attr->is_special = 1;
2462 /* Make each new attribute, in turn. */
2463 for (i = 0; i < ARRAY_SIZE (new_names); i++)
2465 make_internal_attr (new_names[i],
2466 substitute_address (length_attr->default_val->value,
2467 no_address_fn[i], address_fn[i]),
2469 new_attr = find_attr (new_names[i], 0);
2470 for (av = length_attr->first_value; av; av = av->next)
2471 for (ie = av->first_insn; ie; ie = ie->next)
2473 new_av = get_attr_value (substitute_address (av->value,
2474 no_address_fn[i],
2475 address_fn[i]),
2476 new_attr, ie->insn_code);
2477 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2478 new_ie->insn_code = ie->insn_code;
2479 new_ie->insn_index = ie->insn_index;
2480 insert_insn_ent (new_av, new_ie);
2485 /* Utility functions called from above routine. */
2487 static rtx
2488 identity_fn (exp)
2489 rtx exp;
2491 return exp;
2494 static rtx
2495 zero_fn (exp)
2496 rtx exp ATTRIBUTE_UNUSED;
2498 return make_numeric_value (0);
2501 static rtx
2502 one_fn (exp)
2503 rtx exp ATTRIBUTE_UNUSED;
2505 return make_numeric_value (1);
2508 static rtx
2509 max_fn (exp)
2510 rtx exp;
2512 int unknown;
2513 return make_numeric_value (max_attr_value (exp, &unknown));
2516 static void
2517 write_length_unit_log ()
2519 struct attr_desc *length_attr = find_attr ("length", 0);
2520 struct attr_value *av;
2521 struct insn_ent *ie;
2522 unsigned int length_unit_log, length_or;
2523 int unknown = 0;
2525 if (length_attr == 0)
2526 return;
2527 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2528 for (av = length_attr->first_value; av; av = av->next)
2529 for (ie = av->first_insn; ie; ie = ie->next)
2530 length_or |= or_attr_value (av->value, &unknown);
2532 if (unknown)
2533 length_unit_log = 0;
2534 else
2536 length_or = ~length_or;
2537 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
2538 length_unit_log++;
2540 printf ("int length_unit_log = %u;\n", length_unit_log);
2543 /* Take a COND expression and see if any of the conditions in it can be
2544 simplified. If any are known true or known false for the particular insn
2545 code, the COND can be further simplified.
2547 Also call ourselves on any COND operations that are values of this COND.
2549 We do not modify EXP; rather, we make and return a new rtx. */
2551 static rtx
2552 simplify_cond (exp, insn_code, insn_index)
2553 rtx exp;
2554 int insn_code, insn_index;
2556 int i, j;
2557 /* We store the desired contents here,
2558 then build a new expression if they don't match EXP. */
2559 rtx defval = XEXP (exp, 1);
2560 rtx new_defval = XEXP (exp, 1);
2561 int len = XVECLEN (exp, 0);
2562 rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
2563 int allsame = 1;
2564 char *first_spacer;
2565 rtx ret;
2567 /* This lets us free all storage allocated below, if appropriate. */
2568 first_spacer = (char *) obstack_finish (rtl_obstack);
2570 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
2572 /* See if default value needs simplification. */
2573 if (GET_CODE (defval) == COND)
2574 new_defval = simplify_cond (defval, insn_code, insn_index);
2576 /* Simplify the subexpressions, and see what tests we can get rid of. */
2578 for (i = 0; i < len; i += 2)
2580 rtx newtest, newval;
2582 /* Simplify this test. */
2583 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
2584 tests[i] = newtest;
2586 newval = tests[i + 1];
2587 /* See if this value may need simplification. */
2588 if (GET_CODE (newval) == COND)
2589 newval = simplify_cond (newval, insn_code, insn_index);
2591 /* Look for ways to delete or combine this test. */
2592 if (newtest == true_rtx)
2594 /* If test is true, make this value the default
2595 and discard this + any following tests. */
2596 len = i;
2597 defval = tests[i + 1];
2598 new_defval = newval;
2601 else if (newtest == false_rtx)
2603 /* If test is false, discard it and its value. */
2604 for (j = i; j < len - 2; j++)
2605 tests[j] = tests[j + 2];
2606 len -= 2;
2609 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
2611 /* If this value and the value for the prev test are the same,
2612 merge the tests. */
2614 tests[i - 2]
2615 = insert_right_side (IOR, tests[i - 2], newtest,
2616 insn_code, insn_index);
2618 /* Delete this test/value. */
2619 for (j = i; j < len - 2; j++)
2620 tests[j] = tests[j + 2];
2621 len -= 2;
2624 else
2625 tests[i + 1] = newval;
2628 /* If the last test in a COND has the same value
2629 as the default value, that test isn't needed. */
2631 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
2632 len -= 2;
2634 /* See if we changed anything. */
2635 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2636 allsame = 0;
2637 else
2638 for (i = 0; i < len; i++)
2639 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
2641 allsame = 0;
2642 break;
2645 if (len == 0)
2647 if (GET_CODE (defval) == COND)
2648 ret = simplify_cond (defval, insn_code, insn_index);
2649 else
2650 ret = defval;
2652 else if (allsame)
2653 ret = exp;
2654 else
2656 rtx newexp = rtx_alloc (COND);
2658 XVEC (newexp, 0) = rtvec_alloc (len);
2659 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
2660 XEXP (newexp, 1) = new_defval;
2661 ret = newexp;
2663 free (tests);
2664 return ret;
2667 /* Remove an insn entry from an attribute value. */
2669 static void
2670 remove_insn_ent (av, ie)
2671 struct attr_value *av;
2672 struct insn_ent *ie;
2674 struct insn_ent *previe;
2676 if (av->first_insn == ie)
2677 av->first_insn = ie->next;
2678 else
2680 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2682 previe->next = ie->next;
2685 av->num_insns--;
2686 if (ie->insn_code == -1)
2687 av->has_asm_insn = 0;
2689 num_insn_ents--;
2692 /* Insert an insn entry in an attribute value list. */
2694 static void
2695 insert_insn_ent (av, ie)
2696 struct attr_value *av;
2697 struct insn_ent *ie;
2699 ie->next = av->first_insn;
2700 av->first_insn = ie;
2701 av->num_insns++;
2702 if (ie->insn_code == -1)
2703 av->has_asm_insn = 1;
2705 num_insn_ents++;
2708 /* This is a utility routine to take an expression that is a tree of either
2709 AND or IOR expressions and insert a new term. The new term will be
2710 inserted at the right side of the first node whose code does not match
2711 the root. A new node will be created with the root's code. Its left
2712 side will be the old right side and its right side will be the new
2713 term.
2715 If the `term' is itself a tree, all its leaves will be inserted. */
2717 static rtx
2718 insert_right_side (code, exp, term, insn_code, insn_index)
2719 enum rtx_code code;
2720 rtx exp;
2721 rtx term;
2722 int insn_code, insn_index;
2724 rtx newexp;
2726 /* Avoid consing in some special cases. */
2727 if (code == AND && term == true_rtx)
2728 return exp;
2729 if (code == AND && term == false_rtx)
2730 return false_rtx;
2731 if (code == AND && exp == true_rtx)
2732 return term;
2733 if (code == AND && exp == false_rtx)
2734 return false_rtx;
2735 if (code == IOR && term == true_rtx)
2736 return true_rtx;
2737 if (code == IOR && term == false_rtx)
2738 return exp;
2739 if (code == IOR && exp == true_rtx)
2740 return true_rtx;
2741 if (code == IOR && exp == false_rtx)
2742 return term;
2743 if (attr_equal_p (exp, term))
2744 return exp;
2746 if (GET_CODE (term) == code)
2748 exp = insert_right_side (code, exp, XEXP (term, 0),
2749 insn_code, insn_index);
2750 exp = insert_right_side (code, exp, XEXP (term, 1),
2751 insn_code, insn_index);
2753 return exp;
2756 if (GET_CODE (exp) == code)
2758 rtx new = insert_right_side (code, XEXP (exp, 1),
2759 term, insn_code, insn_index);
2760 if (new != XEXP (exp, 1))
2761 /* Make a copy of this expression and call recursively. */
2762 newexp = attr_rtx (code, XEXP (exp, 0), new);
2763 else
2764 newexp = exp;
2766 else
2768 /* Insert the new term. */
2769 newexp = attr_rtx (code, exp, term);
2772 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2775 /* If we have an expression which AND's a bunch of
2776 (not (eq_attrq "alternative" "n"))
2777 terms, we may have covered all or all but one of the possible alternatives.
2778 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2780 This routine is passed an expression and either AND or IOR. It returns a
2781 bitmask indicating which alternatives are mentioned within EXP. */
2783 static int
2784 compute_alternative_mask (exp, code)
2785 rtx exp;
2786 enum rtx_code code;
2788 const char *string;
2789 if (GET_CODE (exp) == code)
2790 return compute_alternative_mask (XEXP (exp, 0), code)
2791 | compute_alternative_mask (XEXP (exp, 1), code);
2793 else if (code == AND && GET_CODE (exp) == NOT
2794 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2795 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2796 string = XSTR (XEXP (exp, 0), 1);
2798 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2799 && XSTR (exp, 0) == alternative_name)
2800 string = XSTR (exp, 1);
2802 else
2803 return 0;
2805 if (string[1] == 0)
2806 return 1 << (string[0] - '0');
2807 return 1 << atoi (string);
2810 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2811 attribute with the value represented by that bit. */
2813 static rtx
2814 make_alternative_compare (mask)
2815 int mask;
2817 rtx newexp;
2818 int i;
2820 /* Find the bit. */
2821 for (i = 0; (mask & (1 << i)) == 0; i++)
2824 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2825 RTX_UNCHANGING_P (newexp) = 1;
2827 return newexp;
2830 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2831 of "attr" for this insn code. From that value, we can compute a test
2832 showing when the EQ_ATTR will be true. This routine performs that
2833 computation. If a test condition involves an address, we leave the EQ_ATTR
2834 intact because addresses are only valid for the `length' attribute.
2836 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2837 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2839 static rtx
2840 evaluate_eq_attr (exp, value, insn_code, insn_index)
2841 rtx exp;
2842 rtx value;
2843 int insn_code, insn_index;
2845 rtx orexp, andexp;
2846 rtx right;
2847 rtx newexp;
2848 int i;
2850 if (GET_CODE (value) == CONST_STRING)
2852 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2853 newexp = true_rtx;
2854 else
2855 newexp = false_rtx;
2857 else if (GET_CODE (value) == SYMBOL_REF)
2859 char *p;
2860 char string[256];
2862 if (GET_CODE (exp) != EQ_ATTR)
2863 abort ();
2865 if (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 > 256)
2866 abort ();
2868 strcpy (string, XSTR (exp, 0));
2869 strcat (string, "_");
2870 strcat (string, XSTR (exp, 1));
2871 for (p = string; *p; p++)
2872 *p = TOUPPER (*p);
2874 newexp = attr_rtx (EQ, value,
2875 attr_rtx (SYMBOL_REF,
2876 attr_string (string, strlen (string))));
2878 else if (GET_CODE (value) == COND)
2880 /* We construct an IOR of all the cases for which the requested attribute
2881 value is present. Since we start with FALSE, if it is not present,
2882 FALSE will be returned.
2884 Each case is the AND of the NOT's of the previous conditions with the
2885 current condition; in the default case the current condition is TRUE.
2887 For each possible COND value, call ourselves recursively.
2889 The extra TRUE and FALSE expressions will be eliminated by another
2890 call to the simplification routine. */
2892 orexp = false_rtx;
2893 andexp = true_rtx;
2895 if (current_alternative_string)
2896 clear_struct_flag (value);
2898 for (i = 0; i < XVECLEN (value, 0); i += 2)
2900 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2901 insn_code, insn_index);
2903 SIMPLIFY_ALTERNATIVE (this);
2905 right = insert_right_side (AND, andexp, this,
2906 insn_code, insn_index);
2907 right = insert_right_side (AND, right,
2908 evaluate_eq_attr (exp,
2909 XVECEXP (value, 0,
2910 i + 1),
2911 insn_code, insn_index),
2912 insn_code, insn_index);
2913 orexp = insert_right_side (IOR, orexp, right,
2914 insn_code, insn_index);
2916 /* Add this condition into the AND expression. */
2917 newexp = attr_rtx (NOT, this);
2918 andexp = insert_right_side (AND, andexp, newexp,
2919 insn_code, insn_index);
2922 /* Handle the default case. */
2923 right = insert_right_side (AND, andexp,
2924 evaluate_eq_attr (exp, XEXP (value, 1),
2925 insn_code, insn_index),
2926 insn_code, insn_index);
2927 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2929 else
2930 abort ();
2932 /* If uses an address, must return original expression. But set the
2933 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2935 address_used = 0;
2936 walk_attr_value (newexp);
2938 if (address_used)
2940 /* This had `&& current_alternative_string', which seems to be wrong. */
2941 if (! RTX_UNCHANGING_P (exp))
2942 return copy_rtx_unchanging (exp);
2943 return exp;
2945 else
2946 return newexp;
2949 /* This routine is called when an AND of a term with a tree of AND's is
2950 encountered. If the term or its complement is present in the tree, it
2951 can be replaced with TRUE or FALSE, respectively.
2953 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2954 be true and hence are complementary.
2956 There is one special case: If we see
2957 (and (not (eq_attr "att" "v1"))
2958 (eq_attr "att" "v2"))
2959 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2960 replace the term, not anything in the AND tree. So we pass a pointer to
2961 the term. */
2963 static rtx
2964 simplify_and_tree (exp, pterm, insn_code, insn_index)
2965 rtx exp;
2966 rtx *pterm;
2967 int insn_code, insn_index;
2969 rtx left, right;
2970 rtx newexp;
2971 rtx temp;
2972 int left_eliminates_term, right_eliminates_term;
2974 if (GET_CODE (exp) == AND)
2976 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2977 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2978 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2980 newexp = attr_rtx (GET_CODE (exp), left, right);
2982 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2986 else if (GET_CODE (exp) == IOR)
2988 /* For the IOR case, we do the same as above, except that we can
2989 only eliminate `term' if both sides of the IOR would do so. */
2990 temp = *pterm;
2991 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2992 left_eliminates_term = (temp == true_rtx);
2994 temp = *pterm;
2995 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2996 right_eliminates_term = (temp == true_rtx);
2998 if (left_eliminates_term && right_eliminates_term)
2999 *pterm = true_rtx;
3001 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3003 newexp = attr_rtx (GET_CODE (exp), left, right);
3005 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3009 /* Check for simplifications. Do some extra checking here since this
3010 routine is called so many times. */
3012 if (exp == *pterm)
3013 return true_rtx;
3015 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
3016 return false_rtx;
3018 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
3019 return false_rtx;
3021 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
3023 if (XSTR (exp, 0) != XSTR (*pterm, 0))
3024 return exp;
3026 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
3027 return true_rtx;
3028 else
3029 return false_rtx;
3032 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3033 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3035 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3036 return exp;
3038 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3039 return false_rtx;
3040 else
3041 return true_rtx;
3044 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3045 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3047 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3048 return exp;
3050 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3051 return false_rtx;
3052 else
3053 *pterm = true_rtx;
3056 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3058 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
3059 return true_rtx;
3062 else if (GET_CODE (exp) == NOT)
3064 if (attr_equal_p (XEXP (exp, 0), *pterm))
3065 return false_rtx;
3068 else if (GET_CODE (*pterm) == NOT)
3070 if (attr_equal_p (XEXP (*pterm, 0), exp))
3071 return false_rtx;
3074 else if (attr_equal_p (exp, *pterm))
3075 return true_rtx;
3077 return exp;
3080 /* Similar to `simplify_and_tree', but for IOR trees. */
3082 static rtx
3083 simplify_or_tree (exp, pterm, insn_code, insn_index)
3084 rtx exp;
3085 rtx *pterm;
3086 int insn_code, insn_index;
3088 rtx left, right;
3089 rtx newexp;
3090 rtx temp;
3091 int left_eliminates_term, right_eliminates_term;
3093 if (GET_CODE (exp) == IOR)
3095 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
3096 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3097 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3099 newexp = attr_rtx (GET_CODE (exp), left, right);
3101 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3105 else if (GET_CODE (exp) == AND)
3107 /* For the AND case, we do the same as above, except that we can
3108 only eliminate `term' if both sides of the AND would do so. */
3109 temp = *pterm;
3110 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3111 left_eliminates_term = (temp == false_rtx);
3113 temp = *pterm;
3114 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3115 right_eliminates_term = (temp == false_rtx);
3117 if (left_eliminates_term && right_eliminates_term)
3118 *pterm = false_rtx;
3120 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3122 newexp = attr_rtx (GET_CODE (exp), left, right);
3124 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3128 if (attr_equal_p (exp, *pterm))
3129 return false_rtx;
3131 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
3132 return true_rtx;
3134 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
3135 return true_rtx;
3137 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3138 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3139 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3140 *pterm = false_rtx;
3142 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3143 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3144 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3145 return false_rtx;
3147 return exp;
3149 /* Compute approximate cost of the expression. Used to decide whether
3150 expression is cheap enough for inline. */
3151 static int
3152 attr_rtx_cost (x)
3153 rtx x;
3155 int cost = 0;
3156 enum rtx_code code;
3157 if (!x)
3158 return 0;
3159 code = GET_CODE (x);
3160 switch (code)
3162 case MATCH_OPERAND:
3163 if (XSTR (x, 1)[0])
3164 return 10;
3165 else
3166 return 0;
3167 case EQ_ATTR:
3168 /* Alternatives don't result into function call. */
3169 if (!strcmp (XSTR (x, 0), "alternative"))
3170 return 0;
3171 else
3172 return 5;
3173 default:
3175 int i, j;
3176 const char *fmt = GET_RTX_FORMAT (code);
3177 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3179 switch (fmt[i])
3181 case 'V':
3182 case 'E':
3183 for (j = 0; j < XVECLEN (x, i); j++)
3184 cost += attr_rtx_cost (XVECEXP (x, i, j));
3185 break;
3186 case 'e':
3187 cost += attr_rtx_cost (XEXP (x, i));
3188 break;
3192 break;
3194 return cost;
3198 /* Simplify test expression and use temporary obstack in order to avoid
3199 memory bloat. Use RTX_UNCHANGING_P to avoid unnecesary simplifications
3200 and avoid unnecesary copying if possible. */
3202 static rtx
3203 simplify_test_exp_in_temp (exp, insn_code, insn_index)
3204 rtx exp;
3205 int insn_code, insn_index;
3207 rtx x;
3208 struct obstack *old;
3209 if (RTX_UNCHANGING_P (exp))
3210 return exp;
3211 old = rtl_obstack;
3212 rtl_obstack = temp_obstack;
3213 x = simplify_test_exp (exp, insn_code, insn_index);
3214 rtl_obstack = old;
3215 if (x == exp || rtl_obstack == temp_obstack)
3216 return x;
3217 return attr_copy_rtx (x);
3220 /* Given an expression, see if it can be simplified for a particular insn
3221 code based on the values of other attributes being tested. This can
3222 eliminate nested get_attr_... calls.
3224 Note that if an endless recursion is specified in the patterns, the
3225 optimization will loop. However, it will do so in precisely the cases where
3226 an infinite recursion loop could occur during compilation. It's better that
3227 it occurs here! */
3229 static rtx
3230 simplify_test_exp (exp, insn_code, insn_index)
3231 rtx exp;
3232 int insn_code, insn_index;
3234 rtx left, right;
3235 struct attr_desc *attr;
3236 struct attr_value *av;
3237 struct insn_ent *ie;
3238 int i;
3239 rtx newexp = exp;
3241 /* Don't re-simplify something we already simplified. */
3242 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3243 return exp;
3245 switch (GET_CODE (exp))
3247 case AND:
3248 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3249 SIMPLIFY_ALTERNATIVE (left);
3250 if (left == false_rtx)
3251 return false_rtx;
3252 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3253 SIMPLIFY_ALTERNATIVE (right);
3254 if (left == false_rtx)
3255 return false_rtx;
3257 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3258 present on both sides, apply the distributive law since this will
3259 yield simplifications. */
3260 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3261 && compute_alternative_mask (left, IOR)
3262 && compute_alternative_mask (right, IOR))
3264 if (GET_CODE (left) == IOR)
3266 rtx tem = left;
3267 left = right;
3268 right = tem;
3271 newexp = attr_rtx (IOR,
3272 attr_rtx (AND, left, XEXP (right, 0)),
3273 attr_rtx (AND, left, XEXP (right, 1)));
3275 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3278 /* Try with the term on both sides. */
3279 right = simplify_and_tree (right, &left, insn_code, insn_index);
3280 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3281 left = simplify_and_tree (left, &right, insn_code, insn_index);
3283 if (left == false_rtx || right == false_rtx)
3284 return false_rtx;
3285 else if (left == true_rtx)
3287 return right;
3289 else if (right == true_rtx)
3291 return left;
3293 /* See if all or all but one of the insn's alternatives are specified
3294 in this tree. Optimize if so. */
3296 else if (insn_code >= 0
3297 && (GET_CODE (left) == AND
3298 || (GET_CODE (left) == NOT
3299 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3300 && XSTR (XEXP (left, 0), 0) == alternative_name)
3301 || GET_CODE (right) == AND
3302 || (GET_CODE (right) == NOT
3303 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3304 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3306 i = compute_alternative_mask (exp, AND);
3307 if (i & ~insn_alternatives[insn_code])
3308 fatal ("invalid alternative specified for pattern number %d",
3309 insn_index);
3311 /* If all alternatives are excluded, this is false. */
3312 i ^= insn_alternatives[insn_code];
3313 if (i == 0)
3314 return false_rtx;
3315 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3317 /* If just one excluded, AND a comparison with that one to the
3318 front of the tree. The others will be eliminated by
3319 optimization. We do not want to do this if the insn has one
3320 alternative and we have tested none of them! */
3321 left = make_alternative_compare (i);
3322 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3323 newexp = attr_rtx (AND, left, right);
3325 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3329 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3331 newexp = attr_rtx (AND, left, right);
3332 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3334 break;
3336 case IOR:
3337 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3338 SIMPLIFY_ALTERNATIVE (left);
3339 if (left == true_rtx)
3340 return true_rtx;
3341 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3342 SIMPLIFY_ALTERNATIVE (right);
3343 if (right == true_rtx)
3344 return true_rtx;
3346 right = simplify_or_tree (right, &left, insn_code, insn_index);
3347 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3348 left = simplify_or_tree (left, &right, insn_code, insn_index);
3350 if (right == true_rtx || left == true_rtx)
3351 return true_rtx;
3352 else if (left == false_rtx)
3354 return right;
3356 else if (right == false_rtx)
3358 return left;
3361 /* Test for simple cases where the distributive law is useful. I.e.,
3362 convert (ior (and (x) (y))
3363 (and (x) (z)))
3364 to (and (x)
3365 (ior (y) (z)))
3368 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3369 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3371 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3373 left = XEXP (left, 0);
3374 right = newexp;
3375 newexp = attr_rtx (AND, left, right);
3376 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3379 /* See if all or all but one of the insn's alternatives are specified
3380 in this tree. Optimize if so. */
3382 else if (insn_code >= 0
3383 && (GET_CODE (left) == IOR
3384 || (GET_CODE (left) == EQ_ATTR
3385 && XSTR (left, 0) == alternative_name)
3386 || GET_CODE (right) == IOR
3387 || (GET_CODE (right) == EQ_ATTR
3388 && XSTR (right, 0) == alternative_name)))
3390 i = compute_alternative_mask (exp, IOR);
3391 if (i & ~insn_alternatives[insn_code])
3392 fatal ("invalid alternative specified for pattern number %d",
3393 insn_index);
3395 /* If all alternatives are included, this is true. */
3396 i ^= insn_alternatives[insn_code];
3397 if (i == 0)
3398 return true_rtx;
3399 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3401 /* If just one excluded, IOR a comparison with that one to the
3402 front of the tree. The others will be eliminated by
3403 optimization. We do not want to do this if the insn has one
3404 alternative and we have tested none of them! */
3405 left = make_alternative_compare (i);
3406 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3407 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3409 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3413 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3415 newexp = attr_rtx (IOR, left, right);
3416 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3418 break;
3420 case NOT:
3421 if (GET_CODE (XEXP (exp, 0)) == NOT)
3423 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3424 insn_code, insn_index);
3425 SIMPLIFY_ALTERNATIVE (left);
3426 return left;
3429 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3430 SIMPLIFY_ALTERNATIVE (left);
3431 if (GET_CODE (left) == NOT)
3432 return XEXP (left, 0);
3434 if (left == false_rtx)
3435 return true_rtx;
3436 else if (left == true_rtx)
3437 return false_rtx;
3439 /* Try to apply De`Morgan's laws. */
3440 else if (GET_CODE (left) == IOR)
3442 newexp = attr_rtx (AND,
3443 attr_rtx (NOT, XEXP (left, 0)),
3444 attr_rtx (NOT, XEXP (left, 1)));
3446 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3448 else if (GET_CODE (left) == AND)
3450 newexp = attr_rtx (IOR,
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 (left != XEXP (exp, 0))
3458 newexp = attr_rtx (NOT, left);
3460 break;
3462 case EQ_ATTR:
3463 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3464 return (XSTR (exp, 1) == current_alternative_string
3465 ? true_rtx : false_rtx);
3467 /* Look at the value for this insn code in the specified attribute.
3468 We normally can replace this comparison with the condition that
3469 would give this insn the values being tested for. */
3470 if (XSTR (exp, 0) != alternative_name
3471 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3472 for (av = attr->first_value; av; av = av->next)
3473 for (ie = av->first_insn; ie; ie = ie->next)
3474 if (ie->insn_code == insn_code)
3476 rtx x;
3477 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3478 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
3479 if (attr_rtx_cost(x) < 20)
3480 return x;
3482 break;
3484 default:
3485 break;
3488 /* We have already simplified this expression. Simplifying it again
3489 won't buy anything unless we weren't given a valid insn code
3490 to process (i.e., we are canonicalizing something.). */
3491 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3492 && ! RTX_UNCHANGING_P (newexp))
3493 return copy_rtx_unchanging (newexp);
3495 return newexp;
3498 /* Optimize the attribute lists by seeing if we can determine conditional
3499 values from the known values of other attributes. This will save subroutine
3500 calls during the compilation. */
3502 static void
3503 optimize_attrs ()
3505 struct attr_desc *attr;
3506 struct attr_value *av;
3507 struct insn_ent *ie;
3508 rtx newexp;
3509 int i;
3510 struct attr_value_list
3512 struct attr_value *av;
3513 struct insn_ent *ie;
3514 struct attr_desc *attr;
3515 struct attr_value_list *next;
3517 struct attr_value_list **insn_code_values;
3518 struct attr_value_list *ivbuf;
3519 struct attr_value_list *iv;
3521 /* For each insn code, make a list of all the insn_ent's for it,
3522 for all values for all attributes. */
3524 if (num_insn_ents == 0)
3525 return;
3527 /* Make 2 extra elements, for "code" values -2 and -1. */
3528 insn_code_values
3529 = (struct attr_value_list **) xmalloc ((insn_code_number + 2)
3530 * sizeof (struct attr_value_list *));
3531 memset ((char *) insn_code_values, 0,
3532 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3534 /* Offset the table address so we can index by -2 or -1. */
3535 insn_code_values += 2;
3537 iv = ivbuf = ((struct attr_value_list *)
3538 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3540 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3541 for (attr = attrs[i]; attr; attr = attr->next)
3542 for (av = attr->first_value; av; av = av->next)
3543 for (ie = av->first_insn; ie; ie = ie->next)
3545 iv->attr = attr;
3546 iv->av = av;
3547 iv->ie = ie;
3548 iv->next = insn_code_values[ie->insn_code];
3549 insn_code_values[ie->insn_code] = iv;
3550 iv++;
3553 /* Sanity check on num_insn_ents. */
3554 if (iv != ivbuf + num_insn_ents)
3555 abort ();
3557 /* Process one insn code at a time. */
3558 for (i = -2; i < insn_code_number; i++)
3560 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3561 We use it to mean "already simplified for this insn". */
3562 for (iv = insn_code_values[i]; iv; iv = iv->next)
3563 clear_struct_flag (iv->av->value);
3565 for (iv = insn_code_values[i]; iv; iv = iv->next)
3567 struct obstack *old = rtl_obstack;
3569 attr = iv->attr;
3570 av = iv->av;
3571 ie = iv->ie;
3572 if (GET_CODE (av->value) != COND)
3573 continue;
3575 rtl_obstack = temp_obstack;
3576 #if 0 /* This was intended as a speed up, but it was slower. */
3577 if (insn_n_alternatives[ie->insn_code] > 6
3578 && count_sub_rtxs (av->value, 200) >= 200)
3579 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3580 ie->insn_index);
3581 else
3582 #endif
3583 newexp = av->value;
3584 while (GET_CODE (newexp) == COND)
3586 rtx newexp2 = simplify_cond (newexp, ie->insn_code,
3587 ie->insn_index);
3588 if (newexp2 == newexp)
3589 break;
3590 newexp = newexp2;
3593 rtl_obstack = old;
3594 if (newexp != av->value)
3596 newexp = attr_copy_rtx (newexp);
3597 remove_insn_ent (av, ie);
3598 av = get_attr_value (newexp, attr, ie->insn_code);
3599 iv->av = av;
3600 insert_insn_ent (av, ie);
3605 free (ivbuf);
3606 free (insn_code_values - 2);
3609 #if 0
3610 static rtx
3611 simplify_by_alternatives (exp, insn_code, insn_index)
3612 rtx exp;
3613 int insn_code, insn_index;
3615 int i;
3616 int len = insn_n_alternatives[insn_code];
3617 rtx newexp = rtx_alloc (COND);
3618 rtx ultimate;
3620 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3622 /* It will not matter what value we use as the default value
3623 of the new COND, since that default will never be used.
3624 Choose something of the right type. */
3625 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3626 ultimate = XEXP (ultimate, 1);
3627 XEXP (newexp, 1) = ultimate;
3629 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3631 current_alternative_string = attr_numeral (i);
3632 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3633 XVECEXP (newexp, 0, i * 2 + 1)
3634 = simplify_cond (exp, insn_code, insn_index);
3637 current_alternative_string = 0;
3638 return simplify_cond (newexp, insn_code, insn_index);
3640 #endif
3642 /* If EXP is a suitable expression, reorganize it by constructing an
3643 equivalent expression that is a COND with the tests being all combinations
3644 of attribute values and the values being simple constants. */
3646 static rtx
3647 simplify_by_exploding (exp)
3648 rtx exp;
3650 rtx list = 0, link, condexp, defval = NULL_RTX;
3651 struct dimension *space;
3652 rtx *condtest, *condval;
3653 int i, j, total, ndim = 0;
3654 int most_tests, num_marks, new_marks;
3655 rtx ret;
3657 /* Locate all the EQ_ATTR expressions. */
3658 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3660 unmark_used_attributes (list, 0, 0);
3661 return exp;
3664 /* Create an attribute space from the list of used attributes. For each
3665 dimension in the attribute space, record the attribute, list of values
3666 used, and number of values used. Add members to the list of values to
3667 cover the domain of the attribute. This makes the expanded COND form
3668 order independent. */
3670 space = (struct dimension *) xmalloc (ndim * sizeof (struct dimension));
3672 total = 1;
3673 for (ndim = 0; list; ndim++)
3675 /* Pull the first attribute value from the list and record that
3676 attribute as another dimension in the attribute space. */
3677 const char *name = XSTR (XEXP (list, 0), 0);
3678 rtx *prev;
3680 if ((space[ndim].attr = find_attr (name, 0)) == 0
3681 || space[ndim].attr->is_numeric)
3683 unmark_used_attributes (list, space, ndim);
3684 return exp;
3687 /* Add all remaining attribute values that refer to this attribute. */
3688 space[ndim].num_values = 0;
3689 space[ndim].values = 0;
3690 prev = &list;
3691 for (link = list; link; link = *prev)
3692 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3694 space[ndim].num_values++;
3695 *prev = XEXP (link, 1);
3696 XEXP (link, 1) = space[ndim].values;
3697 space[ndim].values = link;
3699 else
3700 prev = &XEXP (link, 1);
3702 /* Add sufficient members to the list of values to make the list
3703 mutually exclusive and record the total size of the attribute
3704 space. */
3705 total *= add_values_to_cover (&space[ndim]);
3708 /* Sort the attribute space so that the attributes go from non-constant
3709 to constant and from most values to least values. */
3710 for (i = 0; i < ndim; i++)
3711 for (j = ndim - 1; j > i; j--)
3712 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3713 || space[j-1].num_values < space[j].num_values)
3715 struct dimension tmp;
3716 tmp = space[j];
3717 space[j] = space[j - 1];
3718 space[j - 1] = tmp;
3721 /* Establish the initial current value. */
3722 for (i = 0; i < ndim; i++)
3723 space[i].current_value = space[i].values;
3725 condtest = (rtx *) xmalloc (total * sizeof (rtx));
3726 condval = (rtx *) xmalloc (total * sizeof (rtx));
3728 /* Expand the tests and values by iterating over all values in the
3729 attribute space. */
3730 for (i = 0;; i++)
3732 condtest[i] = test_for_current_value (space, ndim);
3733 condval[i] = simplify_with_current_value (exp, space, ndim);
3734 if (! increment_current_value (space, ndim))
3735 break;
3737 if (i != total - 1)
3738 abort ();
3740 /* We are now finished with the original expression. */
3741 unmark_used_attributes (0, space, ndim);
3742 free (space);
3744 /* Find the most used constant value and make that the default. */
3745 most_tests = -1;
3746 for (i = num_marks = 0; i < total; i++)
3747 if (GET_CODE (condval[i]) == CONST_STRING
3748 && ! MEM_VOLATILE_P (condval[i]))
3750 /* Mark the unmarked constant value and count how many are marked. */
3751 MEM_VOLATILE_P (condval[i]) = 1;
3752 for (j = new_marks = 0; j < total; j++)
3753 if (GET_CODE (condval[j]) == CONST_STRING
3754 && MEM_VOLATILE_P (condval[j]))
3755 new_marks++;
3756 if (new_marks - num_marks > most_tests)
3758 most_tests = new_marks - num_marks;
3759 defval = condval[i];
3761 num_marks = new_marks;
3763 /* Clear all the marks. */
3764 for (i = 0; i < total; i++)
3765 MEM_VOLATILE_P (condval[i]) = 0;
3767 /* Give up if nothing is constant. */
3768 if (num_marks == 0)
3769 ret = exp;
3771 /* If all values are the default, use that. */
3772 else if (total == most_tests)
3773 ret = defval;
3775 /* Make a COND with the most common constant value the default. (A more
3776 complex method where tests with the same value were combined didn't
3777 seem to improve things.) */
3778 else
3780 condexp = rtx_alloc (COND);
3781 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3782 XEXP (condexp, 1) = defval;
3783 for (i = j = 0; i < total; i++)
3784 if (condval[i] != defval)
3786 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3787 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3788 j++;
3790 ret = condexp;
3792 free (condtest);
3793 free (condval);
3794 return ret;
3797 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3798 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3799 tests have known value. */
3801 static int
3802 find_and_mark_used_attributes (exp, terms, nterms)
3803 rtx exp, *terms;
3804 int *nterms;
3806 int i;
3808 switch (GET_CODE (exp))
3810 case EQ_ATTR:
3811 if (! MEM_VOLATILE_P (exp))
3813 rtx link = rtx_alloc (EXPR_LIST);
3814 XEXP (link, 0) = exp;
3815 XEXP (link, 1) = *terms;
3816 *terms = link;
3817 *nterms += 1;
3818 MEM_VOLATILE_P (exp) = 1;
3820 return 1;
3822 case CONST_STRING:
3823 case CONST_INT:
3824 return 1;
3826 case IF_THEN_ELSE:
3827 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3828 return 0;
3829 case IOR:
3830 case AND:
3831 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3832 return 0;
3833 case NOT:
3834 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3835 return 0;
3836 return 1;
3838 case COND:
3839 for (i = 0; i < XVECLEN (exp, 0); i++)
3840 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3841 return 0;
3842 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3843 return 0;
3844 return 1;
3846 default:
3847 return 0;
3851 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3852 in the values of the NDIM-dimensional attribute space SPACE. */
3854 static void
3855 unmark_used_attributes (list, space, ndim)
3856 rtx list;
3857 struct dimension *space;
3858 int ndim;
3860 rtx link, exp;
3861 int i;
3863 for (i = 0; i < ndim; i++)
3864 unmark_used_attributes (space[i].values, 0, 0);
3866 for (link = list; link; link = XEXP (link, 1))
3868 exp = XEXP (link, 0);
3869 if (GET_CODE (exp) == EQ_ATTR)
3870 MEM_VOLATILE_P (exp) = 0;
3874 /* Update the attribute dimension DIM so that all values of the attribute
3875 are tested. Return the updated number of values. */
3877 static int
3878 add_values_to_cover (dim)
3879 struct dimension *dim;
3881 struct attr_value *av;
3882 rtx exp, link, *prev;
3883 int nalt = 0;
3885 for (av = dim->attr->first_value; av; av = av->next)
3886 if (GET_CODE (av->value) == CONST_STRING)
3887 nalt++;
3889 if (nalt < dim->num_values)
3890 abort ();
3891 else if (nalt == dim->num_values)
3892 /* OK. */
3894 else if (nalt * 2 < dim->num_values * 3)
3896 /* Most all the values of the attribute are used, so add all the unused
3897 values. */
3898 prev = &dim->values;
3899 for (link = dim->values; link; link = *prev)
3900 prev = &XEXP (link, 1);
3902 for (av = dim->attr->first_value; av; av = av->next)
3903 if (GET_CODE (av->value) == CONST_STRING)
3905 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3906 if (MEM_VOLATILE_P (exp))
3907 continue;
3909 link = rtx_alloc (EXPR_LIST);
3910 XEXP (link, 0) = exp;
3911 XEXP (link, 1) = 0;
3912 *prev = link;
3913 prev = &XEXP (link, 1);
3915 dim->num_values = nalt;
3917 else
3919 rtx orexp = false_rtx;
3921 /* Very few values are used, so compute a mutually exclusive
3922 expression. (We could do this for numeric values if that becomes
3923 important.) */
3924 prev = &dim->values;
3925 for (link = dim->values; link; link = *prev)
3927 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3928 prev = &XEXP (link, 1);
3930 link = rtx_alloc (EXPR_LIST);
3931 XEXP (link, 0) = attr_rtx (NOT, orexp);
3932 XEXP (link, 1) = 0;
3933 *prev = link;
3934 dim->num_values++;
3936 return dim->num_values;
3939 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3940 and return FALSE if the increment overflowed. */
3942 static int
3943 increment_current_value (space, ndim)
3944 struct dimension *space;
3945 int ndim;
3947 int i;
3949 for (i = ndim - 1; i >= 0; i--)
3951 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3952 space[i].current_value = space[i].values;
3953 else
3954 return 1;
3956 return 0;
3959 /* Construct an expression corresponding to the current value for the
3960 NDIM-dimensional attribute space SPACE. */
3962 static rtx
3963 test_for_current_value (space, ndim)
3964 struct dimension *space;
3965 int ndim;
3967 int i;
3968 rtx exp = true_rtx;
3970 for (i = 0; i < ndim; i++)
3971 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3972 -2, -2);
3974 return exp;
3977 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3978 set the corresponding EQ_ATTR expressions to that value and reduce
3979 the expression EXP as much as possible. On input [and output], all
3980 known EQ_ATTR expressions are set to FALSE. */
3982 static rtx
3983 simplify_with_current_value (exp, space, ndim)
3984 rtx exp;
3985 struct dimension *space;
3986 int ndim;
3988 int i;
3989 rtx x;
3991 /* Mark each current value as TRUE. */
3992 for (i = 0; i < ndim; i++)
3994 x = XEXP (space[i].current_value, 0);
3995 if (GET_CODE (x) == EQ_ATTR)
3996 MEM_VOLATILE_P (x) = 0;
3999 exp = simplify_with_current_value_aux (exp);
4001 /* Change each current value back to FALSE. */
4002 for (i = 0; i < ndim; i++)
4004 x = XEXP (space[i].current_value, 0);
4005 if (GET_CODE (x) == EQ_ATTR)
4006 MEM_VOLATILE_P (x) = 1;
4009 return exp;
4012 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
4013 all EQ_ATTR expressions. */
4015 static rtx
4016 simplify_with_current_value_aux (exp)
4017 rtx exp;
4019 int i;
4020 rtx cond;
4022 switch (GET_CODE (exp))
4024 case EQ_ATTR:
4025 if (MEM_VOLATILE_P (exp))
4026 return false_rtx;
4027 else
4028 return true_rtx;
4029 case CONST_STRING:
4030 case CONST_INT:
4031 return exp;
4033 case IF_THEN_ELSE:
4034 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4035 if (cond == true_rtx)
4036 return simplify_with_current_value_aux (XEXP (exp, 1));
4037 else if (cond == false_rtx)
4038 return simplify_with_current_value_aux (XEXP (exp, 2));
4039 else
4040 return attr_rtx (IF_THEN_ELSE, cond,
4041 simplify_with_current_value_aux (XEXP (exp, 1)),
4042 simplify_with_current_value_aux (XEXP (exp, 2)));
4044 case IOR:
4045 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4046 if (cond == true_rtx)
4047 return cond;
4048 else if (cond == false_rtx)
4049 return simplify_with_current_value_aux (XEXP (exp, 0));
4050 else
4051 return attr_rtx (IOR, cond,
4052 simplify_with_current_value_aux (XEXP (exp, 0)));
4054 case AND:
4055 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4056 if (cond == true_rtx)
4057 return simplify_with_current_value_aux (XEXP (exp, 0));
4058 else if (cond == false_rtx)
4059 return cond;
4060 else
4061 return attr_rtx (AND, cond,
4062 simplify_with_current_value_aux (XEXP (exp, 0)));
4064 case NOT:
4065 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4066 if (cond == true_rtx)
4067 return false_rtx;
4068 else if (cond == false_rtx)
4069 return true_rtx;
4070 else
4071 return attr_rtx (NOT, cond);
4073 case COND:
4074 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4076 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
4077 if (cond == true_rtx)
4078 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4079 else if (cond == false_rtx)
4080 continue;
4081 else
4082 abort (); /* With all EQ_ATTR's of known value, a case should
4083 have been selected. */
4085 return simplify_with_current_value_aux (XEXP (exp, 1));
4087 default:
4088 abort ();
4092 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
4094 static void
4095 clear_struct_flag (x)
4096 rtx x;
4098 int i;
4099 int j;
4100 enum rtx_code code;
4101 const char *fmt;
4103 MEM_IN_STRUCT_P (x) = 0;
4104 if (RTX_UNCHANGING_P (x))
4105 return;
4107 code = GET_CODE (x);
4109 switch (code)
4111 case REG:
4112 case QUEUED:
4113 case CONST_INT:
4114 case CONST_DOUBLE:
4115 case SYMBOL_REF:
4116 case CODE_LABEL:
4117 case PC:
4118 case CC0:
4119 case EQ_ATTR:
4120 case ATTR_FLAG:
4121 return;
4123 default:
4124 break;
4127 /* Compare the elements. If any pair of corresponding elements
4128 fail to match, return 0 for the whole things. */
4130 fmt = GET_RTX_FORMAT (code);
4131 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4133 switch (fmt[i])
4135 case 'V':
4136 case 'E':
4137 for (j = 0; j < XVECLEN (x, i); j++)
4138 clear_struct_flag (XVECEXP (x, i, j));
4139 break;
4141 case 'e':
4142 clear_struct_flag (XEXP (x, i));
4143 break;
4148 /* Return the number of RTX objects making up the expression X.
4149 But if we count more than MAX objects, stop counting. */
4151 static int
4152 count_sub_rtxs (x, max)
4153 rtx x;
4154 int max;
4156 int i;
4157 int j;
4158 enum rtx_code code;
4159 const char *fmt;
4160 int total = 0;
4162 code = GET_CODE (x);
4164 switch (code)
4166 case REG:
4167 case QUEUED:
4168 case CONST_INT:
4169 case CONST_DOUBLE:
4170 case SYMBOL_REF:
4171 case CODE_LABEL:
4172 case PC:
4173 case CC0:
4174 case EQ_ATTR:
4175 case ATTR_FLAG:
4176 return 1;
4178 default:
4179 break;
4182 /* Compare the elements. If any pair of corresponding elements
4183 fail to match, return 0 for the whole things. */
4185 fmt = GET_RTX_FORMAT (code);
4186 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4188 if (total >= max)
4189 return total;
4191 switch (fmt[i])
4193 case 'V':
4194 case 'E':
4195 for (j = 0; j < XVECLEN (x, i); j++)
4196 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4197 break;
4199 case 'e':
4200 total += count_sub_rtxs (XEXP (x, i), max);
4201 break;
4204 return total;
4208 /* Create table entries for DEFINE_ATTR. */
4210 static void
4211 gen_attr (exp, lineno)
4212 rtx exp;
4213 int lineno;
4215 struct attr_desc *attr;
4216 struct attr_value *av;
4217 const char *name_ptr;
4218 char *p;
4220 /* Make a new attribute structure. Check for duplicate by looking at
4221 attr->default_val, since it is initialized by this routine. */
4222 attr = find_attr (XSTR (exp, 0), 1);
4223 if (attr->default_val)
4225 message_with_line (lineno, "duplicate definition for attribute %s",
4226 attr->name);
4227 message_with_line (attr->lineno, "previous definition");
4228 have_error = 1;
4229 return;
4231 attr->lineno = lineno;
4233 if (*XSTR (exp, 1) == '\0')
4234 attr->is_numeric = 1;
4235 else
4237 name_ptr = XSTR (exp, 1);
4238 while ((p = next_comma_elt (&name_ptr)) != NULL)
4240 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4241 av->value = attr_rtx (CONST_STRING, p);
4242 av->next = attr->first_value;
4243 attr->first_value = av;
4244 av->first_insn = NULL;
4245 av->num_insns = 0;
4246 av->has_asm_insn = 0;
4250 if (GET_CODE (XEXP (exp, 2)) == CONST)
4252 attr->is_const = 1;
4253 if (attr->is_numeric)
4255 message_with_line (lineno,
4256 "constant attributes may not take numeric values");
4257 have_error = 1;
4260 /* Get rid of the CONST node. It is allowed only at top-level. */
4261 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4264 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4266 message_with_line (lineno,
4267 "`length' attribute must take numeric values");
4268 have_error = 1;
4271 /* Set up the default value. */
4272 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4273 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4276 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4277 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4278 number of alternatives as this should be checked elsewhere. */
4280 static int
4281 count_alternatives (exp)
4282 rtx exp;
4284 int i, j, n;
4285 const char *fmt;
4287 if (GET_CODE (exp) == MATCH_OPERAND)
4288 return n_comma_elts (XSTR (exp, 2));
4290 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4291 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4292 switch (*fmt++)
4294 case 'e':
4295 case 'u':
4296 n = count_alternatives (XEXP (exp, i));
4297 if (n)
4298 return n;
4299 break;
4301 case 'E':
4302 case 'V':
4303 if (XVEC (exp, i) != NULL)
4304 for (j = 0; j < XVECLEN (exp, i); j++)
4306 n = count_alternatives (XVECEXP (exp, i, j));
4307 if (n)
4308 return n;
4312 return 0;
4315 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4316 `alternative' attribute. */
4318 static int
4319 compares_alternatives_p (exp)
4320 rtx exp;
4322 int i, j;
4323 const char *fmt;
4325 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4326 return 1;
4328 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4329 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4330 switch (*fmt++)
4332 case 'e':
4333 case 'u':
4334 if (compares_alternatives_p (XEXP (exp, i)))
4335 return 1;
4336 break;
4338 case 'E':
4339 for (j = 0; j < XVECLEN (exp, i); j++)
4340 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4341 return 1;
4342 break;
4345 return 0;
4348 /* Returns non-zero is INNER is contained in EXP. */
4350 static int
4351 contained_in_p (inner, exp)
4352 rtx inner;
4353 rtx exp;
4355 int i, j;
4356 const char *fmt;
4358 if (rtx_equal_p (inner, exp))
4359 return 1;
4361 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4362 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4363 switch (*fmt++)
4365 case 'e':
4366 case 'u':
4367 if (contained_in_p (inner, XEXP (exp, i)))
4368 return 1;
4369 break;
4371 case 'E':
4372 for (j = 0; j < XVECLEN (exp, i); j++)
4373 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4374 return 1;
4375 break;
4378 return 0;
4381 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4383 static void
4384 gen_insn (exp, lineno)
4385 rtx exp;
4386 int lineno;
4388 struct insn_def *id;
4390 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4391 id->next = defs;
4392 defs = id;
4393 id->def = exp;
4394 id->lineno = lineno;
4396 switch (GET_CODE (exp))
4398 case DEFINE_INSN:
4399 id->insn_code = insn_code_number;
4400 id->insn_index = insn_index_number;
4401 id->num_alternatives = count_alternatives (exp);
4402 if (id->num_alternatives == 0)
4403 id->num_alternatives = 1;
4404 id->vec_idx = 4;
4405 break;
4407 case DEFINE_PEEPHOLE:
4408 id->insn_code = insn_code_number;
4409 id->insn_index = insn_index_number;
4410 id->num_alternatives = count_alternatives (exp);
4411 if (id->num_alternatives == 0)
4412 id->num_alternatives = 1;
4413 id->vec_idx = 3;
4414 break;
4416 case DEFINE_ASM_ATTRIBUTES:
4417 id->insn_code = -1;
4418 id->insn_index = -1;
4419 id->num_alternatives = 1;
4420 id->vec_idx = 0;
4421 got_define_asm_attributes = 1;
4422 break;
4424 default:
4425 abort ();
4429 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4430 true or annul false is specified, and make a `struct delay_desc'. */
4432 static void
4433 gen_delay (def, lineno)
4434 rtx def;
4435 int lineno;
4437 struct delay_desc *delay;
4438 int i;
4440 if (XVECLEN (def, 1) % 3 != 0)
4442 message_with_line (lineno,
4443 "number of elements in DEFINE_DELAY must be multiple of three");
4444 have_error = 1;
4445 return;
4448 for (i = 0; i < XVECLEN (def, 1); i += 3)
4450 if (XVECEXP (def, 1, i + 1))
4451 have_annul_true = 1;
4452 if (XVECEXP (def, 1, i + 2))
4453 have_annul_false = 1;
4456 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4457 delay->def = def;
4458 delay->num = ++num_delays;
4459 delay->next = delays;
4460 delay->lineno = lineno;
4461 delays = delay;
4464 /* Process a DEFINE_FUNCTION_UNIT.
4466 This gives information about a function unit contained in the CPU.
4467 We fill in a `struct function_unit_op' and a `struct function_unit'
4468 with information used later by `expand_unit'. */
4470 static void
4471 gen_unit (def, lineno)
4472 rtx def;
4473 int lineno;
4475 struct function_unit *unit;
4476 struct function_unit_op *op;
4477 const char *name = XSTR (def, 0);
4478 int multiplicity = XINT (def, 1);
4479 int simultaneity = XINT (def, 2);
4480 rtx condexp = XEXP (def, 3);
4481 int ready_cost = MAX (XINT (def, 4), 1);
4482 int issue_delay = MAX (XINT (def, 5), 1);
4484 /* See if we have already seen this function unit. If so, check that
4485 the multiplicity and simultaneity values are the same. If not, make
4486 a structure for this function unit. */
4487 for (unit = units; unit; unit = unit->next)
4488 if (! strcmp (unit->name, name))
4490 if (unit->multiplicity != multiplicity
4491 || unit->simultaneity != simultaneity)
4493 message_with_line (lineno,
4494 "differing specifications given for function unit %s",
4495 unit->name);
4496 message_with_line (unit->first_lineno, "previous definition");
4497 have_error = 1;
4498 return;
4500 break;
4503 if (unit == 0)
4505 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4506 unit->name = name;
4507 unit->multiplicity = multiplicity;
4508 unit->simultaneity = simultaneity;
4509 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4510 unit->num = num_units++;
4511 unit->num_opclasses = 0;
4512 unit->condexp = false_rtx;
4513 unit->ops = 0;
4514 unit->next = units;
4515 unit->first_lineno = lineno;
4516 units = unit;
4519 /* Make a new operation class structure entry and initialize it. */
4520 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4521 op->condexp = condexp;
4522 op->num = unit->num_opclasses++;
4523 op->ready = ready_cost;
4524 op->issue_delay = issue_delay;
4525 op->next = unit->ops;
4526 op->lineno = lineno;
4527 unit->ops = op;
4528 num_unit_opclasses++;
4530 /* Set our issue expression based on whether or not an optional conflict
4531 vector was specified. */
4532 if (XVEC (def, 6))
4534 /* Compute the IOR of all the specified expressions. */
4535 rtx orexp = false_rtx;
4536 int i;
4538 for (i = 0; i < XVECLEN (def, 6); i++)
4539 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4541 op->conflict_exp = orexp;
4542 extend_range (&unit->issue_delay, 1, issue_delay);
4544 else
4546 op->conflict_exp = true_rtx;
4547 extend_range (&unit->issue_delay, issue_delay, issue_delay);
4550 /* Merge our conditional into that of the function unit so we can determine
4551 which insns are used by the function unit. */
4552 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4555 /* Given a piece of RTX, print a C expression to test its truth value.
4556 We use AND and IOR both for logical and bit-wise operations, so
4557 interpret them as logical unless they are inside a comparison expression.
4558 The first bit of FLAGS will be non-zero in that case.
4560 Set the second bit of FLAGS to make references to attribute values use
4561 a cached local variable instead of calling a function. */
4563 static void
4564 write_test_expr (exp, flags)
4565 rtx exp;
4566 int flags;
4568 int comparison_operator = 0;
4569 RTX_CODE code;
4570 struct attr_desc *attr;
4572 /* In order not to worry about operator precedence, surround our part of
4573 the expression with parentheses. */
4575 printf ("(");
4576 code = GET_CODE (exp);
4577 switch (code)
4579 /* Binary operators. */
4580 case EQ: case NE:
4581 case GE: case GT: case GEU: case GTU:
4582 case LE: case LT: case LEU: case LTU:
4583 comparison_operator = 1;
4585 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4586 case AND: case IOR: case XOR:
4587 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4588 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
4589 switch (code)
4591 case EQ:
4592 printf (" == ");
4593 break;
4594 case NE:
4595 printf (" != ");
4596 break;
4597 case GE:
4598 printf (" >= ");
4599 break;
4600 case GT:
4601 printf (" > ");
4602 break;
4603 case GEU:
4604 printf (" >= (unsigned) ");
4605 break;
4606 case GTU:
4607 printf (" > (unsigned) ");
4608 break;
4609 case LE:
4610 printf (" <= ");
4611 break;
4612 case LT:
4613 printf (" < ");
4614 break;
4615 case LEU:
4616 printf (" <= (unsigned) ");
4617 break;
4618 case LTU:
4619 printf (" < (unsigned) ");
4620 break;
4621 case PLUS:
4622 printf (" + ");
4623 break;
4624 case MINUS:
4625 printf (" - ");
4626 break;
4627 case MULT:
4628 printf (" * ");
4629 break;
4630 case DIV:
4631 printf (" / ");
4632 break;
4633 case MOD:
4634 printf (" %% ");
4635 break;
4636 case AND:
4637 if (flags & 1)
4638 printf (" & ");
4639 else
4640 printf (" && ");
4641 break;
4642 case IOR:
4643 if (flags & 1)
4644 printf (" | ");
4645 else
4646 printf (" || ");
4647 break;
4648 case XOR:
4649 printf (" ^ ");
4650 break;
4651 case ASHIFT:
4652 printf (" << ");
4653 break;
4654 case LSHIFTRT:
4655 case ASHIFTRT:
4656 printf (" >> ");
4657 break;
4658 default:
4659 abort ();
4662 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
4663 break;
4665 case NOT:
4666 /* Special-case (not (eq_attrq "alternative" "x")) */
4667 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4668 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4670 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4671 break;
4674 /* Otherwise, fall through to normal unary operator. */
4676 /* Unary operators. */
4677 case ABS: case NEG:
4678 switch (code)
4680 case NOT:
4681 if (flags & 1)
4682 printf ("~ ");
4683 else
4684 printf ("! ");
4685 break;
4686 case ABS:
4687 printf ("abs ");
4688 break;
4689 case NEG:
4690 printf ("-");
4691 break;
4692 default:
4693 abort ();
4696 write_test_expr (XEXP (exp, 0), flags);
4697 break;
4699 /* Comparison test of an attribute with a value. Most of these will
4700 have been removed by optimization. Handle "alternative"
4701 specially and give error if EQ_ATTR present inside a comparison. */
4702 case EQ_ATTR:
4703 if (flags & 1)
4704 fatal ("EQ_ATTR not valid inside comparison");
4706 if (XSTR (exp, 0) == alternative_name)
4708 printf ("which_alternative == %s", XSTR (exp, 1));
4709 break;
4712 attr = find_attr (XSTR (exp, 0), 0);
4713 if (! attr)
4714 abort ();
4716 /* Now is the time to expand the value of a constant attribute. */
4717 if (attr->is_const)
4719 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4720 -2, -2),
4721 flags);
4723 else
4725 if (flags & 2)
4726 printf ("attr_%s", attr->name);
4727 else
4728 printf ("get_attr_%s (insn)", attr->name);
4729 printf (" == ");
4730 write_attr_valueq (attr, XSTR (exp, 1));
4732 break;
4734 /* Comparison test of flags for define_delays. */
4735 case ATTR_FLAG:
4736 if (flags & 1)
4737 fatal ("ATTR_FLAG not valid inside comparison");
4738 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4739 break;
4741 /* See if an operand matches a predicate. */
4742 case MATCH_OPERAND:
4743 /* If only a mode is given, just ensure the mode matches the operand.
4744 If neither a mode nor predicate is given, error. */
4745 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4747 if (GET_MODE (exp) == VOIDmode)
4748 fatal ("null MATCH_OPERAND specified as test");
4749 else
4750 printf ("GET_MODE (operands[%d]) == %smode",
4751 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4753 else
4754 printf ("%s (operands[%d], %smode)",
4755 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4756 break;
4758 case MATCH_INSN:
4759 printf ("%s (insn)", XSTR (exp, 0));
4760 break;
4762 /* Constant integer. */
4763 case CONST_INT:
4764 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
4765 break;
4767 /* A random C expression. */
4768 case SYMBOL_REF:
4769 printf ("%s", XSTR (exp, 0));
4770 break;
4772 /* The address of the branch target. */
4773 case MATCH_DUP:
4774 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
4775 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4776 break;
4778 case PC:
4779 /* The address of the current insn. We implement this actually as the
4780 address of the current insn for backward branches, but the last
4781 address of the next insn for forward branches, and both with
4782 adjustments that account for the worst-case possible stretching of
4783 intervening alignments between this insn and its destination. */
4784 printf ("insn_current_reference_address (insn)");
4785 break;
4787 case CONST_STRING:
4788 printf ("%s", XSTR (exp, 0));
4789 break;
4791 case IF_THEN_ELSE:
4792 write_test_expr (XEXP (exp, 0), flags & 2);
4793 printf (" ? ");
4794 write_test_expr (XEXP (exp, 1), flags | 1);
4795 printf (" : ");
4796 write_test_expr (XEXP (exp, 2), flags | 1);
4797 break;
4799 default:
4800 fatal ("bad RTX code `%s' in attribute calculation\n",
4801 GET_RTX_NAME (code));
4804 printf (")");
4807 /* Given an attribute value, return the maximum CONST_STRING argument
4808 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
4810 static int
4811 max_attr_value (exp, unknownp)
4812 rtx exp;
4813 int *unknownp;
4815 int current_max;
4816 int i, n;
4818 switch (GET_CODE (exp))
4820 case CONST_STRING:
4821 current_max = atoi (XSTR (exp, 0));
4822 break;
4824 case COND:
4825 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4826 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4828 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4829 if (n > current_max)
4830 current_max = n;
4832 break;
4834 case IF_THEN_ELSE:
4835 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4836 n = max_attr_value (XEXP (exp, 2), unknownp);
4837 if (n > current_max)
4838 current_max = n;
4839 break;
4841 default:
4842 *unknownp = 1;
4843 current_max = INT_MAX;
4844 break;
4847 return current_max;
4850 /* Given an attribute value, return the result of ORing together all
4851 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4852 if the numeric value is not known. */
4854 static int
4855 or_attr_value (exp, unknownp)
4856 rtx exp;
4857 int *unknownp;
4859 int current_or;
4860 int i;
4862 switch (GET_CODE (exp))
4864 case CONST_STRING:
4865 current_or = atoi (XSTR (exp, 0));
4866 break;
4868 case COND:
4869 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4870 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4871 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4872 break;
4874 case IF_THEN_ELSE:
4875 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4876 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4877 break;
4879 default:
4880 *unknownp = 1;
4881 current_or = -1;
4882 break;
4885 return current_or;
4888 /* Scan an attribute value, possibly a conditional, and record what actions
4889 will be required to do any conditional tests in it.
4891 Specifically, set
4892 `must_extract' if we need to extract the insn operands
4893 `must_constrain' if we must compute `which_alternative'
4894 `address_used' if an address expression was used
4895 `length_used' if an (eq_attr "length" ...) was used
4898 static void
4899 walk_attr_value (exp)
4900 rtx exp;
4902 int i, j;
4903 const char *fmt;
4904 RTX_CODE code;
4906 if (exp == NULL)
4907 return;
4909 code = GET_CODE (exp);
4910 switch (code)
4912 case SYMBOL_REF:
4913 if (! RTX_UNCHANGING_P (exp))
4914 /* Since this is an arbitrary expression, it can look at anything.
4915 However, constant expressions do not depend on any particular
4916 insn. */
4917 must_extract = must_constrain = 1;
4918 return;
4920 case MATCH_OPERAND:
4921 must_extract = 1;
4922 return;
4924 case EQ_ATTR:
4925 if (XSTR (exp, 0) == alternative_name)
4926 must_extract = must_constrain = 1;
4927 else if (strcmp (XSTR (exp, 0), "length") == 0)
4928 length_used = 1;
4929 return;
4931 case MATCH_DUP:
4932 must_extract = 1;
4933 address_used = 1;
4934 return;
4936 case PC:
4937 address_used = 1;
4938 return;
4940 case ATTR_FLAG:
4941 return;
4943 default:
4944 break;
4947 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4948 switch (*fmt++)
4950 case 'e':
4951 case 'u':
4952 walk_attr_value (XEXP (exp, i));
4953 break;
4955 case 'E':
4956 if (XVEC (exp, i) != NULL)
4957 for (j = 0; j < XVECLEN (exp, i); j++)
4958 walk_attr_value (XVECEXP (exp, i, j));
4959 break;
4963 /* Write out a function to obtain the attribute for a given INSN. */
4965 static void
4966 write_attr_get (attr)
4967 struct attr_desc *attr;
4969 struct attr_value *av, *common_av;
4971 /* Find the most used attribute value. Handle that as the `default' of the
4972 switch we will generate. */
4973 common_av = find_most_used (attr);
4975 /* Write out prototype of function. */
4976 if (!attr->is_numeric)
4977 printf ("extern enum attr_%s ", attr->name);
4978 else if (attr->unsigned_p)
4979 printf ("extern unsigned int ");
4980 else
4981 printf ("extern int ");
4982 /* If the attribute name starts with a star, the remainder is the name of
4983 the subroutine to use, instead of `get_attr_...'. */
4984 if (attr->name[0] == '*')
4985 printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
4986 else
4987 printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
4988 (attr->is_const ? "void" : "rtx"));
4990 /* Write out start of function, then all values with explicit `case' lines,
4991 then a `default', then the value with the most uses. */
4992 if (!attr->is_numeric)
4993 printf ("enum attr_%s\n", attr->name);
4994 else if (attr->unsigned_p)
4995 printf ("unsigned int\n");
4996 else
4997 printf ("int\n");
4999 /* If the attribute name starts with a star, the remainder is the name of
5000 the subroutine to use, instead of `get_attr_...'. */
5001 if (attr->name[0] == '*')
5002 printf ("%s (insn)\n", &attr->name[1]);
5003 else if (attr->is_const == 0)
5004 printf ("get_attr_%s (insn)\n", attr->name);
5005 else
5007 printf ("get_attr_%s ()\n", attr->name);
5008 printf ("{\n");
5010 for (av = attr->first_value; av; av = av->next)
5011 if (av->num_insns != 0)
5012 write_attr_set (attr, 2, av->value, "return", ";",
5013 true_rtx, av->first_insn->insn_code,
5014 av->first_insn->insn_index);
5016 printf ("}\n\n");
5017 return;
5020 printf (" rtx insn;\n");
5021 printf ("{\n");
5023 if (GET_CODE (common_av->value) == FFS)
5025 rtx p = XEXP (common_av->value, 0);
5027 /* No need to emit code to abort if the insn is unrecognized; the
5028 other get_attr_foo functions will do that when we call them. */
5030 write_toplevel_expr (p);
5032 printf ("\n if (accum && accum == (accum & -accum))\n");
5033 printf (" {\n");
5034 printf (" int i;\n");
5035 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
5036 printf (" accum = i;\n");
5037 printf (" }\n else\n");
5038 printf (" accum = ~accum;\n");
5039 printf (" return accum;\n}\n\n");
5041 else
5043 printf (" switch (recog_memoized (insn))\n");
5044 printf (" {\n");
5046 for (av = attr->first_value; av; av = av->next)
5047 if (av != common_av)
5048 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5050 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5051 printf (" }\n}\n\n");
5055 /* Given an AND tree of known true terms (because we are inside an `if' with
5056 that as the condition or are in an `else' clause) and an expression,
5057 replace any known true terms with TRUE. Use `simplify_and_tree' to do
5058 the bulk of the work. */
5060 static rtx
5061 eliminate_known_true (known_true, exp, insn_code, insn_index)
5062 rtx known_true;
5063 rtx exp;
5064 int insn_code, insn_index;
5066 rtx term;
5068 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
5070 if (GET_CODE (known_true) == AND)
5072 exp = eliminate_known_true (XEXP (known_true, 0), exp,
5073 insn_code, insn_index);
5074 exp = eliminate_known_true (XEXP (known_true, 1), exp,
5075 insn_code, insn_index);
5077 else
5079 term = known_true;
5080 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
5083 return exp;
5086 /* Write out a series of tests and assignment statements to perform tests and
5087 sets of an attribute value. We are passed an indentation amount and prefix
5088 and suffix strings to write around each attribute value (e.g., "return"
5089 and ";"). */
5091 static void
5092 write_attr_set (attr, indent, value, prefix, suffix, known_true,
5093 insn_code, insn_index)
5094 struct attr_desc *attr;
5095 int indent;
5096 rtx value;
5097 const char *prefix;
5098 const char *suffix;
5099 rtx known_true;
5100 int insn_code, insn_index;
5102 if (GET_CODE (value) == COND)
5104 /* Assume the default value will be the default of the COND unless we
5105 find an always true expression. */
5106 rtx default_val = XEXP (value, 1);
5107 rtx our_known_true = known_true;
5108 rtx newexp;
5109 int first_if = 1;
5110 int i;
5112 for (i = 0; i < XVECLEN (value, 0); i += 2)
5114 rtx testexp;
5115 rtx inner_true;
5117 testexp = eliminate_known_true (our_known_true,
5118 XVECEXP (value, 0, i),
5119 insn_code, insn_index);
5120 newexp = attr_rtx (NOT, testexp);
5121 newexp = insert_right_side (AND, our_known_true, newexp,
5122 insn_code, insn_index);
5124 /* If the test expression is always true or if the next `known_true'
5125 expression is always false, this is the last case, so break
5126 out and let this value be the `else' case. */
5127 if (testexp == true_rtx || newexp == false_rtx)
5129 default_val = XVECEXP (value, 0, i + 1);
5130 break;
5133 /* Compute the expression to pass to our recursive call as being
5134 known true. */
5135 inner_true = insert_right_side (AND, our_known_true,
5136 testexp, insn_code, insn_index);
5138 /* If this is always false, skip it. */
5139 if (inner_true == false_rtx)
5140 continue;
5142 write_indent (indent);
5143 printf ("%sif ", first_if ? "" : "else ");
5144 first_if = 0;
5145 write_test_expr (testexp, 0);
5146 printf ("\n");
5147 write_indent (indent + 2);
5148 printf ("{\n");
5150 write_attr_set (attr, indent + 4,
5151 XVECEXP (value, 0, i + 1), prefix, suffix,
5152 inner_true, insn_code, insn_index);
5153 write_indent (indent + 2);
5154 printf ("}\n");
5155 our_known_true = newexp;
5158 if (! first_if)
5160 write_indent (indent);
5161 printf ("else\n");
5162 write_indent (indent + 2);
5163 printf ("{\n");
5166 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5167 prefix, suffix, our_known_true, insn_code, insn_index);
5169 if (! first_if)
5171 write_indent (indent + 2);
5172 printf ("}\n");
5175 else
5177 write_indent (indent);
5178 printf ("%s ", prefix);
5179 write_attr_value (attr, value);
5180 printf ("%s\n", suffix);
5184 /* Write out the computation for one attribute value. */
5186 static void
5187 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5188 known_true)
5189 struct attr_desc *attr;
5190 struct attr_value *av;
5191 int write_case_lines;
5192 const char *prefix, *suffix;
5193 int indent;
5194 rtx known_true;
5196 struct insn_ent *ie;
5198 if (av->num_insns == 0)
5199 return;
5201 if (av->has_asm_insn)
5203 write_indent (indent);
5204 printf ("case -1:\n");
5205 write_indent (indent + 2);
5206 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5207 write_indent (indent + 2);
5208 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5209 write_indent (indent + 2);
5210 printf (" fatal_insn_not_found (insn);\n");
5213 if (write_case_lines)
5215 for (ie = av->first_insn; ie; ie = ie->next)
5216 if (ie->insn_code != -1)
5218 write_indent (indent);
5219 printf ("case %d:\n", ie->insn_code);
5222 else
5224 write_indent (indent);
5225 printf ("default:\n");
5228 /* See what we have to do to output this value. */
5229 must_extract = must_constrain = address_used = 0;
5230 walk_attr_value (av->value);
5232 if (must_constrain)
5234 write_indent (indent + 2);
5235 printf ("extract_constrain_insn_cached (insn);\n");
5237 else if (must_extract)
5239 write_indent (indent + 2);
5240 printf ("extract_insn_cached (insn);\n");
5243 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5244 known_true, av->first_insn->insn_code,
5245 av->first_insn->insn_index);
5247 if (strncmp (prefix, "return", 6))
5249 write_indent (indent + 2);
5250 printf ("break;\n");
5252 printf ("\n");
5255 /* Search for uses of non-const attributes and write code to cache them. */
5257 static int
5258 write_expr_attr_cache (p, attr)
5259 rtx p;
5260 struct attr_desc *attr;
5262 const char *fmt;
5263 int i, ie, j, je;
5265 if (GET_CODE (p) == EQ_ATTR)
5267 if (XSTR (p, 0) != attr->name)
5268 return 0;
5270 if (!attr->is_numeric)
5271 printf (" enum attr_%s ", attr->name);
5272 else if (attr->unsigned_p)
5273 printf (" unsigned int ");
5274 else
5275 printf (" int ");
5277 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5278 return 1;
5281 fmt = GET_RTX_FORMAT (GET_CODE (p));
5282 ie = GET_RTX_LENGTH (GET_CODE (p));
5283 for (i = 0; i < ie; i++)
5285 switch (*fmt++)
5287 case 'e':
5288 if (write_expr_attr_cache (XEXP (p, i), attr))
5289 return 1;
5290 break;
5292 case 'E':
5293 je = XVECLEN (p, i);
5294 for (j = 0; j < je; ++j)
5295 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5296 return 1;
5297 break;
5301 return 0;
5304 /* Evaluate an expression at top level. A front end to write_test_expr,
5305 in which we cache attribute values and break up excessively large
5306 expressions to cater to older compilers. */
5308 static void
5309 write_toplevel_expr (p)
5310 rtx p;
5312 struct attr_desc *attr;
5313 int i;
5315 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
5316 for (attr = attrs[i]; attr; attr = attr->next)
5317 if (!attr->is_const)
5318 write_expr_attr_cache (p, attr);
5320 printf (" unsigned long accum = 0;\n\n");
5322 while (GET_CODE (p) == IOR)
5324 rtx e;
5325 if (GET_CODE (XEXP (p, 0)) == IOR)
5326 e = XEXP (p, 1), p = XEXP (p, 0);
5327 else
5328 e = XEXP (p, 0), p = XEXP (p, 1);
5330 printf (" accum |= ");
5331 write_test_expr (e, 3);
5332 printf (";\n");
5334 printf (" accum |= ");
5335 write_test_expr (p, 3);
5336 printf (";\n");
5339 /* Utilities to write names in various forms. */
5341 static void
5342 write_unit_name (prefix, num, suffix)
5343 const char *prefix;
5344 int num;
5345 const char *suffix;
5347 struct function_unit *unit;
5349 for (unit = units; unit; unit = unit->next)
5350 if (unit->num == num)
5352 printf ("%s%s%s", prefix, unit->name, suffix);
5353 return;
5356 printf ("%s<unknown>%s", prefix, suffix);
5359 static void
5360 write_attr_valueq (attr, s)
5361 struct attr_desc *attr;
5362 const char *s;
5364 if (attr->is_numeric)
5366 int num = atoi (s);
5368 printf ("%d", num);
5370 /* Make the blockage range values and function units used values easier
5371 to read. */
5372 if (attr->func_units_p)
5374 if (num == -1)
5375 printf (" /* units: none */");
5376 else if (num >= 0)
5377 write_unit_name (" /* units: ", num, " */");
5378 else
5380 int i;
5381 const char *sep = " /* units: ";
5382 for (i = 0, num = ~num; num; i++, num >>= 1)
5383 if (num & 1)
5385 write_unit_name (sep, i, (num == 1) ? " */" : "");
5386 sep = ", ";
5391 else if (attr->blockage_p)
5392 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5393 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5395 else if (num > 9 || num < 0)
5396 printf (" /* 0x%x */", num);
5398 else
5400 write_upcase (attr->name);
5401 printf ("_");
5402 write_upcase (s);
5406 static void
5407 write_attr_value (attr, value)
5408 struct attr_desc *attr;
5409 rtx value;
5411 int op;
5413 switch (GET_CODE (value))
5415 case CONST_STRING:
5416 write_attr_valueq (attr, XSTR (value, 0));
5417 break;
5419 case CONST_INT:
5420 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
5421 break;
5423 case SYMBOL_REF:
5424 fputs (XSTR (value, 0), stdout);
5425 break;
5427 case ATTR:
5429 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
5430 printf ("get_attr_%s (%s)", attr2->name,
5431 (attr2->is_const ? "" : "insn"));
5433 break;
5435 case PLUS:
5436 op = '+';
5437 goto do_operator;
5438 case MINUS:
5439 op = '-';
5440 goto do_operator;
5441 case MULT:
5442 op = '*';
5443 goto do_operator;
5444 case DIV:
5445 op = '/';
5446 goto do_operator;
5447 case MOD:
5448 op = '%';
5449 goto do_operator;
5451 do_operator:
5452 write_attr_value (attr, XEXP (value, 0));
5453 putchar (' ');
5454 putchar (op);
5455 putchar (' ');
5456 write_attr_value (attr, XEXP (value, 1));
5457 break;
5459 default:
5460 abort ();
5464 static void
5465 write_upcase (str)
5466 const char *str;
5468 while (*str)
5470 /* The argument of TOUPPER should not have side effects. */
5471 putchar (TOUPPER(*str));
5472 str++;
5476 static void
5477 write_indent (indent)
5478 int indent;
5480 for (; indent > 8; indent -= 8)
5481 printf ("\t");
5483 for (; indent; indent--)
5484 printf (" ");
5487 /* Write a subroutine that is given an insn that requires a delay slot, a
5488 delay slot ordinal, and a candidate insn. It returns non-zero if the
5489 candidate can be placed in the specified delay slot of the insn.
5491 We can write as many as three subroutines. `eligible_for_delay'
5492 handles normal delay slots, `eligible_for_annul_true' indicates that
5493 the specified insn can be annulled if the branch is true, and likewise
5494 for `eligible_for_annul_false'.
5496 KIND is a string distinguishing these three cases ("delay", "annul_true",
5497 or "annul_false"). */
5499 static void
5500 write_eligible_delay (kind)
5501 const char *kind;
5503 struct delay_desc *delay;
5504 int max_slots;
5505 char str[50];
5506 struct attr_desc *attr;
5507 struct attr_value *av, *common_av;
5508 int i;
5510 /* Compute the maximum number of delay slots required. We use the delay
5511 ordinal times this number plus one, plus the slot number as an index into
5512 the appropriate predicate to test. */
5514 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5515 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5516 max_slots = XVECLEN (delay->def, 1) / 3;
5518 /* Write function prelude. */
5520 printf ("int\n");
5521 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5522 kind);
5523 printf (" rtx delay_insn ATTRIBUTE_UNUSED;\n");
5524 printf (" int slot;\n");
5525 printf (" rtx candidate_insn;\n");
5526 printf (" int flags ATTRIBUTE_UNUSED;\n");
5527 printf ("{\n");
5528 printf (" rtx insn;\n");
5529 printf ("\n");
5530 printf (" if (slot >= %d)\n", max_slots);
5531 printf (" abort ();\n");
5532 printf ("\n");
5534 /* If more than one delay type, find out which type the delay insn is. */
5536 if (num_delays > 1)
5538 attr = find_attr ("*delay_type", 0);
5539 if (! attr)
5540 abort ();
5541 common_av = find_most_used (attr);
5543 printf (" insn = delay_insn;\n");
5544 printf (" switch (recog_memoized (insn))\n");
5545 printf (" {\n");
5547 sprintf (str, " * %d;\n break;", max_slots);
5548 for (av = attr->first_value; av; av = av->next)
5549 if (av != common_av)
5550 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5552 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5553 printf (" }\n\n");
5555 /* Ensure matched. Otherwise, shouldn't have been called. */
5556 printf (" if (slot < %d)\n", max_slots);
5557 printf (" abort ();\n\n");
5560 /* If just one type of delay slot, write simple switch. */
5561 if (num_delays == 1 && max_slots == 1)
5563 printf (" insn = candidate_insn;\n");
5564 printf (" switch (recog_memoized (insn))\n");
5565 printf (" {\n");
5567 attr = find_attr ("*delay_1_0", 0);
5568 if (! attr)
5569 abort ();
5570 common_av = find_most_used (attr);
5572 for (av = attr->first_value; av; av = av->next)
5573 if (av != common_av)
5574 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5576 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5577 printf (" }\n");
5580 else
5582 /* Write a nested CASE. The first indicates which condition we need to
5583 test, and the inner CASE tests the condition. */
5584 printf (" insn = candidate_insn;\n");
5585 printf (" switch (slot)\n");
5586 printf (" {\n");
5588 for (delay = delays; delay; delay = delay->next)
5589 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5591 printf (" case %d:\n",
5592 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5593 printf (" switch (recog_memoized (insn))\n");
5594 printf ("\t{\n");
5596 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5597 attr = find_attr (str, 0);
5598 if (! attr)
5599 abort ();
5600 common_av = find_most_used (attr);
5602 for (av = attr->first_value; av; av = av->next)
5603 if (av != common_av)
5604 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5606 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5607 printf (" }\n");
5610 printf (" default:\n");
5611 printf (" abort ();\n");
5612 printf (" }\n");
5615 printf ("}\n\n");
5618 /* Write routines to compute conflict cost for function units. Then write a
5619 table describing the available function units. */
5621 static void
5622 write_function_unit_info ()
5624 struct function_unit *unit;
5625 int i;
5627 /* Write out conflict routines for function units. Don't bother writing
5628 one if there is only one issue delay value. */
5630 for (unit = units; unit; unit = unit->next)
5632 if (unit->needs_blockage_function)
5633 write_complex_function (unit, "blockage", "block");
5635 /* If the minimum and maximum conflict costs are the same, there
5636 is only one value, so we don't need a function. */
5637 if (! unit->needs_conflict_function)
5639 unit->default_cost = make_numeric_value (unit->issue_delay.max);
5640 continue;
5643 /* The function first computes the case from the candidate insn. */
5644 unit->default_cost = make_numeric_value (0);
5645 write_complex_function (unit, "conflict_cost", "cost");
5648 /* Now that all functions have been written, write the table describing
5649 the function units. The name is included for documentation purposes
5650 only. */
5652 printf ("const struct function_unit_desc function_units[] = {\n");
5654 /* Write out the descriptions in numeric order, but don't force that order
5655 on the list. Doing so increases the runtime of genattrtab.c. */
5656 for (i = 0; i < num_units; i++)
5658 for (unit = units; unit; unit = unit->next)
5659 if (unit->num == i)
5660 break;
5662 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5663 unit->name, 1 << unit->num, unit->multiplicity,
5664 unit->simultaneity, XSTR (unit->default_cost, 0),
5665 unit->issue_delay.max, unit->name);
5667 if (unit->needs_conflict_function)
5668 printf ("%s_unit_conflict_cost, ", unit->name);
5669 else
5670 printf ("0, ");
5672 printf ("%d, ", unit->max_blockage);
5674 if (unit->needs_range_function)
5675 printf ("%s_unit_blockage_range, ", unit->name);
5676 else
5677 printf ("0, ");
5679 if (unit->needs_blockage_function)
5680 printf ("%s_unit_blockage", unit->name);
5681 else
5682 printf ("0");
5684 printf ("}, \n");
5687 printf ("};\n\n");
5690 static void
5691 write_complex_function (unit, name, connection)
5692 struct function_unit *unit;
5693 const char *name, *connection;
5695 struct attr_desc *case_attr, *attr;
5696 struct attr_value *av, *common_av;
5697 rtx value;
5698 char str[256];
5699 int using_case;
5700 int i;
5702 printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
5703 printf ("static int\n");
5704 printf ("%s_unit_%s (executing_insn, candidate_insn)\n", unit->name, name);
5705 printf (" rtx executing_insn;\n");
5706 printf (" rtx candidate_insn;\n");
5707 printf ("{\n");
5708 printf (" rtx insn;\n");
5709 printf (" int casenum;\n\n");
5710 printf (" insn = executing_insn;\n");
5711 printf (" switch (recog_memoized (insn))\n");
5712 printf (" {\n");
5714 /* Write the `switch' statement to get the case value. */
5715 if (strlen (unit->name) + sizeof "*_cases" > 256)
5716 abort ();
5717 sprintf (str, "*%s_cases", unit->name);
5718 case_attr = find_attr (str, 0);
5719 if (! case_attr)
5720 abort ();
5721 common_av = find_most_used (case_attr);
5723 for (av = case_attr->first_value; av; av = av->next)
5724 if (av != common_av)
5725 write_attr_case (case_attr, av, 1,
5726 "casenum =", ";", 4, unit->condexp);
5728 write_attr_case (case_attr, common_av, 0,
5729 "casenum =", ";", 4, unit->condexp);
5730 printf (" }\n\n");
5732 /* Now write an outer switch statement on each case. Then write
5733 the tests on the executing function within each. */
5734 printf (" insn = candidate_insn;\n");
5735 printf (" switch (casenum)\n");
5736 printf (" {\n");
5738 for (i = 0; i < unit->num_opclasses; i++)
5740 /* Ensure using this case. */
5741 using_case = 0;
5742 for (av = case_attr->first_value; av; av = av->next)
5743 if (av->num_insns
5744 && contained_in_p (make_numeric_value (i), av->value))
5745 using_case = 1;
5747 if (! using_case)
5748 continue;
5750 printf (" case %d:\n", i);
5751 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5752 attr = find_attr (str, 0);
5753 if (! attr)
5754 abort ();
5756 /* If single value, just write it. */
5757 value = find_single_value (attr);
5758 if (value)
5759 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5760 else
5762 common_av = find_most_used (attr);
5763 printf (" switch (recog_memoized (insn))\n");
5764 printf ("\t{\n");
5766 for (av = attr->first_value; av; av = av->next)
5767 if (av != common_av)
5768 write_attr_case (attr, av, 1,
5769 "return", ";", 8, unit->condexp);
5771 write_attr_case (attr, common_av, 0,
5772 "return", ";", 8, unit->condexp);
5773 printf (" }\n\n");
5777 /* This default case should not be needed, but gcc's analysis is not
5778 good enough to realize that the default case is not needed for the
5779 second switch statement. */
5780 printf (" default:\n abort ();\n");
5781 printf (" }\n}\n\n");
5784 /* This page contains miscellaneous utility routines. */
5786 /* Given a string, return the number of comma-separated elements in it.
5787 Return 0 for the null string. */
5789 static int
5790 n_comma_elts (s)
5791 const char *s;
5793 int n;
5795 if (*s == '\0')
5796 return 0;
5798 for (n = 1; *s; s++)
5799 if (*s == ',')
5800 n++;
5802 return n;
5805 /* Given a pointer to a (char *), return a malloc'ed string containing the
5806 next comma-separated element. Advance the pointer to after the string
5807 scanned, or the end-of-string. Return NULL if at end of string. */
5809 static char *
5810 next_comma_elt (pstr)
5811 const char **pstr;
5813 char *out_str;
5814 const char *p;
5816 if (**pstr == '\0')
5817 return NULL;
5819 /* Find end of string to compute length. */
5820 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5823 out_str = attr_string (*pstr, p - *pstr);
5824 *pstr = p;
5826 if (**pstr == ',')
5827 (*pstr)++;
5829 return out_str;
5832 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5833 is non-zero, build a new attribute, if one does not exist. */
5835 static struct attr_desc *
5836 find_attr (name, create)
5837 const char *name;
5838 int create;
5840 struct attr_desc *attr;
5841 int index;
5843 /* Before we resort to using `strcmp', see if the string address matches
5844 anywhere. In most cases, it should have been canonicalized to do so. */
5845 if (name == alternative_name)
5846 return NULL;
5848 index = name[0] & (MAX_ATTRS_INDEX - 1);
5849 for (attr = attrs[index]; attr; attr = attr->next)
5850 if (name == attr->name)
5851 return attr;
5853 /* Otherwise, do it the slow way. */
5854 for (attr = attrs[index]; attr; attr = attr->next)
5855 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5856 return attr;
5858 if (! create)
5859 return NULL;
5861 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5862 attr->name = attr_string (name, strlen (name));
5863 attr->first_value = attr->default_val = NULL;
5864 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5865 attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
5866 attr->next = attrs[index];
5867 attrs[index] = attr;
5869 return attr;
5872 /* Create internal attribute with the given default value. */
5874 static void
5875 make_internal_attr (name, value, special)
5876 const char *name;
5877 rtx value;
5878 int special;
5880 struct attr_desc *attr;
5882 attr = find_attr (name, 1);
5883 if (attr->default_val)
5884 abort ();
5886 attr->is_numeric = 1;
5887 attr->is_const = 0;
5888 attr->is_special = (special & 1) != 0;
5889 attr->negative_ok = (special & 2) != 0;
5890 attr->unsigned_p = (special & 4) != 0;
5891 attr->func_units_p = (special & 8) != 0;
5892 attr->blockage_p = (special & 16) != 0;
5893 attr->default_val = get_attr_value (value, attr, -2);
5896 /* Find the most used value of an attribute. */
5898 static struct attr_value *
5899 find_most_used (attr)
5900 struct attr_desc *attr;
5902 struct attr_value *av;
5903 struct attr_value *most_used;
5904 int nuses;
5906 most_used = NULL;
5907 nuses = -1;
5909 for (av = attr->first_value; av; av = av->next)
5910 if (av->num_insns > nuses)
5911 nuses = av->num_insns, most_used = av;
5913 return most_used;
5916 /* If an attribute only has a single value used, return it. Otherwise
5917 return NULL. */
5919 static rtx
5920 find_single_value (attr)
5921 struct attr_desc *attr;
5923 struct attr_value *av;
5924 rtx unique_value;
5926 unique_value = NULL;
5927 for (av = attr->first_value; av; av = av->next)
5928 if (av->num_insns)
5930 if (unique_value)
5931 return NULL;
5932 else
5933 unique_value = av->value;
5936 return unique_value;
5939 /* Return (attr_value "n") */
5941 static rtx
5942 make_numeric_value (n)
5943 int n;
5945 static rtx int_values[20];
5946 rtx exp;
5947 char *p;
5949 if (n < 0)
5950 abort ();
5952 if (n < 20 && int_values[n])
5953 return int_values[n];
5955 p = attr_printf (MAX_DIGITS, "%d", n);
5956 exp = attr_rtx (CONST_STRING, p);
5958 if (n < 20)
5959 int_values[n] = exp;
5961 return exp;
5964 static void
5965 extend_range (range, min, max)
5966 struct range *range;
5967 int min;
5968 int max;
5970 if (range->min > min)
5971 range->min = min;
5972 if (range->max < max)
5973 range->max = max;
5976 static rtx
5977 copy_rtx_unchanging (orig)
5978 rtx orig;
5980 #if 0
5981 rtx copy;
5982 RTX_CODE code;
5983 #endif
5985 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
5986 return orig;
5988 MEM_IN_STRUCT_P (orig) = 1;
5989 return orig;
5991 #if 0
5992 code = GET_CODE (orig);
5993 switch (code)
5995 case CONST_INT:
5996 case CONST_DOUBLE:
5997 case SYMBOL_REF:
5998 case CODE_LABEL:
5999 return orig;
6001 default:
6002 break;
6005 copy = rtx_alloc (code);
6006 PUT_MODE (copy, GET_MODE (orig));
6007 RTX_UNCHANGING_P (copy) = 1;
6009 memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
6010 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
6011 return copy;
6012 #endif
6015 /* Determine if an insn has a constant number of delay slots, i.e., the
6016 number of delay slots is not a function of the length of the insn. */
6018 static void
6019 write_const_num_delay_slots ()
6021 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
6022 struct attr_value *av;
6023 struct insn_ent *ie;
6025 if (attr)
6027 printf ("int\nconst_num_delay_slots (insn)\n");
6028 printf (" rtx insn;\n");
6029 printf ("{\n");
6030 printf (" switch (recog_memoized (insn))\n");
6031 printf (" {\n");
6033 for (av = attr->first_value; av; av = av->next)
6035 length_used = 0;
6036 walk_attr_value (av->value);
6037 if (length_used)
6039 for (ie = av->first_insn; ie; ie = ie->next)
6040 if (ie->insn_code != -1)
6041 printf (" case %d:\n", ie->insn_code);
6042 printf (" return 0;\n");
6046 printf (" default:\n");
6047 printf (" return 1;\n");
6048 printf (" }\n}\n\n");
6052 extern int main PARAMS ((int, char **));
6055 main (argc, argv)
6056 int argc;
6057 char **argv;
6059 rtx desc;
6060 struct attr_desc *attr;
6061 struct insn_def *id;
6062 rtx tem;
6063 int i;
6065 progname = "genattrtab";
6067 if (argc <= 1)
6068 fatal ("no input file name");
6070 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
6071 return (FATAL_EXIT_CODE);
6073 obstack_init (hash_obstack);
6074 obstack_init (temp_obstack);
6076 /* Set up true and false rtx's */
6077 true_rtx = rtx_alloc (CONST_INT);
6078 XWINT (true_rtx, 0) = 1;
6079 false_rtx = rtx_alloc (CONST_INT);
6080 XWINT (false_rtx, 0) = 0;
6081 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
6082 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
6084 alternative_name = attr_string ("alternative", strlen ("alternative"));
6086 printf ("/* Generated automatically by the program `genattrtab'\n\
6087 from the machine description file `md'. */\n\n");
6089 /* Read the machine description. */
6091 while (1)
6093 int lineno;
6095 desc = read_md_rtx (&lineno, &insn_code_number);
6096 if (desc == NULL)
6097 break;
6099 switch (GET_CODE (desc))
6101 case DEFINE_INSN:
6102 case DEFINE_PEEPHOLE:
6103 case DEFINE_ASM_ATTRIBUTES:
6104 gen_insn (desc, lineno);
6105 break;
6107 case DEFINE_ATTR:
6108 gen_attr (desc, lineno);
6109 break;
6111 case DEFINE_DELAY:
6112 gen_delay (desc, lineno);
6113 break;
6115 case DEFINE_FUNCTION_UNIT:
6116 gen_unit (desc, lineno);
6117 break;
6119 default:
6120 break;
6122 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
6123 insn_index_number++;
6126 if (have_error)
6127 return FATAL_EXIT_CODE;
6129 insn_code_number++;
6131 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6132 if (! got_define_asm_attributes)
6134 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6135 XVEC (tem, 0) = rtvec_alloc (0);
6136 gen_insn (tem, 0);
6139 /* Expand DEFINE_DELAY information into new attribute. */
6140 if (num_delays)
6141 expand_delays ();
6143 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6144 if (num_units)
6145 expand_units ();
6147 printf ("#include \"config.h\"\n");
6148 printf ("#include \"system.h\"\n");
6149 printf ("#include \"rtl.h\"\n");
6150 printf ("#include \"tm_p.h\"\n");
6151 printf ("#include \"insn-config.h\"\n");
6152 printf ("#include \"recog.h\"\n");
6153 printf ("#include \"regs.h\"\n");
6154 printf ("#include \"real.h\"\n");
6155 printf ("#include \"output.h\"\n");
6156 printf ("#include \"insn-attr.h\"\n");
6157 printf ("#include \"toplev.h\"\n");
6158 printf ("#include \"flags.h\"\n");
6159 printf ("\n");
6160 printf ("#define operands recog_data.operand\n\n");
6162 /* Make `insn_alternatives'. */
6163 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6164 for (id = defs; id; id = id->next)
6165 if (id->insn_code >= 0)
6166 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6168 /* Make `insn_n_alternatives'. */
6169 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6170 for (id = defs; id; id = id->next)
6171 if (id->insn_code >= 0)
6172 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6174 /* Prepare to write out attribute subroutines by checking everything stored
6175 away and building the attribute cases. */
6177 check_defs ();
6179 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6180 for (attr = attrs[i]; attr; attr = attr->next)
6181 attr->default_val->value
6182 = check_attr_value (attr->default_val->value, attr);
6184 if (have_error)
6185 return FATAL_EXIT_CODE;
6187 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6188 for (attr = attrs[i]; attr; attr = attr->next)
6189 fill_attr (attr);
6191 /* Construct extra attributes for `length'. */
6192 make_length_attrs ();
6194 /* Perform any possible optimizations to speed up compilation. */
6195 optimize_attrs ();
6197 /* Now write out all the `gen_attr_...' routines. Do these before the
6198 special routines (specifically before write_function_unit_info), so
6199 that they get defined before they are used. */
6201 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6202 for (attr = attrs[i]; attr; attr = attr->next)
6204 if (! attr->is_special && ! attr->is_const)
6205 write_attr_get (attr);
6208 /* Write out delay eligibility information, if DEFINE_DELAY present.
6209 (The function to compute the number of delay slots will be written
6210 below.) */
6211 if (num_delays)
6213 write_eligible_delay ("delay");
6214 if (have_annul_true)
6215 write_eligible_delay ("annul_true");
6216 if (have_annul_false)
6217 write_eligible_delay ("annul_false");
6220 /* Write out information about function units. */
6221 if (num_units)
6222 write_function_unit_info ();
6224 /* Write out constant delay slot info */
6225 write_const_num_delay_slots ();
6227 write_length_unit_log ();
6229 fflush (stdout);
6230 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6233 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
6234 const char *
6235 get_insn_name (code)
6236 int code ATTRIBUTE_UNUSED;
6238 return NULL;