* arm.md (addsf3, adddf3, subsf3, subdf3, mulsf3, muldf3, negsf2)
[official-gcc.git] / gcc / genattrtab.c
blob0270945abff034e86a1fe737825f7920b821e920
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002 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' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
90 independent of the insn code.
91 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
92 for the insn code currently being processed (see optimize_attrs).
93 `integrated' (ATTR_PERMANENT_P): This rtx is permanent and unique
94 (see attr_rtx).
95 `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
96 EQ_ATTR rtx is true if !volatil and false if volatil. */
98 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
99 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
100 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), integrated))
101 #define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
103 #include "bconfig.h"
104 #include "system.h"
105 #include "coretypes.h"
106 #include "tm.h"
107 #include "rtl.h"
108 #include "ggc.h"
109 #include "gensupport.h"
111 #ifdef HAVE_SYS_RESOURCE_H
112 # include <sys/resource.h>
113 #endif
115 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
116 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
117 #include "obstack.h"
118 #include "errors.h"
120 #include "genattrtab.h"
122 static struct obstack obstack1, obstack2;
123 struct obstack *hash_obstack = &obstack1;
124 struct obstack *temp_obstack = &obstack2;
126 /* enough space to reserve for printing out ints */
127 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
129 /* Define structures used to record attributes and values. */
131 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
132 encountered, we store all the relevant information into a
133 `struct insn_def'. This is done to allow attribute definitions to occur
134 anywhere in the file. */
136 struct insn_def
138 struct insn_def *next; /* Next insn in chain. */
139 rtx def; /* The DEFINE_... */
140 int insn_code; /* Instruction number. */
141 int insn_index; /* Expression numer in file, for errors. */
142 int lineno; /* Line number. */
143 int num_alternatives; /* Number of alternatives. */
144 int vec_idx; /* Index of attribute vector in `def'. */
147 /* Once everything has been read in, we store in each attribute value a list
148 of insn codes that have that value. Here is the structure used for the
149 list. */
151 struct insn_ent
153 struct insn_ent *next; /* Next in chain. */
154 int insn_code; /* Instruction number. */
155 int insn_index; /* Index of definition in file */
156 int lineno; /* Line number. */
159 /* Each value of an attribute (either constant or computed) is assigned a
160 structure which is used as the listhead of the insns that have that
161 value. */
163 struct attr_value
165 rtx value; /* Value of attribute. */
166 struct attr_value *next; /* Next attribute value in chain. */
167 struct insn_ent *first_insn; /* First insn with this value. */
168 int num_insns; /* Number of insns with this value. */
169 int has_asm_insn; /* True if this value used for `asm' insns */
172 /* Structure for each attribute. */
174 struct attr_desc
176 char *name; /* Name of attribute. */
177 struct attr_desc *next; /* Next attribute. */
178 unsigned is_numeric : 1; /* Values of this attribute are numeric. */
179 unsigned negative_ok : 1; /* Allow negative numeric values. */
180 unsigned unsigned_p : 1; /* Make the output function unsigned int. */
181 unsigned is_const : 1; /* Attribute value constant for each run. */
182 unsigned is_special : 1; /* Don't call `write_attr_set'. */
183 unsigned func_units_p : 1; /* this is the function_units attribute */
184 unsigned blockage_p : 1; /* this is the blockage range function */
185 struct attr_value *first_value; /* First value of this attribute. */
186 struct attr_value *default_val; /* Default value for this attribute. */
187 int lineno; /* Line number. */
190 #define NULL_ATTR (struct attr_desc *) NULL
192 /* A range of values. */
194 struct range
196 int min;
197 int max;
200 /* Structure for each DEFINE_DELAY. */
202 struct delay_desc
204 rtx def; /* DEFINE_DELAY expression. */
205 struct delay_desc *next; /* Next DEFINE_DELAY. */
206 int num; /* Number of DEFINE_DELAY, starting at 1. */
207 int lineno; /* Line number. */
210 /* Record information about each DEFINE_FUNCTION_UNIT. */
212 struct function_unit_op
214 rtx condexp; /* Expression TRUE for applicable insn. */
215 struct function_unit_op *next; /* Next operation for this function unit. */
216 int num; /* Ordinal for this operation type in unit. */
217 int ready; /* Cost until data is ready. */
218 int issue_delay; /* Cost until unit can accept another insn. */
219 rtx conflict_exp; /* Expression TRUE for insns incurring issue delay. */
220 rtx issue_exp; /* Expression computing issue delay. */
221 int lineno; /* Line number. */
224 /* Record information about each function unit mentioned in a
225 DEFINE_FUNCTION_UNIT. */
227 struct function_unit
229 const char *name; /* Function unit name. */
230 struct function_unit *next; /* Next function unit. */
231 int num; /* Ordinal of this unit type. */
232 int multiplicity; /* Number of units of this type. */
233 int simultaneity; /* Maximum number of simultaneous insns
234 on this function unit or 0 if unlimited. */
235 rtx condexp; /* Expression TRUE for insn needing unit. */
236 int num_opclasses; /* Number of different operation types. */
237 struct function_unit_op *ops; /* Pointer to first operation type. */
238 int needs_conflict_function; /* Nonzero if a conflict function required. */
239 int needs_blockage_function; /* Nonzero if a blockage function required. */
240 int needs_range_function; /* Nonzero if blockage range function needed. */
241 rtx default_cost; /* Conflict cost, if constant. */
242 struct range issue_delay; /* Range of issue delay values. */
243 int max_blockage; /* Maximum time an insn blocks the unit. */
244 int first_lineno; /* First seen line number. */
247 /* Listheads of above structures. */
249 /* This one is indexed by the first character of the attribute name. */
250 #define MAX_ATTRS_INDEX 256
251 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
252 static struct insn_def *defs;
253 static struct delay_desc *delays;
254 static struct function_unit *units;
256 /* An expression where all the unknown terms are EQ_ATTR tests can be
257 rearranged into a COND provided we can enumerate all possible
258 combinations of the unknown values. The set of combinations become the
259 tests of the COND; the value of the expression given that combination is
260 computed and becomes the corresponding value. To do this, we must be
261 able to enumerate all values for each attribute used in the expression
262 (currently, we give up if we find a numeric attribute).
264 If the set of EQ_ATTR tests used in an expression tests the value of N
265 different attributes, the list of all possible combinations can be made
266 by walking the N-dimensional attribute space defined by those
267 attributes. We record each of these as a struct dimension.
269 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
270 expression are the same, the will also have the same address. We find
271 all the EQ_ATTR nodes by marking them ATTR_EQ_ATTR_P. This bit later
272 represents the value of an EQ_ATTR node, so once all nodes are marked,
273 they are also given an initial value of FALSE.
275 We then separate the set of EQ_ATTR nodes into dimensions for each
276 attribute and put them on the VALUES list. Terms are added as needed by
277 `add_values_to_cover' so that all possible values of the attribute are
278 tested.
280 Each dimension also has a current value. This is the node that is
281 currently considered to be TRUE. If this is one of the nodes added by
282 `add_values_to_cover', all the EQ_ATTR tests in the original expression
283 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
285 NUM_VALUES is simply the length of the VALUES list and is there for
286 convenience.
288 Once the dimensions are created, the algorithm enumerates all possible
289 values and computes the current value of the given expression. */
291 struct dimension
293 struct attr_desc *attr; /* Attribute for this dimension. */
294 rtx values; /* List of attribute values used. */
295 rtx current_value; /* Position in the list for the TRUE value. */
296 int num_values; /* Length of the values list. */
299 /* Other variables. */
301 static int insn_code_number;
302 static int insn_index_number;
303 static int got_define_asm_attributes;
304 static int must_extract;
305 static int must_constrain;
306 static int address_used;
307 static int length_used;
308 static int num_delays;
309 static int have_annul_true, have_annul_false;
310 static int num_units, num_unit_opclasses;
311 static int num_insn_ents;
313 int num_dfa_decls;
315 /* Used as operand to `operate_exp': */
317 enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP};
319 /* Stores, for each insn code, the number of constraint alternatives. */
321 static int *insn_n_alternatives;
323 /* Stores, for each insn code, a bitmap that has bits on for each possible
324 alternative. */
326 static int *insn_alternatives;
328 /* If nonzero, assume that the `alternative' attr has this value.
329 This is the hashed, unique string for the numeral
330 whose value is chosen alternative. */
332 static const char *current_alternative_string;
334 /* Used to simplify expressions. */
336 static rtx true_rtx, false_rtx;
338 /* Used to reduce calls to `strcmp' */
340 static char *alternative_name;
342 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
343 called. */
345 int reload_completed = 0;
347 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
348 to define it here. */
350 int optimize = 0;
352 /* Simplify an expression. Only call the routine if there is something to
353 simplify. */
354 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
355 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
356 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
358 /* Simplify (eq_attr ("alternative") ...)
359 when we are working with a particular alternative. */
360 #define SIMPLIFY_ALTERNATIVE(EXP) \
361 if (current_alternative_string \
362 && GET_CODE ((EXP)) == EQ_ATTR \
363 && XSTR ((EXP), 0) == alternative_name) \
364 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
365 ? true_rtx : false_rtx);
367 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
368 They won't actually be used. */
370 rtx global_rtl[GR_MAX];
371 rtx pic_offset_table_rtx;
373 static void attr_hash_add_rtx PARAMS ((int, rtx));
374 static void attr_hash_add_string PARAMS ((int, char *));
375 static rtx attr_rtx PARAMS ((enum rtx_code, ...));
376 static rtx attr_rtx_1 PARAMS ((enum rtx_code, va_list));
377 static char *attr_string PARAMS ((const char *, int));
378 static rtx check_attr_value PARAMS ((rtx, struct attr_desc *));
379 static rtx convert_set_attr_alternative PARAMS ((rtx, struct insn_def *));
380 static rtx convert_set_attr PARAMS ((rtx, struct insn_def *));
381 static void check_defs PARAMS ((void));
382 #if 0
383 static rtx convert_const_symbol_ref PARAMS ((rtx, struct attr_desc *));
384 #endif
385 static rtx make_canonical PARAMS ((struct attr_desc *, rtx));
386 static struct attr_value *get_attr_value PARAMS ((rtx, struct attr_desc *, int));
387 static rtx copy_rtx_unchanging PARAMS ((rtx));
388 static rtx copy_boolean PARAMS ((rtx));
389 static void expand_delays PARAMS ((void));
390 static rtx operate_exp PARAMS ((enum operator, rtx, rtx));
391 static void expand_units PARAMS ((void));
392 static rtx simplify_knowing PARAMS ((rtx, rtx));
393 static rtx encode_units_mask PARAMS ((rtx));
394 static void fill_attr PARAMS ((struct attr_desc *));
395 static rtx substitute_address PARAMS ((rtx, rtx (*) (rtx), rtx (*) (rtx)));
396 static void make_length_attrs PARAMS ((void));
397 static rtx identity_fn PARAMS ((rtx));
398 static rtx zero_fn PARAMS ((rtx));
399 static rtx one_fn PARAMS ((rtx));
400 static rtx max_fn PARAMS ((rtx));
401 static void write_length_unit_log PARAMS ((void));
402 static rtx simplify_cond PARAMS ((rtx, int, int));
403 #if 0
404 static rtx simplify_by_alternatives PARAMS ((rtx, int, int));
405 #endif
406 static rtx simplify_by_exploding PARAMS ((rtx));
407 static int find_and_mark_used_attributes PARAMS ((rtx, rtx *, int *));
408 static void unmark_used_attributes PARAMS ((rtx, struct dimension *, int));
409 static int add_values_to_cover PARAMS ((struct dimension *));
410 static int increment_current_value PARAMS ((struct dimension *, int));
411 static rtx test_for_current_value PARAMS ((struct dimension *, int));
412 static rtx simplify_with_current_value PARAMS ((rtx, struct dimension *, int));
413 static rtx simplify_with_current_value_aux PARAMS ((rtx));
414 static void clear_struct_flag PARAMS ((rtx));
415 static int count_sub_rtxs PARAMS ((rtx, int));
416 static void remove_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
417 static void insert_insn_ent PARAMS ((struct attr_value *, struct insn_ent *));
418 static rtx insert_right_side PARAMS ((enum rtx_code, rtx, rtx, int, int));
419 static rtx make_alternative_compare PARAMS ((int));
420 static int compute_alternative_mask PARAMS ((rtx, enum rtx_code));
421 static rtx evaluate_eq_attr PARAMS ((rtx, rtx, int, int));
422 static rtx simplify_and_tree PARAMS ((rtx, rtx *, int, int));
423 static rtx simplify_or_tree PARAMS ((rtx, rtx *, int, int));
424 static rtx simplify_test_exp PARAMS ((rtx, int, int));
425 static rtx simplify_test_exp_in_temp PARAMS ((rtx, int, int));
426 static void optimize_attrs PARAMS ((void));
427 static void gen_attr PARAMS ((rtx, int));
428 static int count_alternatives PARAMS ((rtx));
429 static int compares_alternatives_p PARAMS ((rtx));
430 static int contained_in_p PARAMS ((rtx, rtx));
431 static void gen_insn PARAMS ((rtx, int));
432 static void gen_delay PARAMS ((rtx, int));
433 static void gen_unit PARAMS ((rtx, int));
434 static void write_test_expr PARAMS ((rtx, int));
435 static int max_attr_value PARAMS ((rtx, int*));
436 static int or_attr_value PARAMS ((rtx, int*));
437 static void walk_attr_value PARAMS ((rtx));
438 static void write_attr_get PARAMS ((struct attr_desc *));
439 static rtx eliminate_known_true PARAMS ((rtx, rtx, int, int));
440 static void write_attr_set PARAMS ((struct attr_desc *, int, rtx,
441 const char *, const char *, rtx,
442 int, int));
443 static void write_attr_case PARAMS ((struct attr_desc *, struct attr_value *,
444 int, const char *, const char *, int, rtx));
445 static void write_unit_name PARAMS ((const char *, int, const char *));
446 static void write_attr_valueq PARAMS ((struct attr_desc *, const char *));
447 static void write_attr_value PARAMS ((struct attr_desc *, rtx));
448 static void write_upcase PARAMS ((const char *));
449 static void write_indent PARAMS ((int));
450 static void write_eligible_delay PARAMS ((const char *));
451 static void write_function_unit_info PARAMS ((void));
452 static void write_complex_function PARAMS ((struct function_unit *, const char *,
453 const char *));
454 static int write_expr_attr_cache PARAMS ((rtx, struct attr_desc *));
455 static void write_toplevel_expr PARAMS ((rtx));
456 static void write_const_num_delay_slots PARAMS ((void));
457 static char *next_comma_elt PARAMS ((const char **));
458 static struct attr_desc *find_attr PARAMS ((const char *, int));
459 static struct attr_value *find_most_used PARAMS ((struct attr_desc *));
460 static rtx find_single_value PARAMS ((struct attr_desc *));
461 static void extend_range PARAMS ((struct range *, int, int));
462 static rtx attr_eq PARAMS ((const char *, const char *));
463 static const char *attr_numeral PARAMS ((int));
464 static int attr_equal_p PARAMS ((rtx, rtx));
465 static rtx attr_copy_rtx PARAMS ((rtx));
466 static int attr_rtx_cost PARAMS ((rtx));
468 #define oballoc(size) obstack_alloc (hash_obstack, size)
470 /* Hash table for sharing RTL and strings. */
472 /* Each hash table slot is a bucket containing a chain of these structures.
473 Strings are given negative hash codes; RTL expressions are given positive
474 hash codes. */
476 struct attr_hash
478 struct attr_hash *next; /* Next structure in the bucket. */
479 int hashcode; /* Hash code of this rtx or string. */
480 union
482 char *str; /* The string (negative hash codes) */
483 rtx rtl; /* or the RTL recorded here. */
484 } u;
487 /* Now here is the hash table. When recording an RTL, it is added to
488 the slot whose index is the hash code mod the table size. Note
489 that the hash table is used for several kinds of RTL (see attr_rtx)
490 and for strings. While all these live in the same table, they are
491 completely independent, and the hash code is computed differently
492 for each. */
494 #define RTL_HASH_SIZE 4093
495 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
497 /* Here is how primitive or already-shared RTL's hash
498 codes are made. */
499 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
501 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
503 static void
504 attr_hash_add_rtx (hashcode, rtl)
505 int hashcode;
506 rtx rtl;
508 struct attr_hash *h;
510 h = (struct attr_hash *) obstack_alloc (hash_obstack,
511 sizeof (struct attr_hash));
512 h->hashcode = hashcode;
513 h->u.rtl = rtl;
514 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
515 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
518 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
520 static void
521 attr_hash_add_string (hashcode, str)
522 int hashcode;
523 char *str;
525 struct attr_hash *h;
527 h = (struct attr_hash *) obstack_alloc (hash_obstack,
528 sizeof (struct attr_hash));
529 h->hashcode = -hashcode;
530 h->u.str = str;
531 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
532 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
535 /* Generate an RTL expression, but avoid duplicates.
536 Set the ATTR_PERMANENT_P flag for these permanent objects.
538 In some cases we cannot uniquify; then we return an ordinary
539 impermanent rtx with ATTR_PERMANENT_P clear.
541 Args are like gen_rtx, but without the mode:
543 rtx attr_rtx (code, [element1, ..., elementn]) */
545 static rtx
546 attr_rtx_1 (code, p)
547 enum rtx_code code;
548 va_list p;
550 rtx rt_val = NULL_RTX;/* RTX to return to caller... */
551 int hashcode;
552 struct attr_hash *h;
553 struct obstack *old_obstack = rtl_obstack;
555 /* For each of several cases, search the hash table for an existing entry.
556 Use that entry if one is found; otherwise create a new RTL and add it
557 to the table. */
559 if (GET_RTX_CLASS (code) == '1')
561 rtx arg0 = va_arg (p, rtx);
563 /* A permanent object cannot point to impermanent ones. */
564 if (! ATTR_PERMANENT_P (arg0))
566 rt_val = rtx_alloc (code);
567 XEXP (rt_val, 0) = arg0;
568 return rt_val;
571 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
572 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
573 if (h->hashcode == hashcode
574 && GET_CODE (h->u.rtl) == code
575 && XEXP (h->u.rtl, 0) == arg0)
576 return h->u.rtl;
578 if (h == 0)
580 rtl_obstack = hash_obstack;
581 rt_val = rtx_alloc (code);
582 XEXP (rt_val, 0) = arg0;
585 else if (GET_RTX_CLASS (code) == 'c'
586 || GET_RTX_CLASS (code) == '2'
587 || GET_RTX_CLASS (code) == '<')
589 rtx arg0 = va_arg (p, rtx);
590 rtx arg1 = va_arg (p, rtx);
592 /* A permanent object cannot point to impermanent ones. */
593 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1))
595 rt_val = rtx_alloc (code);
596 XEXP (rt_val, 0) = arg0;
597 XEXP (rt_val, 1) = arg1;
598 return rt_val;
601 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
602 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
603 if (h->hashcode == hashcode
604 && GET_CODE (h->u.rtl) == code
605 && XEXP (h->u.rtl, 0) == arg0
606 && XEXP (h->u.rtl, 1) == arg1)
607 return h->u.rtl;
609 if (h == 0)
611 rtl_obstack = hash_obstack;
612 rt_val = rtx_alloc (code);
613 XEXP (rt_val, 0) = arg0;
614 XEXP (rt_val, 1) = arg1;
617 else if (GET_RTX_LENGTH (code) == 1
618 && GET_RTX_FORMAT (code)[0] == 's')
620 char *arg0 = va_arg (p, char *);
622 if (code == SYMBOL_REF)
623 arg0 = attr_string (arg0, strlen (arg0));
625 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
626 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
627 if (h->hashcode == hashcode
628 && GET_CODE (h->u.rtl) == code
629 && XSTR (h->u.rtl, 0) == arg0)
630 return h->u.rtl;
632 if (h == 0)
634 rtl_obstack = hash_obstack;
635 rt_val = rtx_alloc (code);
636 XSTR (rt_val, 0) = arg0;
639 else if (GET_RTX_LENGTH (code) == 2
640 && GET_RTX_FORMAT (code)[0] == 's'
641 && GET_RTX_FORMAT (code)[1] == 's')
643 char *arg0 = va_arg (p, char *);
644 char *arg1 = va_arg (p, char *);
646 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
647 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
648 if (h->hashcode == hashcode
649 && GET_CODE (h->u.rtl) == code
650 && XSTR (h->u.rtl, 0) == arg0
651 && XSTR (h->u.rtl, 1) == arg1)
652 return h->u.rtl;
654 if (h == 0)
656 rtl_obstack = hash_obstack;
657 rt_val = rtx_alloc (code);
658 XSTR (rt_val, 0) = arg0;
659 XSTR (rt_val, 1) = arg1;
662 else if (code == CONST_INT)
664 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
665 if (arg0 == 0)
666 return false_rtx;
667 else if (arg0 == 1)
668 return true_rtx;
669 else
670 goto nohash;
672 else
674 int i; /* Array indices... */
675 const char *fmt; /* Current rtx's format... */
676 nohash:
677 rt_val = rtx_alloc (code); /* Allocate the storage space. */
679 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
680 for (i = 0; i < GET_RTX_LENGTH (code); i++)
682 switch (*fmt++)
684 case '0': /* Unused field. */
685 break;
687 case 'i': /* An integer? */
688 XINT (rt_val, i) = va_arg (p, int);
689 break;
691 case 'w': /* A wide integer? */
692 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
693 break;
695 case 's': /* A string? */
696 XSTR (rt_val, i) = va_arg (p, char *);
697 break;
699 case 'e': /* An expression? */
700 case 'u': /* An insn? Same except when printing. */
701 XEXP (rt_val, i) = va_arg (p, rtx);
702 break;
704 case 'E': /* An RTX vector? */
705 XVEC (rt_val, i) = va_arg (p, rtvec);
706 break;
708 default:
709 abort ();
712 return rt_val;
715 rtl_obstack = old_obstack;
716 attr_hash_add_rtx (hashcode, rt_val);
717 ATTR_PERMANENT_P (rt_val) = 1;
718 return rt_val;
721 static rtx
722 attr_rtx VPARAMS ((enum rtx_code code, ...))
724 rtx result;
726 VA_OPEN (p, code);
727 VA_FIXEDARG (p, enum rtx_code, code);
728 result = attr_rtx_1 (code, p);
729 VA_CLOSE (p);
730 return result;
733 /* Create a new string printed with the printf line arguments into a space
734 of at most LEN bytes:
736 rtx attr_printf (len, format, [arg1, ..., argn]) */
738 char *
739 attr_printf VPARAMS ((unsigned int len, const char *fmt, ...))
741 char str[256];
743 VA_OPEN (p, fmt);
744 VA_FIXEDARG (p, unsigned int, len);
745 VA_FIXEDARG (p, const char *, fmt);
747 if (len > sizeof str - 1) /* Leave room for \0. */
748 abort ();
750 vsprintf (str, fmt, p);
751 VA_CLOSE (p);
753 return attr_string (str, strlen (str));
756 static rtx
757 attr_eq (name, value)
758 const char *name, *value;
760 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
761 attr_string (value, strlen (value)));
764 static const char *
765 attr_numeral (n)
766 int n;
768 return XSTR (make_numeric_value (n), 0);
771 /* Return a permanent (possibly shared) copy of a string STR (not assumed
772 to be null terminated) with LEN bytes. */
774 static char *
775 attr_string (str, len)
776 const char *str;
777 int len;
779 struct attr_hash *h;
780 int hashcode;
781 int i;
782 char *new_str;
784 /* Compute the hash code. */
785 hashcode = (len + 1) * 613 + (unsigned) str[0];
786 for (i = 1; i <= len; i += 2)
787 hashcode = ((hashcode * 613) + (unsigned) str[i]);
788 if (hashcode < 0)
789 hashcode = -hashcode;
791 /* Search the table for the string. */
792 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
793 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
794 && !strncmp (h->u.str, str, len))
795 return h->u.str; /* <-- return if found. */
797 /* Not found; create a permanent copy and add it to the hash table. */
798 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
799 memcpy (new_str, str, len);
800 new_str[len] = '\0';
801 attr_hash_add_string (hashcode, new_str);
803 return new_str; /* Return the new string. */
806 /* Check two rtx's for equality of contents,
807 taking advantage of the fact that if both are hashed
808 then they can't be equal unless they are the same object. */
810 static int
811 attr_equal_p (x, y)
812 rtx x, y;
814 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y))
815 && rtx_equal_p (x, y)));
818 /* Copy an attribute value expression,
819 descending to all depths, but not copying any
820 permanent hashed subexpressions. */
822 static rtx
823 attr_copy_rtx (orig)
824 rtx orig;
826 rtx copy;
827 int i, j;
828 RTX_CODE code;
829 const char *format_ptr;
831 /* No need to copy a permanent object. */
832 if (ATTR_PERMANENT_P (orig))
833 return orig;
835 code = GET_CODE (orig);
837 switch (code)
839 case REG:
840 case QUEUED:
841 case CONST_INT:
842 case CONST_DOUBLE:
843 case CONST_VECTOR:
844 case SYMBOL_REF:
845 case CODE_LABEL:
846 case PC:
847 case CC0:
848 return orig;
850 default:
851 break;
854 copy = rtx_alloc (code);
855 PUT_MODE (copy, GET_MODE (orig));
856 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig);
857 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig);
858 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig);
859 ATTR_EQ_ATTR_P (copy) = ATTR_EQ_ATTR_P (orig);
861 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
863 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
865 switch (*format_ptr++)
867 case 'e':
868 XEXP (copy, i) = XEXP (orig, i);
869 if (XEXP (orig, i) != NULL)
870 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
871 break;
873 case 'E':
874 case 'V':
875 XVEC (copy, i) = XVEC (orig, i);
876 if (XVEC (orig, i) != NULL)
878 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
879 for (j = 0; j < XVECLEN (copy, i); j++)
880 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
882 break;
884 case 'n':
885 case 'i':
886 XINT (copy, i) = XINT (orig, i);
887 break;
889 case 'w':
890 XWINT (copy, i) = XWINT (orig, i);
891 break;
893 case 's':
894 case 'S':
895 XSTR (copy, i) = XSTR (orig, i);
896 break;
898 default:
899 abort ();
902 return copy;
905 /* Given a test expression for an attribute, ensure it is validly formed.
906 IS_CONST indicates whether the expression is constant for each compiler
907 run (a constant expression may not test any particular insn).
909 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
910 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
911 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
913 Update the string address in EQ_ATTR expression to be the same used
914 in the attribute (or `alternative_name') to speed up subsequent
915 `find_attr' calls and eliminate most `strcmp' calls.
917 Return the new expression, if any. */
920 check_attr_test (exp, is_const, lineno)
921 rtx exp;
922 int is_const;
923 int lineno;
925 struct attr_desc *attr;
926 struct attr_value *av;
927 const char *name_ptr, *p;
928 rtx orexp, newexp;
930 switch (GET_CODE (exp))
932 case EQ_ATTR:
933 /* Handle negation test. */
934 if (XSTR (exp, 1)[0] == '!')
935 return check_attr_test (attr_rtx (NOT,
936 attr_eq (XSTR (exp, 0),
937 &XSTR (exp, 1)[1])),
938 is_const, lineno);
940 else if (n_comma_elts (XSTR (exp, 1)) == 1)
942 attr = find_attr (XSTR (exp, 0), 0);
943 if (attr == NULL)
945 if (! strcmp (XSTR (exp, 0), "alternative"))
947 XSTR (exp, 0) = alternative_name;
948 /* This can't be simplified any further. */
949 ATTR_IND_SIMPLIFIED_P (exp) = 1;
950 return exp;
952 else
953 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0));
956 if (is_const && ! attr->is_const)
957 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
958 XSTR (exp, 0));
960 /* Copy this just to make it permanent,
961 so expressions using it can be permanent too. */
962 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
964 /* It shouldn't be possible to simplify the value given to a
965 constant attribute, so don't expand this until it's time to
966 write the test expression. */
967 if (attr->is_const)
968 ATTR_IND_SIMPLIFIED_P (exp) = 1;
970 if (attr->is_numeric)
972 for (p = XSTR (exp, 1); *p; p++)
973 if (! ISDIGIT (*p))
974 fatal ("attribute `%s' takes only numeric values",
975 XSTR (exp, 0));
977 else
979 for (av = attr->first_value; av; av = av->next)
980 if (GET_CODE (av->value) == CONST_STRING
981 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
982 break;
984 if (av == NULL)
985 fatal ("unknown value `%s' for `%s' attribute",
986 XSTR (exp, 1), XSTR (exp, 0));
989 else
991 /* Make an IOR tree of the possible values. */
992 orexp = false_rtx;
993 name_ptr = XSTR (exp, 1);
994 while ((p = next_comma_elt (&name_ptr)) != NULL)
996 newexp = attr_eq (XSTR (exp, 0), p);
997 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
1000 return check_attr_test (orexp, is_const, lineno);
1002 break;
1004 case ATTR_FLAG:
1005 break;
1007 case CONST_INT:
1008 /* Either TRUE or FALSE. */
1009 if (XWINT (exp, 0))
1010 return true_rtx;
1011 else
1012 return false_rtx;
1014 case IOR:
1015 case AND:
1016 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1017 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno);
1018 break;
1020 case NOT:
1021 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno);
1022 break;
1024 case MATCH_INSN:
1025 case MATCH_OPERAND:
1026 if (is_const)
1027 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1028 GET_RTX_NAME (GET_CODE (exp)));
1029 /* These cases can't be simplified. */
1030 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1031 break;
1033 case LE: case LT: case GT: case GE:
1034 case LEU: case LTU: case GTU: case GEU:
1035 case NE: case EQ:
1036 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1037 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1038 exp = attr_rtx (GET_CODE (exp),
1039 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1040 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
1041 /* These cases can't be simplified. */
1042 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1043 break;
1045 case SYMBOL_REF:
1046 if (is_const)
1048 /* These cases are valid for constant attributes, but can't be
1049 simplified. */
1050 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1051 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1052 break;
1054 default:
1055 fatal ("RTL operator \"%s\" not valid in attribute test",
1056 GET_RTX_NAME (GET_CODE (exp)));
1059 return exp;
1062 /* Given an expression, ensure that it is validly formed and that all named
1063 attribute values are valid for the given attribute. Issue a fatal error
1064 if not. If no attribute is specified, assume a numeric attribute.
1066 Return a perhaps modified replacement expression for the value. */
1068 static rtx
1069 check_attr_value (exp, attr)
1070 rtx exp;
1071 struct attr_desc *attr;
1073 struct attr_value *av;
1074 const char *p;
1075 int i;
1077 switch (GET_CODE (exp))
1079 case CONST_INT:
1080 if (attr && ! attr->is_numeric)
1082 message_with_line (attr->lineno,
1083 "CONST_INT not valid for non-numeric attribute %s",
1084 attr->name);
1085 have_error = 1;
1086 break;
1089 if (INTVAL (exp) < 0 && ! attr->negative_ok)
1091 message_with_line (attr->lineno,
1092 "negative numeric value specified for attribute %s",
1093 attr->name);
1094 have_error = 1;
1095 break;
1097 break;
1099 case CONST_STRING:
1100 if (! strcmp (XSTR (exp, 0), "*"))
1101 break;
1103 if (attr == 0 || attr->is_numeric)
1105 p = XSTR (exp, 0);
1106 if (attr && attr->negative_ok && *p == '-')
1107 p++;
1108 for (; *p; p++)
1109 if (! ISDIGIT (*p))
1111 message_with_line (attr ? attr->lineno : 0,
1112 "non-numeric value for numeric attribute %s",
1113 attr ? attr->name : "internal");
1114 have_error = 1;
1115 break;
1117 break;
1120 for (av = attr->first_value; av; av = av->next)
1121 if (GET_CODE (av->value) == CONST_STRING
1122 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1123 break;
1125 if (av == NULL)
1127 message_with_line (attr->lineno,
1128 "unknown value `%s' for `%s' attribute",
1129 XSTR (exp, 0), attr ? attr->name : "internal");
1130 have_error = 1;
1132 break;
1134 case IF_THEN_ELSE:
1135 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1136 attr ? attr->is_const : 0,
1137 attr ? attr->lineno : 0);
1138 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1139 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1140 break;
1142 case PLUS:
1143 case MINUS:
1144 case MULT:
1145 case DIV:
1146 case MOD:
1147 if (attr && !attr->is_numeric)
1149 message_with_line (attr->lineno,
1150 "invalid operation `%s' for non-numeric attribute value",
1151 GET_RTX_NAME (GET_CODE (exp)));
1152 have_error = 1;
1153 break;
1155 /* FALLTHRU */
1157 case IOR:
1158 case AND:
1159 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1160 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1161 break;
1163 case FFS:
1164 case CLZ:
1165 case CTZ:
1166 case POPCOUNT:
1167 case PARITY:
1168 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr);
1169 break;
1171 case COND:
1172 if (XVECLEN (exp, 0) % 2 != 0)
1174 message_with_line (attr->lineno,
1175 "first operand of COND must have even length");
1176 have_error = 1;
1177 break;
1180 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1182 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1183 attr ? attr->is_const : 0,
1184 attr ? attr->lineno : 0);
1185 XVECEXP (exp, 0, i + 1)
1186 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1189 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1190 break;
1192 case ATTR:
1194 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0);
1195 if (attr2 == NULL)
1197 message_with_line (attr ? attr->lineno : 0,
1198 "unknown attribute `%s' in ATTR",
1199 XSTR (exp, 0));
1200 have_error = 1;
1202 else if (attr && attr->is_const && ! attr2->is_const)
1204 message_with_line (attr->lineno,
1205 "non-constant attribute `%s' referenced from `%s'",
1206 XSTR (exp, 0), attr->name);
1207 have_error = 1;
1209 else if (attr
1210 && (attr->is_numeric != attr2->is_numeric
1211 || (! attr->negative_ok && attr2->negative_ok)))
1213 message_with_line (attr->lineno,
1214 "numeric attribute mismatch calling `%s' from `%s'",
1215 XSTR (exp, 0), attr->name);
1216 have_error = 1;
1219 break;
1221 case SYMBOL_REF:
1222 /* A constant SYMBOL_REF is valid as a constant attribute test and
1223 is expanded later by make_canonical into a COND. In a non-constant
1224 attribute test, it is left be. */
1225 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1227 default:
1228 message_with_line (attr ? attr->lineno : 0,
1229 "invalid operation `%s' for attribute value",
1230 GET_RTX_NAME (GET_CODE (exp)));
1231 have_error = 1;
1232 break;
1235 return exp;
1238 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1239 It becomes a COND with each test being (eq_attr "alternative "n") */
1241 static rtx
1242 convert_set_attr_alternative (exp, id)
1243 rtx exp;
1244 struct insn_def *id;
1246 int num_alt = id->num_alternatives;
1247 rtx condexp;
1248 int i;
1250 if (XVECLEN (exp, 1) != num_alt)
1252 message_with_line (id->lineno,
1253 "bad number of entries in SET_ATTR_ALTERNATIVE");
1254 have_error = 1;
1255 return NULL_RTX;
1258 /* Make a COND with all tests but the last. Select the last value via the
1259 default. */
1260 condexp = rtx_alloc (COND);
1261 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1263 for (i = 0; i < num_alt - 1; i++)
1265 const char *p;
1266 p = attr_numeral (i);
1268 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1269 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1272 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1274 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1277 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1278 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1280 static rtx
1281 convert_set_attr (exp, id)
1282 rtx exp;
1283 struct insn_def *id;
1285 rtx newexp;
1286 const char *name_ptr;
1287 char *p;
1288 int n;
1290 /* See how many alternative specified. */
1291 n = n_comma_elts (XSTR (exp, 1));
1292 if (n == 1)
1293 return attr_rtx (SET,
1294 attr_rtx (ATTR, XSTR (exp, 0)),
1295 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1297 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1298 XSTR (newexp, 0) = XSTR (exp, 0);
1299 XVEC (newexp, 1) = rtvec_alloc (n);
1301 /* Process each comma-separated name. */
1302 name_ptr = XSTR (exp, 1);
1303 n = 0;
1304 while ((p = next_comma_elt (&name_ptr)) != NULL)
1305 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1307 return convert_set_attr_alternative (newexp, id);
1310 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1311 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1312 expressions. */
1314 static void
1315 check_defs ()
1317 struct insn_def *id;
1318 struct attr_desc *attr;
1319 int i;
1320 rtx value;
1322 for (id = defs; id; id = id->next)
1324 if (XVEC (id->def, id->vec_idx) == NULL)
1325 continue;
1327 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1329 value = XVECEXP (id->def, id->vec_idx, i);
1330 switch (GET_CODE (value))
1332 case SET:
1333 if (GET_CODE (XEXP (value, 0)) != ATTR)
1335 message_with_line (id->lineno, "bad attribute set");
1336 have_error = 1;
1337 value = NULL_RTX;
1339 break;
1341 case SET_ATTR_ALTERNATIVE:
1342 value = convert_set_attr_alternative (value, id);
1343 break;
1345 case SET_ATTR:
1346 value = convert_set_attr (value, id);
1347 break;
1349 default:
1350 message_with_line (id->lineno, "invalid attribute code %s",
1351 GET_RTX_NAME (GET_CODE (value)));
1352 have_error = 1;
1353 value = NULL_RTX;
1355 if (value == NULL_RTX)
1356 continue;
1358 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1360 message_with_line (id->lineno, "unknown attribute %s",
1361 XSTR (XEXP (value, 0), 0));
1362 have_error = 1;
1363 continue;
1366 XVECEXP (id->def, id->vec_idx, i) = value;
1367 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1372 #if 0
1373 /* Given a constant SYMBOL_REF expression, convert to a COND that
1374 explicitly tests each enumerated value. */
1376 static rtx
1377 convert_const_symbol_ref (exp, attr)
1378 rtx exp;
1379 struct attr_desc *attr;
1381 rtx condexp;
1382 struct attr_value *av;
1383 int i;
1384 int num_alt = 0;
1386 for (av = attr->first_value; av; av = av->next)
1387 num_alt++;
1389 /* Make a COND with all tests but the last, and in the original order.
1390 Select the last value via the default. Note that the attr values
1391 are constructed in reverse order. */
1393 condexp = rtx_alloc (COND);
1394 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1395 av = attr->first_value;
1396 XEXP (condexp, 1) = av->value;
1398 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1400 char *p, *string;
1401 rtx value;
1403 string = p = (char *) oballoc (2
1404 + strlen (attr->name)
1405 + strlen (XSTR (av->value, 0)));
1406 strcpy (p, attr->name);
1407 strcat (p, "_");
1408 strcat (p, XSTR (av->value, 0));
1409 for (; *p != '\0'; p++)
1410 *p = TOUPPER (*p);
1412 value = attr_rtx (SYMBOL_REF, string);
1413 ATTR_IND_SIMPLIFIED_P (value) = 1;
1415 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1417 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1420 return condexp;
1422 #endif
1424 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1425 expressions by converting them into a COND. This removes cases from this
1426 program. Also, replace an attribute value of "*" with the default attribute
1427 value. */
1429 static rtx
1430 make_canonical (attr, exp)
1431 struct attr_desc *attr;
1432 rtx exp;
1434 int i;
1435 rtx newexp;
1437 switch (GET_CODE (exp))
1439 case CONST_INT:
1440 exp = make_numeric_value (INTVAL (exp));
1441 break;
1443 case CONST_STRING:
1444 if (! strcmp (XSTR (exp, 0), "*"))
1446 if (attr == 0 || attr->default_val == 0)
1447 fatal ("(attr_value \"*\") used in invalid context");
1448 exp = attr->default_val->value;
1451 break;
1453 case SYMBOL_REF:
1454 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp))
1455 break;
1456 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1457 This makes the COND something that won't be considered an arbitrary
1458 expression by walk_attr_value. */
1459 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1460 #if 0
1461 /* ??? Why do we do this? With attribute values { A B C D E }, this
1462 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather
1463 than (x==E). */
1464 exp = convert_const_symbol_ref (exp, attr);
1465 ATTR_IND_SIMPLIFIED_P (exp) = 1;
1466 exp = check_attr_value (exp, attr);
1467 /* Goto COND case since this is now a COND. Note that while the
1468 new expression is rescanned, all symbol_ref notes are marked as
1469 unchanging. */
1470 goto cond;
1471 #else
1472 exp = check_attr_value (exp, attr);
1473 break;
1474 #endif
1476 case IF_THEN_ELSE:
1477 newexp = rtx_alloc (COND);
1478 XVEC (newexp, 0) = rtvec_alloc (2);
1479 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1480 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1482 XEXP (newexp, 1) = XEXP (exp, 2);
1484 exp = newexp;
1485 /* Fall through to COND case since this is now a COND. */
1487 case COND:
1489 int allsame = 1;
1490 rtx defval;
1492 /* First, check for degenerate COND. */
1493 if (XVECLEN (exp, 0) == 0)
1494 return make_canonical (attr, XEXP (exp, 1));
1495 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1497 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1499 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1500 XVECEXP (exp, 0, i + 1)
1501 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1502 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1503 allsame = 0;
1505 if (allsame)
1506 return defval;
1508 break;
1510 default:
1511 break;
1514 return exp;
1517 static rtx
1518 copy_boolean (exp)
1519 rtx exp;
1521 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1522 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1523 copy_boolean (XEXP (exp, 1)));
1524 return exp;
1527 /* Given a value and an attribute description, return a `struct attr_value *'
1528 that represents that value. This is either an existing structure, if the
1529 value has been previously encountered, or a newly-created structure.
1531 `insn_code' is the code of an insn whose attribute has the specified
1532 value (-2 if not processing an insn). We ensure that all insns for
1533 a given value have the same number of alternatives if the value checks
1534 alternatives. */
1536 static struct attr_value *
1537 get_attr_value (value, attr, insn_code)
1538 rtx value;
1539 struct attr_desc *attr;
1540 int insn_code;
1542 struct attr_value *av;
1543 int num_alt = 0;
1545 value = make_canonical (attr, value);
1546 if (compares_alternatives_p (value))
1548 if (insn_code < 0 || insn_alternatives == NULL)
1549 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1550 else
1551 num_alt = insn_alternatives[insn_code];
1554 for (av = attr->first_value; av; av = av->next)
1555 if (rtx_equal_p (value, av->value)
1556 && (num_alt == 0 || av->first_insn == NULL
1557 || insn_alternatives[av->first_insn->insn_code]))
1558 return av;
1560 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1561 av->value = value;
1562 av->next = attr->first_value;
1563 attr->first_value = av;
1564 av->first_insn = NULL;
1565 av->num_insns = 0;
1566 av->has_asm_insn = 0;
1568 return av;
1571 /* After all DEFINE_DELAYs have been read in, create internal attributes
1572 to generate the required routines.
1574 First, we compute the number of delay slots for each insn (as a COND of
1575 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1576 delay type is specified, we compute a similar function giving the
1577 DEFINE_DELAY ordinal for each insn.
1579 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1580 tells whether a given insn can be in that delay slot.
1582 Normal attribute filling and optimization expands these to contain the
1583 information needed to handle delay slots. */
1585 static void
1586 expand_delays ()
1588 struct delay_desc *delay;
1589 rtx condexp;
1590 rtx newexp;
1591 int i;
1592 char *p;
1594 /* First, generate data for `num_delay_slots' function. */
1596 condexp = rtx_alloc (COND);
1597 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1598 XEXP (condexp, 1) = make_numeric_value (0);
1600 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1602 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1603 XVECEXP (condexp, 0, i + 1)
1604 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1607 make_internal_attr ("*num_delay_slots", condexp, 0);
1609 /* If more than one delay type, do the same for computing the delay type. */
1610 if (num_delays > 1)
1612 condexp = rtx_alloc (COND);
1613 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1614 XEXP (condexp, 1) = make_numeric_value (0);
1616 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1618 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1619 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1622 make_internal_attr ("*delay_type", condexp, 1);
1625 /* For each delay possibility and delay slot, compute an eligibility
1626 attribute for non-annulled insns and for each type of annulled (annul
1627 if true and annul if false). */
1628 for (delay = delays; delay; delay = delay->next)
1630 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1632 condexp = XVECEXP (delay->def, 1, i);
1633 if (condexp == 0)
1634 condexp = false_rtx;
1635 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1636 make_numeric_value (1), make_numeric_value (0));
1638 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2,
1639 "*delay_%d_%d", delay->num, i / 3);
1640 make_internal_attr (p, newexp, 1);
1642 if (have_annul_true)
1644 condexp = XVECEXP (delay->def, 1, i + 1);
1645 if (condexp == 0) condexp = false_rtx;
1646 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1647 make_numeric_value (1),
1648 make_numeric_value (0));
1649 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2,
1650 "*annul_true_%d_%d", delay->num, i / 3);
1651 make_internal_attr (p, newexp, 1);
1654 if (have_annul_false)
1656 condexp = XVECEXP (delay->def, 1, i + 2);
1657 if (condexp == 0) condexp = false_rtx;
1658 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1659 make_numeric_value (1),
1660 make_numeric_value (0));
1661 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2,
1662 "*annul_false_%d_%d", delay->num, i / 3);
1663 make_internal_attr (p, newexp, 1);
1669 /* This function is given a left and right side expression and an operator.
1670 Each side is a conditional expression, each alternative of which has a
1671 numerical value. The function returns another conditional expression
1672 which, for every possible set of condition values, returns a value that is
1673 the operator applied to the values of the two sides.
1675 Since this is called early, it must also support IF_THEN_ELSE. */
1677 static rtx
1678 operate_exp (op, left, right)
1679 enum operator op;
1680 rtx left, right;
1682 int left_value, right_value;
1683 rtx newexp;
1684 int i;
1686 /* If left is a string, apply operator to it and the right side. */
1687 if (GET_CODE (left) == CONST_STRING)
1689 /* If right is also a string, just perform the operation. */
1690 if (GET_CODE (right) == CONST_STRING)
1692 left_value = atoi (XSTR (left, 0));
1693 right_value = atoi (XSTR (right, 0));
1694 switch (op)
1696 case PLUS_OP:
1697 i = left_value + right_value;
1698 break;
1700 case MINUS_OP:
1701 i = left_value - right_value;
1702 break;
1704 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1705 if (left_value > right_value)
1706 i = left_value - right_value;
1707 else
1708 i = 0;
1709 break;
1711 case OR_OP:
1712 case ORX_OP:
1713 i = left_value | right_value;
1714 break;
1716 case EQ_OP:
1717 i = left_value == right_value;
1718 break;
1720 case RANGE_OP:
1721 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1722 break;
1724 case MAX_OP:
1725 if (left_value > right_value)
1726 i = left_value;
1727 else
1728 i = right_value;
1729 break;
1731 case MIN_OP:
1732 if (left_value < right_value)
1733 i = left_value;
1734 else
1735 i = right_value;
1736 break;
1738 default:
1739 abort ();
1742 if (i == left_value)
1743 return left;
1744 if (i == right_value)
1745 return right;
1746 return make_numeric_value (i);
1748 else if (GET_CODE (right) == IF_THEN_ELSE)
1750 /* Apply recursively to all values within. */
1751 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1752 rtx newright = operate_exp (op, left, XEXP (right, 2));
1753 if (rtx_equal_p (newleft, newright))
1754 return newleft;
1755 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1757 else if (GET_CODE (right) == COND)
1759 int allsame = 1;
1760 rtx defval;
1762 newexp = rtx_alloc (COND);
1763 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1764 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1766 for (i = 0; i < XVECLEN (right, 0); i += 2)
1768 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1769 XVECEXP (newexp, 0, i + 1)
1770 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1771 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1772 defval))
1773 allsame = 0;
1776 /* If the resulting cond is trivial (all alternatives
1777 give the same value), optimize it away. */
1778 if (allsame)
1779 return operate_exp (op, left, XEXP (right, 1));
1781 return newexp;
1783 else
1784 fatal ("badly formed attribute value");
1787 /* A hack to prevent expand_units from completely blowing up: ORX_OP does
1788 not associate through IF_THEN_ELSE. */
1789 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE)
1791 return attr_rtx (IOR, left, right);
1794 /* Otherwise, do recursion the other way. */
1795 else if (GET_CODE (left) == IF_THEN_ELSE)
1797 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1798 rtx newright = operate_exp (op, XEXP (left, 2), right);
1799 if (rtx_equal_p (newleft, newright))
1800 return newleft;
1801 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1803 else if (GET_CODE (left) == COND)
1805 int allsame = 1;
1806 rtx defval;
1808 newexp = rtx_alloc (COND);
1809 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1810 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1812 for (i = 0; i < XVECLEN (left, 0); i += 2)
1814 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1815 XVECEXP (newexp, 0, i + 1)
1816 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1817 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1818 defval))
1819 allsame = 0;
1822 /* If the cond is trivial (all alternatives give the same value),
1823 optimize it away. */
1824 if (allsame)
1825 return operate_exp (op, XEXP (left, 1), right);
1827 /* If the result is the same as the LEFT operand,
1828 just use that. */
1829 if (rtx_equal_p (newexp, left))
1830 return left;
1832 return newexp;
1835 else
1836 fatal ("badly formed attribute value");
1837 /* NOTREACHED */
1838 return NULL;
1841 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1842 construct a number of attributes.
1844 The first produces a function `function_units_used' which is given an
1845 insn and produces an encoding showing which function units are required
1846 for the execution of that insn. If the value is non-negative, the insn
1847 uses that unit; otherwise, the value is a one's complement mask of units
1848 used.
1850 The second produces a function `result_ready_cost' which is used to
1851 determine the time that the result of an insn will be ready and hence
1852 a worst-case schedule.
1854 Both of these produce quite complex expressions which are then set as the
1855 default value of internal attributes. Normal attribute simplification
1856 should produce reasonable expressions.
1858 For each unit, a `<name>_unit_ready_cost' function will take an
1859 insn and give the delay until that unit will be ready with the result
1860 and a `<name>_unit_conflict_cost' function is given an insn already
1861 executing on the unit and a candidate to execute and will give the
1862 cost from the time the executing insn started until the candidate
1863 can start (ignore limitations on the number of simultaneous insns).
1865 For each unit, a `<name>_unit_blockage' function is given an insn
1866 already executing on the unit and a candidate to execute and will
1867 give the delay incurred due to function unit conflicts. The range of
1868 blockage cost values for a given executing insn is given by the
1869 `<name>_unit_blockage_range' function. These values are encoded in
1870 an int where the upper half gives the minimum value and the lower
1871 half gives the maximum value. */
1873 static void
1874 expand_units ()
1876 struct function_unit *unit, **unit_num;
1877 struct function_unit_op *op, **op_array, ***unit_ops;
1878 rtx unitsmask;
1879 rtx readycost;
1880 rtx newexp;
1881 const char *str;
1882 int i, j, u, num, nvalues;
1884 /* Rebuild the condition for the unit to share the RTL expressions.
1885 Sharing is required by simplify_by_exploding. Build the issue delay
1886 expressions. Validate the expressions we were given for the conditions
1887 and conflict vector. Then make attributes for use in the conflict
1888 function. */
1890 for (unit = units; unit; unit = unit->next)
1892 unit->condexp = check_attr_test (unit->condexp, 0, unit->first_lineno);
1894 for (op = unit->ops; op; op = op->next)
1896 rtx issue_delay = make_numeric_value (op->issue_delay);
1897 rtx issue_exp = issue_delay;
1899 /* Build, validate, and simplify the issue delay expression. */
1900 if (op->conflict_exp != true_rtx)
1901 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1902 issue_exp, make_numeric_value (0));
1903 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1904 issue_exp),
1905 NULL_ATTR);
1906 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1907 op->issue_exp = issue_exp;
1909 /* Make an attribute for use in the conflict function if needed. */
1910 unit->needs_conflict_function = (unit->issue_delay.min
1911 != unit->issue_delay.max);
1912 if (unit->needs_conflict_function)
1914 str = attr_printf ((strlen (unit->name) + sizeof "*_cost_"
1915 + MAX_DIGITS),
1916 "*%s_cost_%d", unit->name, op->num);
1917 make_internal_attr (str, issue_exp, 1);
1920 /* Validate the condition. */
1921 op->condexp = check_attr_test (op->condexp, 0, op->lineno);
1925 /* Compute the mask of function units used. Initially, the unitsmask is
1926 zero. Set up a conditional to compute each unit's contribution. */
1927 unitsmask = make_numeric_value (0);
1928 newexp = rtx_alloc (IF_THEN_ELSE);
1929 XEXP (newexp, 2) = make_numeric_value (0);
1931 /* If we have just a few units, we may be all right expanding the whole
1932 thing. But the expansion is 2**N in space on the number of opclasses,
1933 so we can't do this for very long -- Alpha and MIPS in particular have
1934 problems with this. So in that situation, we fall back on an alternate
1935 implementation method. */
1936 #define NUM_UNITOP_CUTOFF 20
1938 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1940 /* Merge each function unit into the unit mask attributes. */
1941 for (unit = units; unit; unit = unit->next)
1943 XEXP (newexp, 0) = unit->condexp;
1944 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1945 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1948 else
1950 /* Merge each function unit into the unit mask attributes. */
1951 for (unit = units; unit; unit = unit->next)
1953 XEXP (newexp, 0) = unit->condexp;
1954 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1955 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp));
1959 /* Simplify the unit mask expression, encode it, and make an attribute
1960 for the function_units_used function. */
1961 unitsmask = simplify_by_exploding (unitsmask);
1963 if (num_unit_opclasses < NUM_UNITOP_CUTOFF)
1964 unitsmask = encode_units_mask (unitsmask);
1965 else
1967 /* We can no longer encode unitsmask at compile time, so emit code to
1968 calculate it at runtime. Rather, put a marker for where we'd do
1969 the code, and actually output it in write_attr_get(). */
1970 unitsmask = attr_rtx (FFS, unitsmask);
1973 make_internal_attr ("*function_units_used", unitsmask, 10);
1975 /* Create an array of ops for each unit. Add an extra unit for the
1976 result_ready_cost function that has the ops of all other units. */
1977 unit_ops = (struct function_unit_op ***)
1978 xmalloc ((num_units + 1) * sizeof (struct function_unit_op **));
1979 unit_num = (struct function_unit **)
1980 xmalloc ((num_units + 1) * sizeof (struct function_unit *));
1982 unit_num[num_units] = unit = (struct function_unit *)
1983 xmalloc (sizeof (struct function_unit));
1984 unit->num = num_units;
1985 unit->num_opclasses = 0;
1987 for (unit = units; unit; unit = unit->next)
1989 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1990 unit_num[unit->num] = unit;
1991 unit_ops[unit->num] = op_array = (struct function_unit_op **)
1992 xmalloc (unit->num_opclasses * sizeof (struct function_unit_op *));
1994 for (op = unit->ops; op; op = op->next)
1995 op_array[op->num] = op;
1998 /* Compose the array of ops for the extra unit. */
1999 unit_ops[num_units] = op_array = (struct function_unit_op **)
2000 xmalloc (unit_num[num_units]->num_opclasses
2001 * sizeof (struct function_unit_op *));
2003 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
2004 memcpy (&op_array[i], unit_ops[unit->num],
2005 unit->num_opclasses * sizeof (struct function_unit_op *));
2007 /* Compute the ready cost function for each unit by computing the
2008 condition for each non-default value. */
2009 for (u = 0; u <= num_units; u++)
2011 rtx orexp;
2012 int value;
2014 unit = unit_num[u];
2015 op_array = unit_ops[unit->num];
2016 num = unit->num_opclasses;
2018 /* Sort the array of ops into increasing ready cost order. */
2019 for (i = 0; i < num; i++)
2020 for (j = num - 1; j > i; j--)
2021 if (op_array[j - 1]->ready < op_array[j]->ready)
2023 op = op_array[j];
2024 op_array[j] = op_array[j - 1];
2025 op_array[j - 1] = op;
2028 /* Determine how many distinct non-default ready cost values there
2029 are. We use a default ready cost value of 1. */
2030 nvalues = 0; value = 1;
2031 for (i = num - 1; i >= 0; i--)
2032 if (op_array[i]->ready > value)
2034 value = op_array[i]->ready;
2035 nvalues++;
2038 if (nvalues == 0)
2039 readycost = make_numeric_value (1);
2040 else
2042 /* Construct the ready cost expression as a COND of each value from
2043 the largest to the smallest. */
2044 readycost = rtx_alloc (COND);
2045 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
2046 XEXP (readycost, 1) = make_numeric_value (1);
2048 nvalues = 0;
2049 orexp = false_rtx;
2050 value = op_array[0]->ready;
2051 for (i = 0; i < num; i++)
2053 op = op_array[i];
2054 if (op->ready <= 1)
2055 break;
2056 else if (op->ready == value)
2057 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
2058 else
2060 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2061 XVECEXP (readycost, 0, nvalues * 2 + 1)
2062 = make_numeric_value (value);
2063 nvalues++;
2064 value = op->ready;
2065 orexp = op->condexp;
2068 XVECEXP (readycost, 0, nvalues * 2) = orexp;
2069 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
2072 if (u < num_units)
2074 rtx max_blockage = 0, min_blockage = 0;
2076 /* Simplify the readycost expression by only considering insns
2077 that use the unit. */
2078 readycost = simplify_knowing (readycost, unit->condexp);
2080 /* Determine the blockage cost the executing insn (E) given
2081 the candidate insn (C). This is the maximum of the issue
2082 delay, the pipeline delay, and the simultaneity constraint.
2083 Each function_unit_op represents the characteristics of the
2084 candidate insn, so in the expressions below, C is a known
2085 term and E is an unknown term.
2087 We compute the blockage cost for each E for every possible C.
2088 Thus OP represents E, and READYCOST is a list of values for
2089 every possible C.
2091 The issue delay function for C is op->issue_exp and is used to
2092 write the `<name>_unit_conflict_cost' function. Symbolically
2093 this is "ISSUE-DELAY (E,C)".
2095 The pipeline delay results form the FIFO constraint on the
2096 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
2098 The simultaneity constraint is based on how long it takes to
2099 fill the unit given the minimum issue delay. FILL-TIME is the
2100 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
2101 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2102 if SIMULTANEITY is nonzero and zero otherwise.
2104 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2106 MAX (ISSUE-DELAY (E,C),
2107 READY-COST (E) - (READY-COST (C) - 1))
2109 and otherwise
2111 MAX (ISSUE-DELAY (E,C),
2112 READY-COST (E) - (READY-COST (C) - 1),
2113 READY-COST (E) - FILL-TIME)
2115 The `<name>_unit_blockage' function is computed by determining
2116 this value for each candidate insn. As these values are
2117 computed, we also compute the upper and lower bounds for
2118 BLOCKAGE (E,*). These are combined to form the function
2119 `<name>_unit_blockage_range'. Finally, the maximum blockage
2120 cost, MAX (BLOCKAGE (*,*)), is computed. */
2122 for (op = unit->ops; op; op = op->next)
2124 rtx blockage = op->issue_exp;
2125 blockage = simplify_knowing (blockage, unit->condexp);
2127 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2128 MIN (BLOCKAGE (E,*)). */
2129 if (max_blockage == 0)
2130 max_blockage = min_blockage = blockage;
2131 else
2133 max_blockage
2134 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2135 blockage),
2136 unit->condexp);
2137 min_blockage
2138 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2139 blockage),
2140 unit->condexp);
2143 /* Make an attribute for use in the blockage function. */
2144 str = attr_printf ((strlen (unit->name) + sizeof "*_block_"
2145 + MAX_DIGITS),
2146 "*%s_block_%d", unit->name, op->num);
2147 make_internal_attr (str, blockage, 1);
2150 /* Record MAX (BLOCKAGE (*,*)). */
2152 int unknown;
2153 unit->max_blockage = max_attr_value (max_blockage, &unknown);
2156 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2157 same. If so, the blockage function carries no additional
2158 information and is not written. */
2159 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2160 newexp = simplify_knowing (newexp, unit->condexp);
2161 unit->needs_blockage_function
2162 = (GET_CODE (newexp) != CONST_STRING
2163 || atoi (XSTR (newexp, 0)) != 1);
2165 /* If the all values of BLOCKAGE (E,C) have the same value,
2166 neither blockage function is written. */
2167 unit->needs_range_function
2168 = (unit->needs_blockage_function
2169 || GET_CODE (max_blockage) != CONST_STRING);
2171 if (unit->needs_range_function)
2173 /* Compute the blockage range function and make an attribute
2174 for writing its value. */
2175 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2176 newexp = simplify_knowing (newexp, unit->condexp);
2178 str = attr_printf ((strlen (unit->name)
2179 + sizeof "*_unit_blockage_range"),
2180 "*%s_unit_blockage_range", unit->name);
2181 make_internal_attr (str, newexp, 20);
2184 str = attr_printf (strlen (unit->name) + sizeof "*_unit_ready_cost",
2185 "*%s_unit_ready_cost", unit->name);
2187 else
2188 str = "*result_ready_cost";
2190 /* Make an attribute for the ready_cost function. Simplifying
2191 further with simplify_by_exploding doesn't win. */
2192 make_internal_attr (str, readycost, 0);
2195 /* For each unit that requires a conflict cost function, make an attribute
2196 that maps insns to the operation number. */
2197 for (unit = units; unit; unit = unit->next)
2199 rtx caseexp;
2201 if (! unit->needs_conflict_function
2202 && ! unit->needs_blockage_function)
2203 continue;
2205 caseexp = rtx_alloc (COND);
2206 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2208 for (op = unit->ops; op; op = op->next)
2210 /* Make our adjustment to the COND being computed. If we are the
2211 last operation class, place our values into the default of the
2212 COND. */
2213 if (op->num == unit->num_opclasses - 1)
2215 XEXP (caseexp, 1) = make_numeric_value (op->num);
2217 else
2219 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2220 XVECEXP (caseexp, 0, op->num * 2 + 1)
2221 = make_numeric_value (op->num);
2225 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2226 str = attr_printf (strlen (unit->name) + sizeof "*_cases",
2227 "*%s_cases", unit->name);
2228 make_internal_attr (str, caseexp, 1);
2232 /* Simplify EXP given KNOWN_TRUE. */
2234 static rtx
2235 simplify_knowing (exp, known_true)
2236 rtx exp, known_true;
2238 if (GET_CODE (exp) != CONST_STRING)
2240 int unknown = 0, max;
2241 max = max_attr_value (exp, &unknown);
2242 if (! unknown)
2244 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2245 make_numeric_value (max));
2246 exp = simplify_by_exploding (exp);
2249 return exp;
2252 /* Translate the CONST_STRING expressions in X to change the encoding of
2253 value. On input, the value is a bitmask with a one bit for each unit
2254 used; on output, the value is the unit number (zero based) if one
2255 and only one unit is used or the one's complement of the bitmask. */
2257 static rtx
2258 encode_units_mask (x)
2259 rtx x;
2261 int i;
2262 int j;
2263 enum rtx_code code;
2264 const char *fmt;
2266 code = GET_CODE (x);
2268 switch (code)
2270 case CONST_STRING:
2271 i = atoi (XSTR (x, 0));
2272 if (i < 0)
2273 /* The sign bit encodes a one's complement mask. */
2274 abort ();
2275 else if (i != 0 && i == (i & -i))
2276 /* Only one bit is set, so yield that unit number. */
2277 for (j = 0; (i >>= 1) != 0; j++)
2279 else
2280 j = ~i;
2281 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2283 case REG:
2284 case QUEUED:
2285 case CONST_INT:
2286 case CONST_DOUBLE:
2287 case CONST_VECTOR:
2288 case SYMBOL_REF:
2289 case CODE_LABEL:
2290 case PC:
2291 case CC0:
2292 case EQ_ATTR:
2293 return x;
2295 default:
2296 break;
2299 /* Compare the elements. If any pair of corresponding elements
2300 fail to match, return 0 for the whole things. */
2302 fmt = GET_RTX_FORMAT (code);
2303 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2305 switch (fmt[i])
2307 case 'V':
2308 case 'E':
2309 for (j = 0; j < XVECLEN (x, i); j++)
2310 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2311 break;
2313 case 'e':
2314 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2315 break;
2318 return x;
2321 /* Once all attributes and insns have been read and checked, we construct for
2322 each attribute value a list of all the insns that have that value for
2323 the attribute. */
2325 static void
2326 fill_attr (attr)
2327 struct attr_desc *attr;
2329 struct attr_value *av;
2330 struct insn_ent *ie;
2331 struct insn_def *id;
2332 int i;
2333 rtx value;
2335 /* Don't fill constant attributes. The value is independent of
2336 any particular insn. */
2337 if (attr->is_const)
2338 return;
2340 for (id = defs; id; id = id->next)
2342 /* If no value is specified for this insn for this attribute, use the
2343 default. */
2344 value = NULL;
2345 if (XVEC (id->def, id->vec_idx))
2346 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2347 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2348 attr->name))
2349 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2351 if (value == NULL)
2352 av = attr->default_val;
2353 else
2354 av = get_attr_value (value, attr, id->insn_code);
2356 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2357 ie->insn_code = id->insn_code;
2358 ie->insn_index = id->insn_code;
2359 insert_insn_ent (av, ie);
2363 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2364 test that checks relative positions of insns (uses MATCH_DUP or PC).
2365 If so, replace it with what is obtained by passing the expression to
2366 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2367 recursively on each value (including the default value). Otherwise,
2368 return the value returned by NO_ADDRESS_FN applied to EXP. */
2370 static rtx
2371 substitute_address (exp, no_address_fn, address_fn)
2372 rtx exp;
2373 rtx (*no_address_fn) PARAMS ((rtx));
2374 rtx (*address_fn) PARAMS ((rtx));
2376 int i;
2377 rtx newexp;
2379 if (GET_CODE (exp) == COND)
2381 /* See if any tests use addresses. */
2382 address_used = 0;
2383 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2384 walk_attr_value (XVECEXP (exp, 0, i));
2386 if (address_used)
2387 return (*address_fn) (exp);
2389 /* Make a new copy of this COND, replacing each element. */
2390 newexp = rtx_alloc (COND);
2391 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2392 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2394 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2395 XVECEXP (newexp, 0, i + 1)
2396 = substitute_address (XVECEXP (exp, 0, i + 1),
2397 no_address_fn, address_fn);
2400 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2401 no_address_fn, address_fn);
2403 return newexp;
2406 else if (GET_CODE (exp) == IF_THEN_ELSE)
2408 address_used = 0;
2409 walk_attr_value (XEXP (exp, 0));
2410 if (address_used)
2411 return (*address_fn) (exp);
2413 return attr_rtx (IF_THEN_ELSE,
2414 substitute_address (XEXP (exp, 0),
2415 no_address_fn, address_fn),
2416 substitute_address (XEXP (exp, 1),
2417 no_address_fn, address_fn),
2418 substitute_address (XEXP (exp, 2),
2419 no_address_fn, address_fn));
2422 return (*no_address_fn) (exp);
2425 /* Make new attributes from the `length' attribute. The following are made,
2426 each corresponding to a function called from `shorten_branches' or
2427 `get_attr_length':
2429 *insn_default_length This is the length of the insn to be returned
2430 by `get_attr_length' before `shorten_branches'
2431 has been called. In each case where the length
2432 depends on relative addresses, the largest
2433 possible is used. This routine is also used
2434 to compute the initial size of the insn.
2436 *insn_variable_length_p This returns 1 if the insn's length depends
2437 on relative addresses, zero otherwise.
2439 *insn_current_length This is only called when it is known that the
2440 insn has a variable length and returns the
2441 current length, based on relative addresses.
2444 static void
2445 make_length_attrs ()
2447 static const char *const new_names[] = {"*insn_default_length",
2448 "*insn_variable_length_p",
2449 "*insn_current_length"};
2450 static rtx (*const no_address_fn[]) PARAMS ((rtx)) = {identity_fn, zero_fn, zero_fn};
2451 static rtx (*const address_fn[]) PARAMS ((rtx)) = {max_fn, one_fn, identity_fn};
2452 size_t i;
2453 struct attr_desc *length_attr, *new_attr;
2454 struct attr_value *av, *new_av;
2455 struct insn_ent *ie, *new_ie;
2457 /* See if length attribute is defined. If so, it must be numeric. Make
2458 it special so we don't output anything for it. */
2459 length_attr = find_attr ("length", 0);
2460 if (length_attr == 0)
2461 return;
2463 if (! length_attr->is_numeric)
2464 fatal ("length attribute must be numeric");
2466 length_attr->is_const = 0;
2467 length_attr->is_special = 1;
2469 /* Make each new attribute, in turn. */
2470 for (i = 0; i < ARRAY_SIZE (new_names); i++)
2472 make_internal_attr (new_names[i],
2473 substitute_address (length_attr->default_val->value,
2474 no_address_fn[i], address_fn[i]),
2476 new_attr = find_attr (new_names[i], 0);
2477 for (av = length_attr->first_value; av; av = av->next)
2478 for (ie = av->first_insn; ie; ie = ie->next)
2480 new_av = get_attr_value (substitute_address (av->value,
2481 no_address_fn[i],
2482 address_fn[i]),
2483 new_attr, ie->insn_code);
2484 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2485 new_ie->insn_code = ie->insn_code;
2486 new_ie->insn_index = ie->insn_index;
2487 insert_insn_ent (new_av, new_ie);
2492 /* Utility functions called from above routine. */
2494 static rtx
2495 identity_fn (exp)
2496 rtx exp;
2498 return exp;
2501 static rtx
2502 zero_fn (exp)
2503 rtx exp ATTRIBUTE_UNUSED;
2505 return make_numeric_value (0);
2508 static rtx
2509 one_fn (exp)
2510 rtx exp ATTRIBUTE_UNUSED;
2512 return make_numeric_value (1);
2515 static rtx
2516 max_fn (exp)
2517 rtx exp;
2519 int unknown;
2520 return make_numeric_value (max_attr_value (exp, &unknown));
2523 static void
2524 write_length_unit_log ()
2526 struct attr_desc *length_attr = find_attr ("length", 0);
2527 struct attr_value *av;
2528 struct insn_ent *ie;
2529 unsigned int length_unit_log, length_or;
2530 int unknown = 0;
2532 if (length_attr == 0)
2533 return;
2534 length_or = or_attr_value (length_attr->default_val->value, &unknown);
2535 for (av = length_attr->first_value; av; av = av->next)
2536 for (ie = av->first_insn; ie; ie = ie->next)
2537 length_or |= or_attr_value (av->value, &unknown);
2539 if (unknown)
2540 length_unit_log = 0;
2541 else
2543 length_or = ~length_or;
2544 for (length_unit_log = 0; length_or & 1; length_or >>= 1)
2545 length_unit_log++;
2547 printf ("int length_unit_log = %u;\n", length_unit_log);
2550 /* Take a COND expression and see if any of the conditions in it can be
2551 simplified. If any are known true or known false for the particular insn
2552 code, the COND can be further simplified.
2554 Also call ourselves on any COND operations that are values of this COND.
2556 We do not modify EXP; rather, we make and return a new rtx. */
2558 static rtx
2559 simplify_cond (exp, insn_code, insn_index)
2560 rtx exp;
2561 int insn_code, insn_index;
2563 int i, j;
2564 /* We store the desired contents here,
2565 then build a new expression if they don't match EXP. */
2566 rtx defval = XEXP (exp, 1);
2567 rtx new_defval = XEXP (exp, 1);
2568 int len = XVECLEN (exp, 0);
2569 rtx *tests = (rtx *) xmalloc (len * sizeof (rtx));
2570 int allsame = 1;
2571 rtx ret;
2573 /* This lets us free all storage allocated below, if appropriate. */
2574 obstack_finish (rtl_obstack);
2576 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx));
2578 /* See if default value needs simplification. */
2579 if (GET_CODE (defval) == COND)
2580 new_defval = simplify_cond (defval, insn_code, insn_index);
2582 /* Simplify the subexpressions, and see what tests we can get rid of. */
2584 for (i = 0; i < len; i += 2)
2586 rtx newtest, newval;
2588 /* Simplify this test. */
2589 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index);
2590 tests[i] = newtest;
2592 newval = tests[i + 1];
2593 /* See if this value may need simplification. */
2594 if (GET_CODE (newval) == COND)
2595 newval = simplify_cond (newval, insn_code, insn_index);
2597 /* Look for ways to delete or combine this test. */
2598 if (newtest == true_rtx)
2600 /* If test is true, make this value the default
2601 and discard this + any following tests. */
2602 len = i;
2603 defval = tests[i + 1];
2604 new_defval = newval;
2607 else if (newtest == false_rtx)
2609 /* If test is false, discard it and its value. */
2610 for (j = i; j < len - 2; j++)
2611 tests[j] = tests[j + 2];
2612 len -= 2;
2615 else if (i > 0 && attr_equal_p (newval, tests[i - 1]))
2617 /* If this value and the value for the prev test are the same,
2618 merge the tests. */
2620 tests[i - 2]
2621 = insert_right_side (IOR, tests[i - 2], newtest,
2622 insn_code, insn_index);
2624 /* Delete this test/value. */
2625 for (j = i; j < len - 2; j++)
2626 tests[j] = tests[j + 2];
2627 len -= 2;
2630 else
2631 tests[i + 1] = newval;
2634 /* If the last test in a COND has the same value
2635 as the default value, that test isn't needed. */
2637 while (len > 0 && attr_equal_p (tests[len - 1], new_defval))
2638 len -= 2;
2640 /* See if we changed anything. */
2641 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2642 allsame = 0;
2643 else
2644 for (i = 0; i < len; i++)
2645 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i)))
2647 allsame = 0;
2648 break;
2651 if (len == 0)
2653 if (GET_CODE (defval) == COND)
2654 ret = simplify_cond (defval, insn_code, insn_index);
2655 else
2656 ret = defval;
2658 else if (allsame)
2659 ret = exp;
2660 else
2662 rtx newexp = rtx_alloc (COND);
2664 XVEC (newexp, 0) = rtvec_alloc (len);
2665 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx));
2666 XEXP (newexp, 1) = new_defval;
2667 ret = newexp;
2669 free (tests);
2670 return ret;
2673 /* Remove an insn entry from an attribute value. */
2675 static void
2676 remove_insn_ent (av, ie)
2677 struct attr_value *av;
2678 struct insn_ent *ie;
2680 struct insn_ent *previe;
2682 if (av->first_insn == ie)
2683 av->first_insn = ie->next;
2684 else
2686 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2688 previe->next = ie->next;
2691 av->num_insns--;
2692 if (ie->insn_code == -1)
2693 av->has_asm_insn = 0;
2695 num_insn_ents--;
2698 /* Insert an insn entry in an attribute value list. */
2700 static void
2701 insert_insn_ent (av, ie)
2702 struct attr_value *av;
2703 struct insn_ent *ie;
2705 ie->next = av->first_insn;
2706 av->first_insn = ie;
2707 av->num_insns++;
2708 if (ie->insn_code == -1)
2709 av->has_asm_insn = 1;
2711 num_insn_ents++;
2714 /* This is a utility routine to take an expression that is a tree of either
2715 AND or IOR expressions and insert a new term. The new term will be
2716 inserted at the right side of the first node whose code does not match
2717 the root. A new node will be created with the root's code. Its left
2718 side will be the old right side and its right side will be the new
2719 term.
2721 If the `term' is itself a tree, all its leaves will be inserted. */
2723 static rtx
2724 insert_right_side (code, exp, term, insn_code, insn_index)
2725 enum rtx_code code;
2726 rtx exp;
2727 rtx term;
2728 int insn_code, insn_index;
2730 rtx newexp;
2732 /* Avoid consing in some special cases. */
2733 if (code == AND && term == true_rtx)
2734 return exp;
2735 if (code == AND && term == false_rtx)
2736 return false_rtx;
2737 if (code == AND && exp == true_rtx)
2738 return term;
2739 if (code == AND && exp == false_rtx)
2740 return false_rtx;
2741 if (code == IOR && term == true_rtx)
2742 return true_rtx;
2743 if (code == IOR && term == false_rtx)
2744 return exp;
2745 if (code == IOR && exp == true_rtx)
2746 return true_rtx;
2747 if (code == IOR && exp == false_rtx)
2748 return term;
2749 if (attr_equal_p (exp, term))
2750 return exp;
2752 if (GET_CODE (term) == code)
2754 exp = insert_right_side (code, exp, XEXP (term, 0),
2755 insn_code, insn_index);
2756 exp = insert_right_side (code, exp, XEXP (term, 1),
2757 insn_code, insn_index);
2759 return exp;
2762 if (GET_CODE (exp) == code)
2764 rtx new = insert_right_side (code, XEXP (exp, 1),
2765 term, insn_code, insn_index);
2766 if (new != XEXP (exp, 1))
2767 /* Make a copy of this expression and call recursively. */
2768 newexp = attr_rtx (code, XEXP (exp, 0), new);
2769 else
2770 newexp = exp;
2772 else
2774 /* Insert the new term. */
2775 newexp = attr_rtx (code, exp, term);
2778 return simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2781 /* If we have an expression which AND's a bunch of
2782 (not (eq_attrq "alternative" "n"))
2783 terms, we may have covered all or all but one of the possible alternatives.
2784 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2786 This routine is passed an expression and either AND or IOR. It returns a
2787 bitmask indicating which alternatives are mentioned within EXP. */
2789 static int
2790 compute_alternative_mask (exp, code)
2791 rtx exp;
2792 enum rtx_code code;
2794 const char *string;
2795 if (GET_CODE (exp) == code)
2796 return compute_alternative_mask (XEXP (exp, 0), code)
2797 | compute_alternative_mask (XEXP (exp, 1), code);
2799 else if (code == AND && GET_CODE (exp) == NOT
2800 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2801 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2802 string = XSTR (XEXP (exp, 0), 1);
2804 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2805 && XSTR (exp, 0) == alternative_name)
2806 string = XSTR (exp, 1);
2808 else
2809 return 0;
2811 if (string[1] == 0)
2812 return 1 << (string[0] - '0');
2813 return 1 << atoi (string);
2816 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2817 attribute with the value represented by that bit. */
2819 static rtx
2820 make_alternative_compare (mask)
2821 int mask;
2823 rtx newexp;
2824 int i;
2826 /* Find the bit. */
2827 for (i = 0; (mask & (1 << i)) == 0; i++)
2830 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2831 ATTR_IND_SIMPLIFIED_P (newexp) = 1;
2833 return newexp;
2836 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2837 of "attr" for this insn code. From that value, we can compute a test
2838 showing when the EQ_ATTR will be true. This routine performs that
2839 computation. If a test condition involves an address, we leave the EQ_ATTR
2840 intact because addresses are only valid for the `length' attribute.
2842 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2843 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2845 static rtx
2846 evaluate_eq_attr (exp, value, insn_code, insn_index)
2847 rtx exp;
2848 rtx value;
2849 int insn_code, insn_index;
2851 rtx orexp, andexp;
2852 rtx right;
2853 rtx newexp;
2854 int i;
2856 if (GET_CODE (value) == CONST_STRING)
2858 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2859 newexp = true_rtx;
2860 else
2861 newexp = false_rtx;
2863 else if (GET_CODE (value) == SYMBOL_REF)
2865 char *p;
2866 char string[256];
2868 if (GET_CODE (exp) != EQ_ATTR)
2869 abort ();
2871 if (strlen (XSTR (exp, 0)) + strlen (XSTR (exp, 1)) + 2 > 256)
2872 abort ();
2874 strcpy (string, XSTR (exp, 0));
2875 strcat (string, "_");
2876 strcat (string, XSTR (exp, 1));
2877 for (p = string; *p; p++)
2878 *p = TOUPPER (*p);
2880 newexp = attr_rtx (EQ, value,
2881 attr_rtx (SYMBOL_REF,
2882 attr_string (string, strlen (string))));
2884 else if (GET_CODE (value) == COND)
2886 /* We construct an IOR of all the cases for which the requested attribute
2887 value is present. Since we start with FALSE, if it is not present,
2888 FALSE will be returned.
2890 Each case is the AND of the NOT's of the previous conditions with the
2891 current condition; in the default case the current condition is TRUE.
2893 For each possible COND value, call ourselves recursively.
2895 The extra TRUE and FALSE expressions will be eliminated by another
2896 call to the simplification routine. */
2898 orexp = false_rtx;
2899 andexp = true_rtx;
2901 if (current_alternative_string)
2902 clear_struct_flag (value);
2904 for (i = 0; i < XVECLEN (value, 0); i += 2)
2906 rtx this = simplify_test_exp_in_temp (XVECEXP (value, 0, i),
2907 insn_code, insn_index);
2909 SIMPLIFY_ALTERNATIVE (this);
2911 right = insert_right_side (AND, andexp, this,
2912 insn_code, insn_index);
2913 right = insert_right_side (AND, right,
2914 evaluate_eq_attr (exp,
2915 XVECEXP (value, 0,
2916 i + 1),
2917 insn_code, insn_index),
2918 insn_code, insn_index);
2919 orexp = insert_right_side (IOR, orexp, right,
2920 insn_code, insn_index);
2922 /* Add this condition into the AND expression. */
2923 newexp = attr_rtx (NOT, this);
2924 andexp = insert_right_side (AND, andexp, newexp,
2925 insn_code, insn_index);
2928 /* Handle the default case. */
2929 right = insert_right_side (AND, andexp,
2930 evaluate_eq_attr (exp, XEXP (value, 1),
2931 insn_code, insn_index),
2932 insn_code, insn_index);
2933 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2935 else
2936 abort ();
2938 /* If uses an address, must return original expression. But set the
2939 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2941 address_used = 0;
2942 walk_attr_value (newexp);
2944 if (address_used)
2946 /* This had `&& current_alternative_string', which seems to be wrong. */
2947 if (! ATTR_IND_SIMPLIFIED_P (exp))
2948 return copy_rtx_unchanging (exp);
2949 return exp;
2951 else
2952 return newexp;
2955 /* This routine is called when an AND of a term with a tree of AND's is
2956 encountered. If the term or its complement is present in the tree, it
2957 can be replaced with TRUE or FALSE, respectively.
2959 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2960 be true and hence are complementary.
2962 There is one special case: If we see
2963 (and (not (eq_attr "att" "v1"))
2964 (eq_attr "att" "v2"))
2965 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2966 replace the term, not anything in the AND tree. So we pass a pointer to
2967 the term. */
2969 static rtx
2970 simplify_and_tree (exp, pterm, insn_code, insn_index)
2971 rtx exp;
2972 rtx *pterm;
2973 int insn_code, insn_index;
2975 rtx left, right;
2976 rtx newexp;
2977 rtx temp;
2978 int left_eliminates_term, right_eliminates_term;
2980 if (GET_CODE (exp) == AND)
2982 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2983 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2984 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2986 newexp = attr_rtx (GET_CODE (exp), left, right);
2988 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
2992 else if (GET_CODE (exp) == IOR)
2994 /* For the IOR case, we do the same as above, except that we can
2995 only eliminate `term' if both sides of the IOR would do so. */
2996 temp = *pterm;
2997 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2998 left_eliminates_term = (temp == true_rtx);
3000 temp = *pterm;
3001 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3002 right_eliminates_term = (temp == true_rtx);
3004 if (left_eliminates_term && right_eliminates_term)
3005 *pterm = true_rtx;
3007 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3009 newexp = attr_rtx (GET_CODE (exp), left, right);
3011 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3015 /* Check for simplifications. Do some extra checking here since this
3016 routine is called so many times. */
3018 if (exp == *pterm)
3019 return true_rtx;
3021 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
3022 return false_rtx;
3024 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
3025 return false_rtx;
3027 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
3029 if (XSTR (exp, 0) != XSTR (*pterm, 0))
3030 return exp;
3032 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
3033 return true_rtx;
3034 else
3035 return false_rtx;
3038 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3039 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
3041 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
3042 return exp;
3044 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
3045 return false_rtx;
3046 else
3047 return true_rtx;
3050 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3051 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
3053 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
3054 return exp;
3056 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
3057 return false_rtx;
3058 else
3059 *pterm = true_rtx;
3062 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
3064 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
3065 return true_rtx;
3068 else if (GET_CODE (exp) == NOT)
3070 if (attr_equal_p (XEXP (exp, 0), *pterm))
3071 return false_rtx;
3074 else if (GET_CODE (*pterm) == NOT)
3076 if (attr_equal_p (XEXP (*pterm, 0), exp))
3077 return false_rtx;
3080 else if (attr_equal_p (exp, *pterm))
3081 return true_rtx;
3083 return exp;
3086 /* Similar to `simplify_and_tree', but for IOR trees. */
3088 static rtx
3089 simplify_or_tree (exp, pterm, insn_code, insn_index)
3090 rtx exp;
3091 rtx *pterm;
3092 int insn_code, insn_index;
3094 rtx left, right;
3095 rtx newexp;
3096 rtx temp;
3097 int left_eliminates_term, right_eliminates_term;
3099 if (GET_CODE (exp) == IOR)
3101 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
3102 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
3103 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3105 newexp = attr_rtx (GET_CODE (exp), left, right);
3107 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3111 else if (GET_CODE (exp) == AND)
3113 /* For the AND case, we do the same as above, except that we can
3114 only eliminate `term' if both sides of the AND would do so. */
3115 temp = *pterm;
3116 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
3117 left_eliminates_term = (temp == false_rtx);
3119 temp = *pterm;
3120 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
3121 right_eliminates_term = (temp == false_rtx);
3123 if (left_eliminates_term && right_eliminates_term)
3124 *pterm = false_rtx;
3126 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3128 newexp = attr_rtx (GET_CODE (exp), left, right);
3130 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index);
3134 if (attr_equal_p (exp, *pterm))
3135 return false_rtx;
3137 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
3138 return true_rtx;
3140 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
3141 return true_rtx;
3143 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
3144 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
3145 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
3146 *pterm = false_rtx;
3148 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3149 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3150 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3151 return false_rtx;
3153 return exp;
3155 /* Compute approximate cost of the expression. Used to decide whether
3156 expression is cheap enough for inline. */
3157 static int
3158 attr_rtx_cost (x)
3159 rtx x;
3161 int cost = 0;
3162 enum rtx_code code;
3163 if (!x)
3164 return 0;
3165 code = GET_CODE (x);
3166 switch (code)
3168 case MATCH_OPERAND:
3169 if (XSTR (x, 1)[0])
3170 return 10;
3171 else
3172 return 0;
3173 case EQ_ATTR:
3174 /* Alternatives don't result into function call. */
3175 if (!strcmp (XSTR (x, 0), "alternative"))
3176 return 0;
3177 else
3178 return 5;
3179 default:
3181 int i, j;
3182 const char *fmt = GET_RTX_FORMAT (code);
3183 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3185 switch (fmt[i])
3187 case 'V':
3188 case 'E':
3189 for (j = 0; j < XVECLEN (x, i); j++)
3190 cost += attr_rtx_cost (XVECEXP (x, i, j));
3191 break;
3192 case 'e':
3193 cost += attr_rtx_cost (XEXP (x, i));
3194 break;
3198 break;
3200 return cost;
3204 /* Simplify test expression and use temporary obstack in order to avoid
3205 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
3206 and avoid unnecessary copying if possible. */
3208 static rtx
3209 simplify_test_exp_in_temp (exp, insn_code, insn_index)
3210 rtx exp;
3211 int insn_code, insn_index;
3213 rtx x;
3214 struct obstack *old;
3215 if (ATTR_IND_SIMPLIFIED_P (exp))
3216 return exp;
3217 old = rtl_obstack;
3218 rtl_obstack = temp_obstack;
3219 x = simplify_test_exp (exp, insn_code, insn_index);
3220 rtl_obstack = old;
3221 if (x == exp || rtl_obstack == temp_obstack)
3222 return x;
3223 return attr_copy_rtx (x);
3226 /* Given an expression, see if it can be simplified for a particular insn
3227 code based on the values of other attributes being tested. This can
3228 eliminate nested get_attr_... calls.
3230 Note that if an endless recursion is specified in the patterns, the
3231 optimization will loop. However, it will do so in precisely the cases where
3232 an infinite recursion loop could occur during compilation. It's better that
3233 it occurs here! */
3235 static rtx
3236 simplify_test_exp (exp, insn_code, insn_index)
3237 rtx exp;
3238 int insn_code, insn_index;
3240 rtx left, right;
3241 struct attr_desc *attr;
3242 struct attr_value *av;
3243 struct insn_ent *ie;
3244 int i;
3245 rtx newexp = exp;
3247 /* Don't re-simplify something we already simplified. */
3248 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp))
3249 return exp;
3251 switch (GET_CODE (exp))
3253 case AND:
3254 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3255 SIMPLIFY_ALTERNATIVE (left);
3256 if (left == false_rtx)
3257 return false_rtx;
3258 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3259 SIMPLIFY_ALTERNATIVE (right);
3260 if (left == false_rtx)
3261 return false_rtx;
3263 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3264 present on both sides, apply the distributive law since this will
3265 yield simplifications. */
3266 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3267 && compute_alternative_mask (left, IOR)
3268 && compute_alternative_mask (right, IOR))
3270 if (GET_CODE (left) == IOR)
3272 rtx tem = left;
3273 left = right;
3274 right = tem;
3277 newexp = attr_rtx (IOR,
3278 attr_rtx (AND, left, XEXP (right, 0)),
3279 attr_rtx (AND, left, XEXP (right, 1)));
3281 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3284 /* Try with the term on both sides. */
3285 right = simplify_and_tree (right, &left, insn_code, insn_index);
3286 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3287 left = simplify_and_tree (left, &right, insn_code, insn_index);
3289 if (left == false_rtx || right == false_rtx)
3290 return false_rtx;
3291 else if (left == true_rtx)
3293 return right;
3295 else if (right == true_rtx)
3297 return left;
3299 /* See if all or all but one of the insn's alternatives are specified
3300 in this tree. Optimize if so. */
3302 else if (insn_code >= 0
3303 && (GET_CODE (left) == AND
3304 || (GET_CODE (left) == NOT
3305 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3306 && XSTR (XEXP (left, 0), 0) == alternative_name)
3307 || GET_CODE (right) == AND
3308 || (GET_CODE (right) == NOT
3309 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3310 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3312 i = compute_alternative_mask (exp, AND);
3313 if (i & ~insn_alternatives[insn_code])
3314 fatal ("invalid alternative specified for pattern number %d",
3315 insn_index);
3317 /* If all alternatives are excluded, this is false. */
3318 i ^= insn_alternatives[insn_code];
3319 if (i == 0)
3320 return false_rtx;
3321 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3323 /* If just one excluded, AND a comparison with that one to the
3324 front of the tree. The others will be eliminated by
3325 optimization. We do not want to do this if the insn has one
3326 alternative and we have tested none of them! */
3327 left = make_alternative_compare (i);
3328 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3329 newexp = attr_rtx (AND, left, right);
3331 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3335 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3337 newexp = attr_rtx (AND, left, right);
3338 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3340 break;
3342 case IOR:
3343 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3344 SIMPLIFY_ALTERNATIVE (left);
3345 if (left == true_rtx)
3346 return true_rtx;
3347 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3348 SIMPLIFY_ALTERNATIVE (right);
3349 if (right == true_rtx)
3350 return true_rtx;
3352 right = simplify_or_tree (right, &left, insn_code, insn_index);
3353 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3354 left = simplify_or_tree (left, &right, insn_code, insn_index);
3356 if (right == true_rtx || left == true_rtx)
3357 return true_rtx;
3358 else if (left == false_rtx)
3360 return right;
3362 else if (right == false_rtx)
3364 return left;
3367 /* Test for simple cases where the distributive law is useful. I.e.,
3368 convert (ior (and (x) (y))
3369 (and (x) (z)))
3370 to (and (x)
3371 (ior (y) (z)))
3374 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3375 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3377 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3379 left = XEXP (left, 0);
3380 right = newexp;
3381 newexp = attr_rtx (AND, left, right);
3382 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3385 /* See if all or all but one of the insn's alternatives are specified
3386 in this tree. Optimize if so. */
3388 else if (insn_code >= 0
3389 && (GET_CODE (left) == IOR
3390 || (GET_CODE (left) == EQ_ATTR
3391 && XSTR (left, 0) == alternative_name)
3392 || GET_CODE (right) == IOR
3393 || (GET_CODE (right) == EQ_ATTR
3394 && XSTR (right, 0) == alternative_name)))
3396 i = compute_alternative_mask (exp, IOR);
3397 if (i & ~insn_alternatives[insn_code])
3398 fatal ("invalid alternative specified for pattern number %d",
3399 insn_index);
3401 /* If all alternatives are included, this is true. */
3402 i ^= insn_alternatives[insn_code];
3403 if (i == 0)
3404 return true_rtx;
3405 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3407 /* If just one excluded, IOR a comparison with that one to the
3408 front of the tree. The others will be eliminated by
3409 optimization. We do not want to do this if the insn has one
3410 alternative and we have tested none of them! */
3411 left = make_alternative_compare (i);
3412 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3413 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3415 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3419 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3421 newexp = attr_rtx (IOR, left, right);
3422 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3424 break;
3426 case NOT:
3427 if (GET_CODE (XEXP (exp, 0)) == NOT)
3429 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3430 insn_code, insn_index);
3431 SIMPLIFY_ALTERNATIVE (left);
3432 return left;
3435 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3436 SIMPLIFY_ALTERNATIVE (left);
3437 if (GET_CODE (left) == NOT)
3438 return XEXP (left, 0);
3440 if (left == false_rtx)
3441 return true_rtx;
3442 else if (left == true_rtx)
3443 return false_rtx;
3445 /* Try to apply De`Morgan's laws. */
3446 else if (GET_CODE (left) == IOR)
3448 newexp = attr_rtx (AND,
3449 attr_rtx (NOT, XEXP (left, 0)),
3450 attr_rtx (NOT, XEXP (left, 1)));
3452 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3454 else if (GET_CODE (left) == AND)
3456 newexp = attr_rtx (IOR,
3457 attr_rtx (NOT, XEXP (left, 0)),
3458 attr_rtx (NOT, XEXP (left, 1)));
3460 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3462 else if (left != XEXP (exp, 0))
3464 newexp = attr_rtx (NOT, left);
3466 break;
3468 case EQ_ATTR:
3469 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3470 return (XSTR (exp, 1) == current_alternative_string
3471 ? true_rtx : false_rtx);
3473 /* Look at the value for this insn code in the specified attribute.
3474 We normally can replace this comparison with the condition that
3475 would give this insn the values being tested for. */
3476 if (XSTR (exp, 0) != alternative_name
3477 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3478 for (av = attr->first_value; av; av = av->next)
3479 for (ie = av->first_insn; ie; ie = ie->next)
3480 if (ie->insn_code == insn_code)
3482 rtx x;
3483 x = evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3484 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index);
3485 if (attr_rtx_cost(x) < 20)
3486 return x;
3488 break;
3490 default:
3491 break;
3494 /* We have already simplified this expression. Simplifying it again
3495 won't buy anything unless we weren't given a valid insn code
3496 to process (i.e., we are canonicalizing something.). */
3497 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3498 && ! ATTR_IND_SIMPLIFIED_P (newexp))
3499 return copy_rtx_unchanging (newexp);
3501 return newexp;
3504 /* Optimize the attribute lists by seeing if we can determine conditional
3505 values from the known values of other attributes. This will save subroutine
3506 calls during the compilation. */
3508 static void
3509 optimize_attrs ()
3511 struct attr_desc *attr;
3512 struct attr_value *av;
3513 struct insn_ent *ie;
3514 rtx newexp;
3515 int i;
3516 struct attr_value_list
3518 struct attr_value *av;
3519 struct insn_ent *ie;
3520 struct attr_desc *attr;
3521 struct attr_value_list *next;
3523 struct attr_value_list **insn_code_values;
3524 struct attr_value_list *ivbuf;
3525 struct attr_value_list *iv;
3527 /* For each insn code, make a list of all the insn_ent's for it,
3528 for all values for all attributes. */
3530 if (num_insn_ents == 0)
3531 return;
3533 /* Make 2 extra elements, for "code" values -2 and -1. */
3534 insn_code_values
3535 = (struct attr_value_list **) xmalloc ((insn_code_number + 2)
3536 * sizeof (struct attr_value_list *));
3537 memset ((char *) insn_code_values, 0,
3538 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3540 /* Offset the table address so we can index by -2 or -1. */
3541 insn_code_values += 2;
3543 iv = ivbuf = ((struct attr_value_list *)
3544 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3546 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3547 for (attr = attrs[i]; attr; attr = attr->next)
3548 for (av = attr->first_value; av; av = av->next)
3549 for (ie = av->first_insn; ie; ie = ie->next)
3551 iv->attr = attr;
3552 iv->av = av;
3553 iv->ie = ie;
3554 iv->next = insn_code_values[ie->insn_code];
3555 insn_code_values[ie->insn_code] = iv;
3556 iv++;
3559 /* Sanity check on num_insn_ents. */
3560 if (iv != ivbuf + num_insn_ents)
3561 abort ();
3563 /* Process one insn code at a time. */
3564 for (i = -2; i < insn_code_number; i++)
3566 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3567 We use it to mean "already simplified for this insn". */
3568 for (iv = insn_code_values[i]; iv; iv = iv->next)
3569 clear_struct_flag (iv->av->value);
3571 for (iv = insn_code_values[i]; iv; iv = iv->next)
3573 struct obstack *old = rtl_obstack;
3575 attr = iv->attr;
3576 av = iv->av;
3577 ie = iv->ie;
3578 if (GET_CODE (av->value) != COND)
3579 continue;
3581 rtl_obstack = temp_obstack;
3582 #if 0 /* This was intended as a speed up, but it was slower. */
3583 if (insn_n_alternatives[ie->insn_code] > 6
3584 && count_sub_rtxs (av->value, 200) >= 200)
3585 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3586 ie->insn_index);
3587 else
3588 #endif
3589 newexp = av->value;
3590 while (GET_CODE (newexp) == COND)
3592 rtx newexp2 = simplify_cond (newexp, ie->insn_code,
3593 ie->insn_index);
3594 if (newexp2 == newexp)
3595 break;
3596 newexp = newexp2;
3599 rtl_obstack = old;
3600 if (newexp != av->value)
3602 newexp = attr_copy_rtx (newexp);
3603 remove_insn_ent (av, ie);
3604 av = get_attr_value (newexp, attr, ie->insn_code);
3605 iv->av = av;
3606 insert_insn_ent (av, ie);
3611 free (ivbuf);
3612 free (insn_code_values - 2);
3615 #if 0
3616 static rtx
3617 simplify_by_alternatives (exp, insn_code, insn_index)
3618 rtx exp;
3619 int insn_code, insn_index;
3621 int i;
3622 int len = insn_n_alternatives[insn_code];
3623 rtx newexp = rtx_alloc (COND);
3624 rtx ultimate;
3626 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3628 /* It will not matter what value we use as the default value
3629 of the new COND, since that default will never be used.
3630 Choose something of the right type. */
3631 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3632 ultimate = XEXP (ultimate, 1);
3633 XEXP (newexp, 1) = ultimate;
3635 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3637 current_alternative_string = attr_numeral (i);
3638 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3639 XVECEXP (newexp, 0, i * 2 + 1)
3640 = simplify_cond (exp, insn_code, insn_index);
3643 current_alternative_string = 0;
3644 return simplify_cond (newexp, insn_code, insn_index);
3646 #endif
3648 /* If EXP is a suitable expression, reorganize it by constructing an
3649 equivalent expression that is a COND with the tests being all combinations
3650 of attribute values and the values being simple constants. */
3652 static rtx
3653 simplify_by_exploding (exp)
3654 rtx exp;
3656 rtx list = 0, link, condexp, defval = NULL_RTX;
3657 struct dimension *space;
3658 rtx *condtest, *condval;
3659 int i, j, total, ndim = 0;
3660 int most_tests, num_marks, new_marks;
3661 rtx ret;
3663 /* Locate all the EQ_ATTR expressions. */
3664 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3666 unmark_used_attributes (list, 0, 0);
3667 return exp;
3670 /* Create an attribute space from the list of used attributes. For each
3671 dimension in the attribute space, record the attribute, list of values
3672 used, and number of values used. Add members to the list of values to
3673 cover the domain of the attribute. This makes the expanded COND form
3674 order independent. */
3676 space = (struct dimension *) xmalloc (ndim * sizeof (struct dimension));
3678 total = 1;
3679 for (ndim = 0; list; ndim++)
3681 /* Pull the first attribute value from the list and record that
3682 attribute as another dimension in the attribute space. */
3683 const char *name = XSTR (XEXP (list, 0), 0);
3684 rtx *prev;
3686 if ((space[ndim].attr = find_attr (name, 0)) == 0
3687 || space[ndim].attr->is_numeric)
3689 unmark_used_attributes (list, space, ndim);
3690 return exp;
3693 /* Add all remaining attribute values that refer to this attribute. */
3694 space[ndim].num_values = 0;
3695 space[ndim].values = 0;
3696 prev = &list;
3697 for (link = list; link; link = *prev)
3698 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3700 space[ndim].num_values++;
3701 *prev = XEXP (link, 1);
3702 XEXP (link, 1) = space[ndim].values;
3703 space[ndim].values = link;
3705 else
3706 prev = &XEXP (link, 1);
3708 /* Add sufficient members to the list of values to make the list
3709 mutually exclusive and record the total size of the attribute
3710 space. */
3711 total *= add_values_to_cover (&space[ndim]);
3714 /* Sort the attribute space so that the attributes go from non-constant
3715 to constant and from most values to least values. */
3716 for (i = 0; i < ndim; i++)
3717 for (j = ndim - 1; j > i; j--)
3718 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3719 || space[j-1].num_values < space[j].num_values)
3721 struct dimension tmp;
3722 tmp = space[j];
3723 space[j] = space[j - 1];
3724 space[j - 1] = tmp;
3727 /* Establish the initial current value. */
3728 for (i = 0; i < ndim; i++)
3729 space[i].current_value = space[i].values;
3731 condtest = (rtx *) xmalloc (total * sizeof (rtx));
3732 condval = (rtx *) xmalloc (total * sizeof (rtx));
3734 /* Expand the tests and values by iterating over all values in the
3735 attribute space. */
3736 for (i = 0;; i++)
3738 condtest[i] = test_for_current_value (space, ndim);
3739 condval[i] = simplify_with_current_value (exp, space, ndim);
3740 if (! increment_current_value (space, ndim))
3741 break;
3743 if (i != total - 1)
3744 abort ();
3746 /* We are now finished with the original expression. */
3747 unmark_used_attributes (0, space, ndim);
3748 free (space);
3750 /* Find the most used constant value and make that the default. */
3751 most_tests = -1;
3752 for (i = num_marks = 0; i < total; i++)
3753 if (GET_CODE (condval[i]) == CONST_STRING
3754 && ! ATTR_EQ_ATTR_P (condval[i]))
3756 /* Mark the unmarked constant value and count how many are marked. */
3757 ATTR_EQ_ATTR_P (condval[i]) = 1;
3758 for (j = new_marks = 0; j < total; j++)
3759 if (GET_CODE (condval[j]) == CONST_STRING
3760 && ATTR_EQ_ATTR_P (condval[j]))
3761 new_marks++;
3762 if (new_marks - num_marks > most_tests)
3764 most_tests = new_marks - num_marks;
3765 defval = condval[i];
3767 num_marks = new_marks;
3769 /* Clear all the marks. */
3770 for (i = 0; i < total; i++)
3771 ATTR_EQ_ATTR_P (condval[i]) = 0;
3773 /* Give up if nothing is constant. */
3774 if (num_marks == 0)
3775 ret = exp;
3777 /* If all values are the default, use that. */
3778 else if (total == most_tests)
3779 ret = defval;
3781 /* Make a COND with the most common constant value the default. (A more
3782 complex method where tests with the same value were combined didn't
3783 seem to improve things.) */
3784 else
3786 condexp = rtx_alloc (COND);
3787 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3788 XEXP (condexp, 1) = defval;
3789 for (i = j = 0; i < total; i++)
3790 if (condval[i] != defval)
3792 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3793 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3794 j++;
3796 ret = condexp;
3798 free (condtest);
3799 free (condval);
3800 return ret;
3803 /* Set the ATTR_EQ_ATTR_P flag for all EQ_ATTR expressions in EXP and
3804 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3805 tests have known value. */
3807 static int
3808 find_and_mark_used_attributes (exp, terms, nterms)
3809 rtx exp, *terms;
3810 int *nterms;
3812 int i;
3814 switch (GET_CODE (exp))
3816 case EQ_ATTR:
3817 if (! ATTR_EQ_ATTR_P (exp))
3819 rtx link = rtx_alloc (EXPR_LIST);
3820 XEXP (link, 0) = exp;
3821 XEXP (link, 1) = *terms;
3822 *terms = link;
3823 *nterms += 1;
3824 ATTR_EQ_ATTR_P (exp) = 1;
3826 return 1;
3828 case CONST_STRING:
3829 case CONST_INT:
3830 return 1;
3832 case IF_THEN_ELSE:
3833 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3834 return 0;
3835 case IOR:
3836 case AND:
3837 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3838 return 0;
3839 case NOT:
3840 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3841 return 0;
3842 return 1;
3844 case COND:
3845 for (i = 0; i < XVECLEN (exp, 0); i++)
3846 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3847 return 0;
3848 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3849 return 0;
3850 return 1;
3852 default:
3853 return 0;
3857 /* Clear the ATTR_EQ_ATTR_P flag in all EQ_ATTR expressions on LIST and
3858 in the values of the NDIM-dimensional attribute space SPACE. */
3860 static void
3861 unmark_used_attributes (list, space, ndim)
3862 rtx list;
3863 struct dimension *space;
3864 int ndim;
3866 rtx link, exp;
3867 int i;
3869 for (i = 0; i < ndim; i++)
3870 unmark_used_attributes (space[i].values, 0, 0);
3872 for (link = list; link; link = XEXP (link, 1))
3874 exp = XEXP (link, 0);
3875 if (GET_CODE (exp) == EQ_ATTR)
3876 ATTR_EQ_ATTR_P (exp) = 0;
3880 /* Update the attribute dimension DIM so that all values of the attribute
3881 are tested. Return the updated number of values. */
3883 static int
3884 add_values_to_cover (dim)
3885 struct dimension *dim;
3887 struct attr_value *av;
3888 rtx exp, link, *prev;
3889 int nalt = 0;
3891 for (av = dim->attr->first_value; av; av = av->next)
3892 if (GET_CODE (av->value) == CONST_STRING)
3893 nalt++;
3895 if (nalt < dim->num_values)
3896 abort ();
3897 else if (nalt == dim->num_values)
3898 /* OK. */
3900 else if (nalt * 2 < dim->num_values * 3)
3902 /* Most all the values of the attribute are used, so add all the unused
3903 values. */
3904 prev = &dim->values;
3905 for (link = dim->values; link; link = *prev)
3906 prev = &XEXP (link, 1);
3908 for (av = dim->attr->first_value; av; av = av->next)
3909 if (GET_CODE (av->value) == CONST_STRING)
3911 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3912 if (ATTR_EQ_ATTR_P (exp))
3913 continue;
3915 link = rtx_alloc (EXPR_LIST);
3916 XEXP (link, 0) = exp;
3917 XEXP (link, 1) = 0;
3918 *prev = link;
3919 prev = &XEXP (link, 1);
3921 dim->num_values = nalt;
3923 else
3925 rtx orexp = false_rtx;
3927 /* Very few values are used, so compute a mutually exclusive
3928 expression. (We could do this for numeric values if that becomes
3929 important.) */
3930 prev = &dim->values;
3931 for (link = dim->values; link; link = *prev)
3933 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3934 prev = &XEXP (link, 1);
3936 link = rtx_alloc (EXPR_LIST);
3937 XEXP (link, 0) = attr_rtx (NOT, orexp);
3938 XEXP (link, 1) = 0;
3939 *prev = link;
3940 dim->num_values++;
3942 return dim->num_values;
3945 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3946 and return FALSE if the increment overflowed. */
3948 static int
3949 increment_current_value (space, ndim)
3950 struct dimension *space;
3951 int ndim;
3953 int i;
3955 for (i = ndim - 1; i >= 0; i--)
3957 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3958 space[i].current_value = space[i].values;
3959 else
3960 return 1;
3962 return 0;
3965 /* Construct an expression corresponding to the current value for the
3966 NDIM-dimensional attribute space SPACE. */
3968 static rtx
3969 test_for_current_value (space, ndim)
3970 struct dimension *space;
3971 int ndim;
3973 int i;
3974 rtx exp = true_rtx;
3976 for (i = 0; i < ndim; i++)
3977 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3978 -2, -2);
3980 return exp;
3983 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3984 set the corresponding EQ_ATTR expressions to that value and reduce
3985 the expression EXP as much as possible. On input [and output], all
3986 known EQ_ATTR expressions are set to FALSE. */
3988 static rtx
3989 simplify_with_current_value (exp, space, ndim)
3990 rtx exp;
3991 struct dimension *space;
3992 int ndim;
3994 int i;
3995 rtx x;
3997 /* Mark each current value as TRUE. */
3998 for (i = 0; i < ndim; i++)
4000 x = XEXP (space[i].current_value, 0);
4001 if (GET_CODE (x) == EQ_ATTR)
4002 ATTR_EQ_ATTR_P (x) = 0;
4005 exp = simplify_with_current_value_aux (exp);
4007 /* Change each current value back to FALSE. */
4008 for (i = 0; i < ndim; i++)
4010 x = XEXP (space[i].current_value, 0);
4011 if (GET_CODE (x) == EQ_ATTR)
4012 ATTR_EQ_ATTR_P (x) = 1;
4015 return exp;
4018 /* Reduce the expression EXP based on the ATTR_EQ_ATTR_P settings of
4019 all EQ_ATTR expressions. */
4021 static rtx
4022 simplify_with_current_value_aux (exp)
4023 rtx exp;
4025 int i;
4026 rtx cond;
4028 switch (GET_CODE (exp))
4030 case EQ_ATTR:
4031 if (ATTR_EQ_ATTR_P (exp))
4032 return false_rtx;
4033 else
4034 return true_rtx;
4035 case CONST_STRING:
4036 case CONST_INT:
4037 return exp;
4039 case IF_THEN_ELSE:
4040 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4041 if (cond == true_rtx)
4042 return simplify_with_current_value_aux (XEXP (exp, 1));
4043 else if (cond == false_rtx)
4044 return simplify_with_current_value_aux (XEXP (exp, 2));
4045 else
4046 return attr_rtx (IF_THEN_ELSE, cond,
4047 simplify_with_current_value_aux (XEXP (exp, 1)),
4048 simplify_with_current_value_aux (XEXP (exp, 2)));
4050 case IOR:
4051 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4052 if (cond == true_rtx)
4053 return cond;
4054 else if (cond == false_rtx)
4055 return simplify_with_current_value_aux (XEXP (exp, 0));
4056 else
4057 return attr_rtx (IOR, cond,
4058 simplify_with_current_value_aux (XEXP (exp, 0)));
4060 case AND:
4061 cond = simplify_with_current_value_aux (XEXP (exp, 1));
4062 if (cond == true_rtx)
4063 return simplify_with_current_value_aux (XEXP (exp, 0));
4064 else if (cond == false_rtx)
4065 return cond;
4066 else
4067 return attr_rtx (AND, cond,
4068 simplify_with_current_value_aux (XEXP (exp, 0)));
4070 case NOT:
4071 cond = simplify_with_current_value_aux (XEXP (exp, 0));
4072 if (cond == true_rtx)
4073 return false_rtx;
4074 else if (cond == false_rtx)
4075 return true_rtx;
4076 else
4077 return attr_rtx (NOT, cond);
4079 case COND:
4080 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4082 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
4083 if (cond == true_rtx)
4084 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
4085 else if (cond == false_rtx)
4086 continue;
4087 else
4088 abort (); /* With all EQ_ATTR's of known value, a case should
4089 have been selected. */
4091 return simplify_with_current_value_aux (XEXP (exp, 1));
4093 default:
4094 abort ();
4098 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
4100 static void
4101 clear_struct_flag (x)
4102 rtx x;
4104 int i;
4105 int j;
4106 enum rtx_code code;
4107 const char *fmt;
4109 ATTR_CURR_SIMPLIFIED_P (x) = 0;
4110 if (ATTR_IND_SIMPLIFIED_P (x))
4111 return;
4113 code = GET_CODE (x);
4115 switch (code)
4117 case REG:
4118 case QUEUED:
4119 case CONST_INT:
4120 case CONST_DOUBLE:
4121 case CONST_VECTOR:
4122 case SYMBOL_REF:
4123 case CODE_LABEL:
4124 case PC:
4125 case CC0:
4126 case EQ_ATTR:
4127 case ATTR_FLAG:
4128 return;
4130 default:
4131 break;
4134 /* Compare the elements. If any pair of corresponding elements
4135 fail to match, return 0 for the whole things. */
4137 fmt = GET_RTX_FORMAT (code);
4138 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4140 switch (fmt[i])
4142 case 'V':
4143 case 'E':
4144 for (j = 0; j < XVECLEN (x, i); j++)
4145 clear_struct_flag (XVECEXP (x, i, j));
4146 break;
4148 case 'e':
4149 clear_struct_flag (XEXP (x, i));
4150 break;
4155 /* Return the number of RTX objects making up the expression X.
4156 But if we count more than MAX objects, stop counting. */
4158 static int
4159 count_sub_rtxs (x, max)
4160 rtx x;
4161 int max;
4163 int i;
4164 int j;
4165 enum rtx_code code;
4166 const char *fmt;
4167 int total = 0;
4169 code = GET_CODE (x);
4171 switch (code)
4173 case REG:
4174 case QUEUED:
4175 case CONST_INT:
4176 case CONST_DOUBLE:
4177 case CONST_VECTOR:
4178 case SYMBOL_REF:
4179 case CODE_LABEL:
4180 case PC:
4181 case CC0:
4182 case EQ_ATTR:
4183 case ATTR_FLAG:
4184 return 1;
4186 default:
4187 break;
4190 /* Compare the elements. If any pair of corresponding elements
4191 fail to match, return 0 for the whole things. */
4193 fmt = GET_RTX_FORMAT (code);
4194 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
4196 if (total >= max)
4197 return total;
4199 switch (fmt[i])
4201 case 'V':
4202 case 'E':
4203 for (j = 0; j < XVECLEN (x, i); j++)
4204 total += count_sub_rtxs (XVECEXP (x, i, j), max);
4205 break;
4207 case 'e':
4208 total += count_sub_rtxs (XEXP (x, i), max);
4209 break;
4212 return total;
4216 /* Create table entries for DEFINE_ATTR. */
4218 static void
4219 gen_attr (exp, lineno)
4220 rtx exp;
4221 int lineno;
4223 struct attr_desc *attr;
4224 struct attr_value *av;
4225 const char *name_ptr;
4226 char *p;
4228 /* Make a new attribute structure. Check for duplicate by looking at
4229 attr->default_val, since it is initialized by this routine. */
4230 attr = find_attr (XSTR (exp, 0), 1);
4231 if (attr->default_val)
4233 message_with_line (lineno, "duplicate definition for attribute %s",
4234 attr->name);
4235 message_with_line (attr->lineno, "previous definition");
4236 have_error = 1;
4237 return;
4239 attr->lineno = lineno;
4241 if (*XSTR (exp, 1) == '\0')
4242 attr->is_numeric = 1;
4243 else
4245 name_ptr = XSTR (exp, 1);
4246 while ((p = next_comma_elt (&name_ptr)) != NULL)
4248 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4249 av->value = attr_rtx (CONST_STRING, p);
4250 av->next = attr->first_value;
4251 attr->first_value = av;
4252 av->first_insn = NULL;
4253 av->num_insns = 0;
4254 av->has_asm_insn = 0;
4258 if (GET_CODE (XEXP (exp, 2)) == CONST)
4260 attr->is_const = 1;
4261 if (attr->is_numeric)
4263 message_with_line (lineno,
4264 "constant attributes may not take numeric values");
4265 have_error = 1;
4268 /* Get rid of the CONST node. It is allowed only at top-level. */
4269 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4272 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4274 message_with_line (lineno,
4275 "`length' attribute must take numeric values");
4276 have_error = 1;
4279 /* Set up the default value. */
4280 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4281 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4284 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4285 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4286 number of alternatives as this should be checked elsewhere. */
4288 static int
4289 count_alternatives (exp)
4290 rtx exp;
4292 int i, j, n;
4293 const char *fmt;
4295 if (GET_CODE (exp) == MATCH_OPERAND)
4296 return n_comma_elts (XSTR (exp, 2));
4298 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4299 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4300 switch (*fmt++)
4302 case 'e':
4303 case 'u':
4304 n = count_alternatives (XEXP (exp, i));
4305 if (n)
4306 return n;
4307 break;
4309 case 'E':
4310 case 'V':
4311 if (XVEC (exp, i) != NULL)
4312 for (j = 0; j < XVECLEN (exp, i); j++)
4314 n = count_alternatives (XVECEXP (exp, i, j));
4315 if (n)
4316 return n;
4320 return 0;
4323 /* Returns nonzero if the given expression contains an EQ_ATTR with the
4324 `alternative' attribute. */
4326 static int
4327 compares_alternatives_p (exp)
4328 rtx exp;
4330 int i, j;
4331 const char *fmt;
4333 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4334 return 1;
4336 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4337 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4338 switch (*fmt++)
4340 case 'e':
4341 case 'u':
4342 if (compares_alternatives_p (XEXP (exp, i)))
4343 return 1;
4344 break;
4346 case 'E':
4347 for (j = 0; j < XVECLEN (exp, i); j++)
4348 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4349 return 1;
4350 break;
4353 return 0;
4356 /* Returns nonzero is INNER is contained in EXP. */
4358 static int
4359 contained_in_p (inner, exp)
4360 rtx inner;
4361 rtx exp;
4363 int i, j;
4364 const char *fmt;
4366 if (rtx_equal_p (inner, exp))
4367 return 1;
4369 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4370 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4371 switch (*fmt++)
4373 case 'e':
4374 case 'u':
4375 if (contained_in_p (inner, XEXP (exp, i)))
4376 return 1;
4377 break;
4379 case 'E':
4380 for (j = 0; j < XVECLEN (exp, i); j++)
4381 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4382 return 1;
4383 break;
4386 return 0;
4389 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4391 static void
4392 gen_insn (exp, lineno)
4393 rtx exp;
4394 int lineno;
4396 struct insn_def *id;
4398 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4399 id->next = defs;
4400 defs = id;
4401 id->def = exp;
4402 id->lineno = lineno;
4404 switch (GET_CODE (exp))
4406 case DEFINE_INSN:
4407 id->insn_code = insn_code_number;
4408 id->insn_index = insn_index_number;
4409 id->num_alternatives = count_alternatives (exp);
4410 if (id->num_alternatives == 0)
4411 id->num_alternatives = 1;
4412 id->vec_idx = 4;
4413 break;
4415 case DEFINE_PEEPHOLE:
4416 id->insn_code = insn_code_number;
4417 id->insn_index = insn_index_number;
4418 id->num_alternatives = count_alternatives (exp);
4419 if (id->num_alternatives == 0)
4420 id->num_alternatives = 1;
4421 id->vec_idx = 3;
4422 break;
4424 case DEFINE_ASM_ATTRIBUTES:
4425 id->insn_code = -1;
4426 id->insn_index = -1;
4427 id->num_alternatives = 1;
4428 id->vec_idx = 0;
4429 got_define_asm_attributes = 1;
4430 break;
4432 default:
4433 abort ();
4437 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4438 true or annul false is specified, and make a `struct delay_desc'. */
4440 static void
4441 gen_delay (def, lineno)
4442 rtx def;
4443 int lineno;
4445 struct delay_desc *delay;
4446 int i;
4448 if (XVECLEN (def, 1) % 3 != 0)
4450 message_with_line (lineno,
4451 "number of elements in DEFINE_DELAY must be multiple of three");
4452 have_error = 1;
4453 return;
4456 for (i = 0; i < XVECLEN (def, 1); i += 3)
4458 if (XVECEXP (def, 1, i + 1))
4459 have_annul_true = 1;
4460 if (XVECEXP (def, 1, i + 2))
4461 have_annul_false = 1;
4464 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4465 delay->def = def;
4466 delay->num = ++num_delays;
4467 delay->next = delays;
4468 delay->lineno = lineno;
4469 delays = delay;
4472 /* Process a DEFINE_FUNCTION_UNIT.
4474 This gives information about a function unit contained in the CPU.
4475 We fill in a `struct function_unit_op' and a `struct function_unit'
4476 with information used later by `expand_unit'. */
4478 static void
4479 gen_unit (def, lineno)
4480 rtx def;
4481 int lineno;
4483 struct function_unit *unit;
4484 struct function_unit_op *op;
4485 const char *name = XSTR (def, 0);
4486 int multiplicity = XINT (def, 1);
4487 int simultaneity = XINT (def, 2);
4488 rtx condexp = XEXP (def, 3);
4489 int ready_cost = MAX (XINT (def, 4), 1);
4490 int issue_delay = MAX (XINT (def, 5), 1);
4492 /* See if we have already seen this function unit. If so, check that
4493 the multiplicity and simultaneity values are the same. If not, make
4494 a structure for this function unit. */
4495 for (unit = units; unit; unit = unit->next)
4496 if (! strcmp (unit->name, name))
4498 if (unit->multiplicity != multiplicity
4499 || unit->simultaneity != simultaneity)
4501 message_with_line (lineno,
4502 "differing specifications given for function unit %s",
4503 unit->name);
4504 message_with_line (unit->first_lineno, "previous definition");
4505 have_error = 1;
4506 return;
4508 break;
4511 if (unit == 0)
4513 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4514 unit->name = name;
4515 unit->multiplicity = multiplicity;
4516 unit->simultaneity = simultaneity;
4517 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4518 unit->num = num_units++;
4519 unit->num_opclasses = 0;
4520 unit->condexp = false_rtx;
4521 unit->ops = 0;
4522 unit->next = units;
4523 unit->first_lineno = lineno;
4524 units = unit;
4527 /* Make a new operation class structure entry and initialize it. */
4528 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4529 op->condexp = condexp;
4530 op->num = unit->num_opclasses++;
4531 op->ready = ready_cost;
4532 op->issue_delay = issue_delay;
4533 op->next = unit->ops;
4534 op->lineno = lineno;
4535 unit->ops = op;
4536 num_unit_opclasses++;
4538 /* Set our issue expression based on whether or not an optional conflict
4539 vector was specified. */
4540 if (XVEC (def, 6))
4542 /* Compute the IOR of all the specified expressions. */
4543 rtx orexp = false_rtx;
4544 int i;
4546 for (i = 0; i < XVECLEN (def, 6); i++)
4547 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4549 op->conflict_exp = orexp;
4550 extend_range (&unit->issue_delay, 1, issue_delay);
4552 else
4554 op->conflict_exp = true_rtx;
4555 extend_range (&unit->issue_delay, issue_delay, issue_delay);
4558 /* Merge our conditional into that of the function unit so we can determine
4559 which insns are used by the function unit. */
4560 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4563 /* Given a piece of RTX, print a C expression to test its truth value.
4564 We use AND and IOR both for logical and bit-wise operations, so
4565 interpret them as logical unless they are inside a comparison expression.
4566 The first bit of FLAGS will be nonzero in that case.
4568 Set the second bit of FLAGS to make references to attribute values use
4569 a cached local variable instead of calling a function. */
4571 static void
4572 write_test_expr (exp, flags)
4573 rtx exp;
4574 int flags;
4576 int comparison_operator = 0;
4577 RTX_CODE code;
4578 struct attr_desc *attr;
4580 /* In order not to worry about operator precedence, surround our part of
4581 the expression with parentheses. */
4583 printf ("(");
4584 code = GET_CODE (exp);
4585 switch (code)
4587 /* Binary operators. */
4588 case EQ: case NE:
4589 case GE: case GT: case GEU: case GTU:
4590 case LE: case LT: case LEU: case LTU:
4591 comparison_operator = 1;
4593 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4594 case AND: case IOR: case XOR:
4595 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4596 write_test_expr (XEXP (exp, 0), flags | comparison_operator);
4597 switch (code)
4599 case EQ:
4600 printf (" == ");
4601 break;
4602 case NE:
4603 printf (" != ");
4604 break;
4605 case GE:
4606 printf (" >= ");
4607 break;
4608 case GT:
4609 printf (" > ");
4610 break;
4611 case GEU:
4612 printf (" >= (unsigned) ");
4613 break;
4614 case GTU:
4615 printf (" > (unsigned) ");
4616 break;
4617 case LE:
4618 printf (" <= ");
4619 break;
4620 case LT:
4621 printf (" < ");
4622 break;
4623 case LEU:
4624 printf (" <= (unsigned) ");
4625 break;
4626 case LTU:
4627 printf (" < (unsigned) ");
4628 break;
4629 case PLUS:
4630 printf (" + ");
4631 break;
4632 case MINUS:
4633 printf (" - ");
4634 break;
4635 case MULT:
4636 printf (" * ");
4637 break;
4638 case DIV:
4639 printf (" / ");
4640 break;
4641 case MOD:
4642 printf (" %% ");
4643 break;
4644 case AND:
4645 if (flags & 1)
4646 printf (" & ");
4647 else
4648 printf (" && ");
4649 break;
4650 case IOR:
4651 if (flags & 1)
4652 printf (" | ");
4653 else
4654 printf (" || ");
4655 break;
4656 case XOR:
4657 printf (" ^ ");
4658 break;
4659 case ASHIFT:
4660 printf (" << ");
4661 break;
4662 case LSHIFTRT:
4663 case ASHIFTRT:
4664 printf (" >> ");
4665 break;
4666 default:
4667 abort ();
4670 write_test_expr (XEXP (exp, 1), flags | comparison_operator);
4671 break;
4673 case NOT:
4674 /* Special-case (not (eq_attrq "alternative" "x")) */
4675 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4676 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4678 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4679 break;
4682 /* Otherwise, fall through to normal unary operator. */
4684 /* Unary operators. */
4685 case ABS: case NEG:
4686 switch (code)
4688 case NOT:
4689 if (flags & 1)
4690 printf ("~ ");
4691 else
4692 printf ("! ");
4693 break;
4694 case ABS:
4695 printf ("abs ");
4696 break;
4697 case NEG:
4698 printf ("-");
4699 break;
4700 default:
4701 abort ();
4704 write_test_expr (XEXP (exp, 0), flags);
4705 break;
4707 /* Comparison test of an attribute with a value. Most of these will
4708 have been removed by optimization. Handle "alternative"
4709 specially and give error if EQ_ATTR present inside a comparison. */
4710 case EQ_ATTR:
4711 if (flags & 1)
4712 fatal ("EQ_ATTR not valid inside comparison");
4714 if (XSTR (exp, 0) == alternative_name)
4716 printf ("which_alternative == %s", XSTR (exp, 1));
4717 break;
4720 attr = find_attr (XSTR (exp, 0), 0);
4721 if (! attr)
4722 abort ();
4724 /* Now is the time to expand the value of a constant attribute. */
4725 if (attr->is_const)
4727 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4728 -2, -2),
4729 flags);
4731 else
4733 if (flags & 2)
4734 printf ("attr_%s", attr->name);
4735 else
4736 printf ("get_attr_%s (insn)", attr->name);
4737 printf (" == ");
4738 write_attr_valueq (attr, XSTR (exp, 1));
4740 break;
4742 /* Comparison test of flags for define_delays. */
4743 case ATTR_FLAG:
4744 if (flags & 1)
4745 fatal ("ATTR_FLAG not valid inside comparison");
4746 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4747 break;
4749 /* See if an operand matches a predicate. */
4750 case MATCH_OPERAND:
4751 /* If only a mode is given, just ensure the mode matches the operand.
4752 If neither a mode nor predicate is given, error. */
4753 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4755 if (GET_MODE (exp) == VOIDmode)
4756 fatal ("null MATCH_OPERAND specified as test");
4757 else
4758 printf ("GET_MODE (operands[%d]) == %smode",
4759 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4761 else
4762 printf ("%s (operands[%d], %smode)",
4763 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4764 break;
4766 case MATCH_INSN:
4767 printf ("%s (insn)", XSTR (exp, 0));
4768 break;
4770 /* Constant integer. */
4771 case CONST_INT:
4772 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0));
4773 break;
4775 /* A random C expression. */
4776 case SYMBOL_REF:
4777 printf ("%s", XSTR (exp, 0));
4778 break;
4780 /* The address of the branch target. */
4781 case MATCH_DUP:
4782 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
4783 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4784 break;
4786 case PC:
4787 /* The address of the current insn. We implement this actually as the
4788 address of the current insn for backward branches, but the last
4789 address of the next insn for forward branches, and both with
4790 adjustments that account for the worst-case possible stretching of
4791 intervening alignments between this insn and its destination. */
4792 printf ("insn_current_reference_address (insn)");
4793 break;
4795 case CONST_STRING:
4796 printf ("%s", XSTR (exp, 0));
4797 break;
4799 case IF_THEN_ELSE:
4800 write_test_expr (XEXP (exp, 0), flags & 2);
4801 printf (" ? ");
4802 write_test_expr (XEXP (exp, 1), flags | 1);
4803 printf (" : ");
4804 write_test_expr (XEXP (exp, 2), flags | 1);
4805 break;
4807 default:
4808 fatal ("bad RTX code `%s' in attribute calculation\n",
4809 GET_RTX_NAME (code));
4812 printf (")");
4815 /* Given an attribute value, return the maximum CONST_STRING argument
4816 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
4818 static int
4819 max_attr_value (exp, unknownp)
4820 rtx exp;
4821 int *unknownp;
4823 int current_max;
4824 int i, n;
4826 switch (GET_CODE (exp))
4828 case CONST_STRING:
4829 current_max = atoi (XSTR (exp, 0));
4830 break;
4832 case COND:
4833 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4834 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4836 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4837 if (n > current_max)
4838 current_max = n;
4840 break;
4842 case IF_THEN_ELSE:
4843 current_max = max_attr_value (XEXP (exp, 1), unknownp);
4844 n = max_attr_value (XEXP (exp, 2), unknownp);
4845 if (n > current_max)
4846 current_max = n;
4847 break;
4849 default:
4850 *unknownp = 1;
4851 current_max = INT_MAX;
4852 break;
4855 return current_max;
4858 /* Given an attribute value, return the result of ORing together all
4859 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
4860 if the numeric value is not known. */
4862 static int
4863 or_attr_value (exp, unknownp)
4864 rtx exp;
4865 int *unknownp;
4867 int current_or;
4868 int i;
4870 switch (GET_CODE (exp))
4872 case CONST_STRING:
4873 current_or = atoi (XSTR (exp, 0));
4874 break;
4876 case COND:
4877 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4878 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4879 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp);
4880 break;
4882 case IF_THEN_ELSE:
4883 current_or = or_attr_value (XEXP (exp, 1), unknownp);
4884 current_or |= or_attr_value (XEXP (exp, 2), unknownp);
4885 break;
4887 default:
4888 *unknownp = 1;
4889 current_or = -1;
4890 break;
4893 return current_or;
4896 /* Scan an attribute value, possibly a conditional, and record what actions
4897 will be required to do any conditional tests in it.
4899 Specifically, set
4900 `must_extract' if we need to extract the insn operands
4901 `must_constrain' if we must compute `which_alternative'
4902 `address_used' if an address expression was used
4903 `length_used' if an (eq_attr "length" ...) was used
4906 static void
4907 walk_attr_value (exp)
4908 rtx exp;
4910 int i, j;
4911 const char *fmt;
4912 RTX_CODE code;
4914 if (exp == NULL)
4915 return;
4917 code = GET_CODE (exp);
4918 switch (code)
4920 case SYMBOL_REF:
4921 if (! ATTR_IND_SIMPLIFIED_P (exp))
4922 /* Since this is an arbitrary expression, it can look at anything.
4923 However, constant expressions do not depend on any particular
4924 insn. */
4925 must_extract = must_constrain = 1;
4926 return;
4928 case MATCH_OPERAND:
4929 must_extract = 1;
4930 return;
4932 case EQ_ATTR:
4933 if (XSTR (exp, 0) == alternative_name)
4934 must_extract = must_constrain = 1;
4935 else if (strcmp (XSTR (exp, 0), "length") == 0)
4936 length_used = 1;
4937 return;
4939 case MATCH_DUP:
4940 must_extract = 1;
4941 address_used = 1;
4942 return;
4944 case PC:
4945 address_used = 1;
4946 return;
4948 case ATTR_FLAG:
4949 return;
4951 default:
4952 break;
4955 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4956 switch (*fmt++)
4958 case 'e':
4959 case 'u':
4960 walk_attr_value (XEXP (exp, i));
4961 break;
4963 case 'E':
4964 if (XVEC (exp, i) != NULL)
4965 for (j = 0; j < XVECLEN (exp, i); j++)
4966 walk_attr_value (XVECEXP (exp, i, j));
4967 break;
4971 /* Write out a function to obtain the attribute for a given INSN. */
4973 static void
4974 write_attr_get (attr)
4975 struct attr_desc *attr;
4977 struct attr_value *av, *common_av;
4979 /* Find the most used attribute value. Handle that as the `default' of the
4980 switch we will generate. */
4981 common_av = find_most_used (attr);
4983 /* Write out prototype of function. */
4984 if (!attr->is_numeric)
4985 printf ("extern enum attr_%s ", attr->name);
4986 else if (attr->unsigned_p)
4987 printf ("extern unsigned int ");
4988 else
4989 printf ("extern int ");
4990 /* If the attribute name starts with a star, the remainder is the name of
4991 the subroutine to use, instead of `get_attr_...'. */
4992 if (attr->name[0] == '*')
4993 printf ("%s PARAMS ((rtx));\n", &attr->name[1]);
4994 else
4995 printf ("get_attr_%s PARAMS ((%s));\n", attr->name,
4996 (attr->is_const ? "void" : "rtx"));
4998 /* Write out start of function, then all values with explicit `case' lines,
4999 then a `default', then the value with the most uses. */
5000 if (!attr->is_numeric)
5001 printf ("enum attr_%s\n", attr->name);
5002 else if (attr->unsigned_p)
5003 printf ("unsigned int\n");
5004 else
5005 printf ("int\n");
5007 /* If the attribute name starts with a star, the remainder is the name of
5008 the subroutine to use, instead of `get_attr_...'. */
5009 if (attr->name[0] == '*')
5010 printf ("%s (insn)\n", &attr->name[1]);
5011 else if (attr->is_const == 0)
5012 printf ("get_attr_%s (insn)\n", attr->name);
5013 else
5015 printf ("get_attr_%s ()\n", attr->name);
5016 printf ("{\n");
5018 for (av = attr->first_value; av; av = av->next)
5019 if (av->num_insns != 0)
5020 write_attr_set (attr, 2, av->value, "return", ";",
5021 true_rtx, av->first_insn->insn_code,
5022 av->first_insn->insn_index);
5024 printf ("}\n\n");
5025 return;
5028 printf (" rtx insn ATTRIBUTE_UNUSED;\n");
5029 printf ("{\n");
5031 if (GET_CODE (common_av->value) == FFS)
5033 rtx p = XEXP (common_av->value, 0);
5035 /* No need to emit code to abort if the insn is unrecognized; the
5036 other get_attr_foo functions will do that when we call them. */
5038 write_toplevel_expr (p);
5040 printf ("\n if (accum && accum == (accum & -accum))\n");
5041 printf (" {\n");
5042 printf (" int i;\n");
5043 printf (" for (i = 0; accum >>= 1; ++i) continue;\n");
5044 printf (" accum = i;\n");
5045 printf (" }\n else\n");
5046 printf (" accum = ~accum;\n");
5047 printf (" return accum;\n}\n\n");
5049 else
5051 printf (" switch (recog_memoized (insn))\n");
5052 printf (" {\n");
5054 for (av = attr->first_value; av; av = av->next)
5055 if (av != common_av)
5056 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5058 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5059 printf (" }\n}\n\n");
5063 /* Given an AND tree of known true terms (because we are inside an `if' with
5064 that as the condition or are in an `else' clause) and an expression,
5065 replace any known true terms with TRUE. Use `simplify_and_tree' to do
5066 the bulk of the work. */
5068 static rtx
5069 eliminate_known_true (known_true, exp, insn_code, insn_index)
5070 rtx known_true;
5071 rtx exp;
5072 int insn_code, insn_index;
5074 rtx term;
5076 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
5078 if (GET_CODE (known_true) == AND)
5080 exp = eliminate_known_true (XEXP (known_true, 0), exp,
5081 insn_code, insn_index);
5082 exp = eliminate_known_true (XEXP (known_true, 1), exp,
5083 insn_code, insn_index);
5085 else
5087 term = known_true;
5088 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
5091 return exp;
5094 /* Write out a series of tests and assignment statements to perform tests and
5095 sets of an attribute value. We are passed an indentation amount and prefix
5096 and suffix strings to write around each attribute value (e.g., "return"
5097 and ";"). */
5099 static void
5100 write_attr_set (attr, indent, value, prefix, suffix, known_true,
5101 insn_code, insn_index)
5102 struct attr_desc *attr;
5103 int indent;
5104 rtx value;
5105 const char *prefix;
5106 const char *suffix;
5107 rtx known_true;
5108 int insn_code, insn_index;
5110 if (GET_CODE (value) == COND)
5112 /* Assume the default value will be the default of the COND unless we
5113 find an always true expression. */
5114 rtx default_val = XEXP (value, 1);
5115 rtx our_known_true = known_true;
5116 rtx newexp;
5117 int first_if = 1;
5118 int i;
5120 for (i = 0; i < XVECLEN (value, 0); i += 2)
5122 rtx testexp;
5123 rtx inner_true;
5125 testexp = eliminate_known_true (our_known_true,
5126 XVECEXP (value, 0, i),
5127 insn_code, insn_index);
5128 newexp = attr_rtx (NOT, testexp);
5129 newexp = insert_right_side (AND, our_known_true, newexp,
5130 insn_code, insn_index);
5132 /* If the test expression is always true or if the next `known_true'
5133 expression is always false, this is the last case, so break
5134 out and let this value be the `else' case. */
5135 if (testexp == true_rtx || newexp == false_rtx)
5137 default_val = XVECEXP (value, 0, i + 1);
5138 break;
5141 /* Compute the expression to pass to our recursive call as being
5142 known true. */
5143 inner_true = insert_right_side (AND, our_known_true,
5144 testexp, insn_code, insn_index);
5146 /* If this is always false, skip it. */
5147 if (inner_true == false_rtx)
5148 continue;
5150 write_indent (indent);
5151 printf ("%sif ", first_if ? "" : "else ");
5152 first_if = 0;
5153 write_test_expr (testexp, 0);
5154 printf ("\n");
5155 write_indent (indent + 2);
5156 printf ("{\n");
5158 write_attr_set (attr, indent + 4,
5159 XVECEXP (value, 0, i + 1), prefix, suffix,
5160 inner_true, insn_code, insn_index);
5161 write_indent (indent + 2);
5162 printf ("}\n");
5163 our_known_true = newexp;
5166 if (! first_if)
5168 write_indent (indent);
5169 printf ("else\n");
5170 write_indent (indent + 2);
5171 printf ("{\n");
5174 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
5175 prefix, suffix, our_known_true, insn_code, insn_index);
5177 if (! first_if)
5179 write_indent (indent + 2);
5180 printf ("}\n");
5183 else
5185 write_indent (indent);
5186 printf ("%s ", prefix);
5187 write_attr_value (attr, value);
5188 printf ("%s\n", suffix);
5192 /* Write out the computation for one attribute value. */
5194 static void
5195 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
5196 known_true)
5197 struct attr_desc *attr;
5198 struct attr_value *av;
5199 int write_case_lines;
5200 const char *prefix, *suffix;
5201 int indent;
5202 rtx known_true;
5204 struct insn_ent *ie;
5206 if (av->num_insns == 0)
5207 return;
5209 if (av->has_asm_insn)
5211 write_indent (indent);
5212 printf ("case -1:\n");
5213 write_indent (indent + 2);
5214 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
5215 write_indent (indent + 2);
5216 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
5217 write_indent (indent + 2);
5218 printf (" fatal_insn_not_found (insn);\n");
5221 if (write_case_lines)
5223 for (ie = av->first_insn; ie; ie = ie->next)
5224 if (ie->insn_code != -1)
5226 write_indent (indent);
5227 printf ("case %d:\n", ie->insn_code);
5230 else
5232 write_indent (indent);
5233 printf ("default:\n");
5236 /* See what we have to do to output this value. */
5237 must_extract = must_constrain = address_used = 0;
5238 walk_attr_value (av->value);
5240 if (must_constrain)
5242 write_indent (indent + 2);
5243 printf ("extract_constrain_insn_cached (insn);\n");
5245 else if (must_extract)
5247 write_indent (indent + 2);
5248 printf ("extract_insn_cached (insn);\n");
5251 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
5252 known_true, av->first_insn->insn_code,
5253 av->first_insn->insn_index);
5255 if (strncmp (prefix, "return", 6))
5257 write_indent (indent + 2);
5258 printf ("break;\n");
5260 printf ("\n");
5263 /* Search for uses of non-const attributes and write code to cache them. */
5265 static int
5266 write_expr_attr_cache (p, attr)
5267 rtx p;
5268 struct attr_desc *attr;
5270 const char *fmt;
5271 int i, ie, j, je;
5273 if (GET_CODE (p) == EQ_ATTR)
5275 if (XSTR (p, 0) != attr->name)
5276 return 0;
5278 if (!attr->is_numeric)
5279 printf (" enum attr_%s ", attr->name);
5280 else if (attr->unsigned_p)
5281 printf (" unsigned int ");
5282 else
5283 printf (" int ");
5285 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name);
5286 return 1;
5289 fmt = GET_RTX_FORMAT (GET_CODE (p));
5290 ie = GET_RTX_LENGTH (GET_CODE (p));
5291 for (i = 0; i < ie; i++)
5293 switch (*fmt++)
5295 case 'e':
5296 if (write_expr_attr_cache (XEXP (p, i), attr))
5297 return 1;
5298 break;
5300 case 'E':
5301 je = XVECLEN (p, i);
5302 for (j = 0; j < je; ++j)
5303 if (write_expr_attr_cache (XVECEXP (p, i, j), attr))
5304 return 1;
5305 break;
5309 return 0;
5312 /* Evaluate an expression at top level. A front end to write_test_expr,
5313 in which we cache attribute values and break up excessively large
5314 expressions to cater to older compilers. */
5316 static void
5317 write_toplevel_expr (p)
5318 rtx p;
5320 struct attr_desc *attr;
5321 int i;
5323 for (i = 0; i < MAX_ATTRS_INDEX; ++i)
5324 for (attr = attrs[i]; attr; attr = attr->next)
5325 if (!attr->is_const)
5326 write_expr_attr_cache (p, attr);
5328 printf (" unsigned long accum = 0;\n\n");
5330 while (GET_CODE (p) == IOR)
5332 rtx e;
5333 if (GET_CODE (XEXP (p, 0)) == IOR)
5334 e = XEXP (p, 1), p = XEXP (p, 0);
5335 else
5336 e = XEXP (p, 0), p = XEXP (p, 1);
5338 printf (" accum |= ");
5339 write_test_expr (e, 3);
5340 printf (";\n");
5342 printf (" accum |= ");
5343 write_test_expr (p, 3);
5344 printf (";\n");
5347 /* Utilities to write names in various forms. */
5349 static void
5350 write_unit_name (prefix, num, suffix)
5351 const char *prefix;
5352 int num;
5353 const char *suffix;
5355 struct function_unit *unit;
5357 for (unit = units; unit; unit = unit->next)
5358 if (unit->num == num)
5360 printf ("%s%s%s", prefix, unit->name, suffix);
5361 return;
5364 printf ("%s<unknown>%s", prefix, suffix);
5367 static void
5368 write_attr_valueq (attr, s)
5369 struct attr_desc *attr;
5370 const char *s;
5372 if (attr->is_numeric)
5374 int num = atoi (s);
5376 printf ("%d", num);
5378 /* Make the blockage range values and function units used values easier
5379 to read. */
5380 if (attr->func_units_p)
5382 if (num == -1)
5383 printf (" /* units: none */");
5384 else if (num >= 0)
5385 write_unit_name (" /* units: ", num, " */");
5386 else
5388 int i;
5389 const char *sep = " /* units: ";
5390 for (i = 0, num = ~num; num; i++, num >>= 1)
5391 if (num & 1)
5393 write_unit_name (sep, i, (num == 1) ? " */" : "");
5394 sep = ", ";
5399 else if (attr->blockage_p)
5400 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2),
5401 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1));
5403 else if (num > 9 || num < 0)
5404 printf (" /* 0x%x */", num);
5406 else
5408 write_upcase (attr->name);
5409 printf ("_");
5410 write_upcase (s);
5414 static void
5415 write_attr_value (attr, value)
5416 struct attr_desc *attr;
5417 rtx value;
5419 int op;
5421 switch (GET_CODE (value))
5423 case CONST_STRING:
5424 write_attr_valueq (attr, XSTR (value, 0));
5425 break;
5427 case CONST_INT:
5428 printf (HOST_WIDE_INT_PRINT_DEC, INTVAL (value));
5429 break;
5431 case SYMBOL_REF:
5432 fputs (XSTR (value, 0), stdout);
5433 break;
5435 case ATTR:
5437 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0);
5438 printf ("get_attr_%s (%s)", attr2->name,
5439 (attr2->is_const ? "" : "insn"));
5441 break;
5443 case PLUS:
5444 op = '+';
5445 goto do_operator;
5446 case MINUS:
5447 op = '-';
5448 goto do_operator;
5449 case MULT:
5450 op = '*';
5451 goto do_operator;
5452 case DIV:
5453 op = '/';
5454 goto do_operator;
5455 case MOD:
5456 op = '%';
5457 goto do_operator;
5459 do_operator:
5460 write_attr_value (attr, XEXP (value, 0));
5461 putchar (' ');
5462 putchar (op);
5463 putchar (' ');
5464 write_attr_value (attr, XEXP (value, 1));
5465 break;
5467 default:
5468 abort ();
5472 static void
5473 write_upcase (str)
5474 const char *str;
5476 while (*str)
5478 /* The argument of TOUPPER should not have side effects. */
5479 putchar (TOUPPER(*str));
5480 str++;
5484 static void
5485 write_indent (indent)
5486 int indent;
5488 for (; indent > 8; indent -= 8)
5489 printf ("\t");
5491 for (; indent; indent--)
5492 printf (" ");
5495 /* Write a subroutine that is given an insn that requires a delay slot, a
5496 delay slot ordinal, and a candidate insn. It returns nonzero if the
5497 candidate can be placed in the specified delay slot of the insn.
5499 We can write as many as three subroutines. `eligible_for_delay'
5500 handles normal delay slots, `eligible_for_annul_true' indicates that
5501 the specified insn can be annulled if the branch is true, and likewise
5502 for `eligible_for_annul_false'.
5504 KIND is a string distinguishing these three cases ("delay", "annul_true",
5505 or "annul_false"). */
5507 static void
5508 write_eligible_delay (kind)
5509 const char *kind;
5511 struct delay_desc *delay;
5512 int max_slots;
5513 char str[50];
5514 struct attr_desc *attr;
5515 struct attr_value *av, *common_av;
5516 int i;
5518 /* Compute the maximum number of delay slots required. We use the delay
5519 ordinal times this number plus one, plus the slot number as an index into
5520 the appropriate predicate to test. */
5522 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5523 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5524 max_slots = XVECLEN (delay->def, 1) / 3;
5526 /* Write function prelude. */
5528 printf ("int\n");
5529 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5530 kind);
5531 printf (" rtx delay_insn ATTRIBUTE_UNUSED;\n");
5532 printf (" int slot;\n");
5533 printf (" rtx candidate_insn;\n");
5534 printf (" int flags ATTRIBUTE_UNUSED;\n");
5535 printf ("{\n");
5536 printf (" rtx insn;\n");
5537 printf ("\n");
5538 printf (" if (slot >= %d)\n", max_slots);
5539 printf (" abort ();\n");
5540 printf ("\n");
5542 /* If more than one delay type, find out which type the delay insn is. */
5544 if (num_delays > 1)
5546 attr = find_attr ("*delay_type", 0);
5547 if (! attr)
5548 abort ();
5549 common_av = find_most_used (attr);
5551 printf (" insn = delay_insn;\n");
5552 printf (" switch (recog_memoized (insn))\n");
5553 printf (" {\n");
5555 sprintf (str, " * %d;\n break;", max_slots);
5556 for (av = attr->first_value; av; av = av->next)
5557 if (av != common_av)
5558 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5560 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5561 printf (" }\n\n");
5563 /* Ensure matched. Otherwise, shouldn't have been called. */
5564 printf (" if (slot < %d)\n", max_slots);
5565 printf (" abort ();\n\n");
5568 /* If just one type of delay slot, write simple switch. */
5569 if (num_delays == 1 && max_slots == 1)
5571 printf (" insn = candidate_insn;\n");
5572 printf (" switch (recog_memoized (insn))\n");
5573 printf (" {\n");
5575 attr = find_attr ("*delay_1_0", 0);
5576 if (! attr)
5577 abort ();
5578 common_av = find_most_used (attr);
5580 for (av = attr->first_value; av; av = av->next)
5581 if (av != common_av)
5582 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5584 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5585 printf (" }\n");
5588 else
5590 /* Write a nested CASE. The first indicates which condition we need to
5591 test, and the inner CASE tests the condition. */
5592 printf (" insn = candidate_insn;\n");
5593 printf (" switch (slot)\n");
5594 printf (" {\n");
5596 for (delay = delays; delay; delay = delay->next)
5597 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5599 printf (" case %d:\n",
5600 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5601 printf (" switch (recog_memoized (insn))\n");
5602 printf ("\t{\n");
5604 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5605 attr = find_attr (str, 0);
5606 if (! attr)
5607 abort ();
5608 common_av = find_most_used (attr);
5610 for (av = attr->first_value; av; av = av->next)
5611 if (av != common_av)
5612 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5614 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5615 printf (" }\n");
5618 printf (" default:\n");
5619 printf (" abort ();\n");
5620 printf (" }\n");
5623 printf ("}\n\n");
5626 /* Write routines to compute conflict cost for function units. Then write a
5627 table describing the available function units. */
5629 static void
5630 write_function_unit_info ()
5632 struct function_unit *unit;
5633 int i;
5635 /* Write out conflict routines for function units. Don't bother writing
5636 one if there is only one issue delay value. */
5638 for (unit = units; unit; unit = unit->next)
5640 if (unit->needs_blockage_function)
5641 write_complex_function (unit, "blockage", "block");
5643 /* If the minimum and maximum conflict costs are the same, there
5644 is only one value, so we don't need a function. */
5645 if (! unit->needs_conflict_function)
5647 unit->default_cost = make_numeric_value (unit->issue_delay.max);
5648 continue;
5651 /* The function first computes the case from the candidate insn. */
5652 unit->default_cost = make_numeric_value (0);
5653 write_complex_function (unit, "conflict_cost", "cost");
5656 /* Now that all functions have been written, write the table describing
5657 the function units. The name is included for documentation purposes
5658 only. */
5660 printf ("const struct function_unit_desc function_units[] = {\n");
5662 /* Write out the descriptions in numeric order, but don't force that order
5663 on the list. Doing so increases the runtime of genattrtab.c. */
5664 for (i = 0; i < num_units; i++)
5666 for (unit = units; unit; unit = unit->next)
5667 if (unit->num == i)
5668 break;
5670 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5671 unit->name, 1 << unit->num, unit->multiplicity,
5672 unit->simultaneity, XSTR (unit->default_cost, 0),
5673 unit->issue_delay.max, unit->name);
5675 if (unit->needs_conflict_function)
5676 printf ("%s_unit_conflict_cost, ", unit->name);
5677 else
5678 printf ("0, ");
5680 printf ("%d, ", unit->max_blockage);
5682 if (unit->needs_range_function)
5683 printf ("%s_unit_blockage_range, ", unit->name);
5684 else
5685 printf ("0, ");
5687 if (unit->needs_blockage_function)
5688 printf ("%s_unit_blockage", unit->name);
5689 else
5690 printf ("0");
5692 printf ("}, \n");
5695 if (num_units == 0)
5696 printf ("{\"dummy\", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} /* a dummy element */");
5697 printf ("};\n\n");
5700 static void
5701 write_complex_function (unit, name, connection)
5702 struct function_unit *unit;
5703 const char *name, *connection;
5705 struct attr_desc *case_attr, *attr;
5706 struct attr_value *av, *common_av;
5707 rtx value;
5708 char str[256];
5709 int using_case;
5710 int i;
5712 printf ("static int %s_unit_%s PARAMS ((rtx, rtx));\n", unit->name, name);
5713 printf ("static int\n");
5714 printf ("%s_unit_%s (executing_insn, candidate_insn)\n", unit->name, name);
5715 printf (" rtx executing_insn;\n");
5716 printf (" rtx candidate_insn;\n");
5717 printf ("{\n");
5718 printf (" rtx insn;\n");
5719 printf (" int casenum;\n\n");
5720 printf (" insn = executing_insn;\n");
5721 printf (" switch (recog_memoized (insn))\n");
5722 printf (" {\n");
5724 /* Write the `switch' statement to get the case value. */
5725 if (strlen (unit->name) + sizeof "*_cases" > 256)
5726 abort ();
5727 sprintf (str, "*%s_cases", unit->name);
5728 case_attr = find_attr (str, 0);
5729 if (! case_attr)
5730 abort ();
5731 common_av = find_most_used (case_attr);
5733 for (av = case_attr->first_value; av; av = av->next)
5734 if (av != common_av)
5735 write_attr_case (case_attr, av, 1,
5736 "casenum =", ";", 4, unit->condexp);
5738 write_attr_case (case_attr, common_av, 0,
5739 "casenum =", ";", 4, unit->condexp);
5740 printf (" }\n\n");
5742 /* Now write an outer switch statement on each case. Then write
5743 the tests on the executing function within each. */
5744 printf (" insn = candidate_insn;\n");
5745 printf (" switch (casenum)\n");
5746 printf (" {\n");
5748 for (i = 0; i < unit->num_opclasses; i++)
5750 /* Ensure using this case. */
5751 using_case = 0;
5752 for (av = case_attr->first_value; av; av = av->next)
5753 if (av->num_insns
5754 && contained_in_p (make_numeric_value (i), av->value))
5755 using_case = 1;
5757 if (! using_case)
5758 continue;
5760 printf (" case %d:\n", i);
5761 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5762 attr = find_attr (str, 0);
5763 if (! attr)
5764 abort ();
5766 /* If single value, just write it. */
5767 value = find_single_value (attr);
5768 if (value)
5769 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5770 else
5772 common_av = find_most_used (attr);
5773 printf (" switch (recog_memoized (insn))\n");
5774 printf ("\t{\n");
5776 for (av = attr->first_value; av; av = av->next)
5777 if (av != common_av)
5778 write_attr_case (attr, av, 1,
5779 "return", ";", 8, unit->condexp);
5781 write_attr_case (attr, common_av, 0,
5782 "return", ";", 8, unit->condexp);
5783 printf (" }\n\n");
5787 /* This default case should not be needed, but gcc's analysis is not
5788 good enough to realize that the default case is not needed for the
5789 second switch statement. */
5790 printf (" default:\n abort ();\n");
5791 printf (" }\n}\n\n");
5794 /* This page contains miscellaneous utility routines. */
5796 /* Given a pointer to a (char *), return a malloc'ed string containing the
5797 next comma-separated element. Advance the pointer to after the string
5798 scanned, or the end-of-string. Return NULL if at end of string. */
5800 static char *
5801 next_comma_elt (pstr)
5802 const char **pstr;
5804 const char *start;
5806 start = scan_comma_elt (pstr);
5808 if (start == NULL)
5809 return NULL;
5811 return attr_string (start, *pstr - start);
5814 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5815 is nonzero, build a new attribute, if one does not exist. */
5817 static struct attr_desc *
5818 find_attr (name, create)
5819 const char *name;
5820 int create;
5822 struct attr_desc *attr;
5823 int index;
5825 /* Before we resort to using `strcmp', see if the string address matches
5826 anywhere. In most cases, it should have been canonicalized to do so. */
5827 if (name == alternative_name)
5828 return NULL;
5830 index = name[0] & (MAX_ATTRS_INDEX - 1);
5831 for (attr = attrs[index]; attr; attr = attr->next)
5832 if (name == attr->name)
5833 return attr;
5835 /* Otherwise, do it the slow way. */
5836 for (attr = attrs[index]; attr; attr = attr->next)
5837 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5838 return attr;
5840 if (! create)
5841 return NULL;
5843 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5844 attr->name = attr_string (name, strlen (name));
5845 attr->first_value = attr->default_val = NULL;
5846 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5847 attr->unsigned_p = attr->func_units_p = attr->blockage_p = 0;
5848 attr->next = attrs[index];
5849 attrs[index] = attr;
5851 return attr;
5854 /* Create internal attribute with the given default value. */
5856 void
5857 make_internal_attr (name, value, special)
5858 const char *name;
5859 rtx value;
5860 int special;
5862 struct attr_desc *attr;
5864 attr = find_attr (name, 1);
5865 if (attr->default_val)
5866 abort ();
5868 attr->is_numeric = 1;
5869 attr->is_const = 0;
5870 attr->is_special = (special & 1) != 0;
5871 attr->negative_ok = (special & 2) != 0;
5872 attr->unsigned_p = (special & 4) != 0;
5873 attr->func_units_p = (special & 8) != 0;
5874 attr->blockage_p = (special & 16) != 0;
5875 attr->default_val = get_attr_value (value, attr, -2);
5878 /* Find the most used value of an attribute. */
5880 static struct attr_value *
5881 find_most_used (attr)
5882 struct attr_desc *attr;
5884 struct attr_value *av;
5885 struct attr_value *most_used;
5886 int nuses;
5888 most_used = NULL;
5889 nuses = -1;
5891 for (av = attr->first_value; av; av = av->next)
5892 if (av->num_insns > nuses)
5893 nuses = av->num_insns, most_used = av;
5895 return most_used;
5898 /* If an attribute only has a single value used, return it. Otherwise
5899 return NULL. */
5901 static rtx
5902 find_single_value (attr)
5903 struct attr_desc *attr;
5905 struct attr_value *av;
5906 rtx unique_value;
5908 unique_value = NULL;
5909 for (av = attr->first_value; av; av = av->next)
5910 if (av->num_insns)
5912 if (unique_value)
5913 return NULL;
5914 else
5915 unique_value = av->value;
5918 return unique_value;
5921 /* Return (attr_value "n") */
5924 make_numeric_value (n)
5925 int n;
5927 static rtx int_values[20];
5928 rtx exp;
5929 char *p;
5931 if (n < 0)
5932 abort ();
5934 if (n < 20 && int_values[n])
5935 return int_values[n];
5937 p = attr_printf (MAX_DIGITS, "%d", n);
5938 exp = attr_rtx (CONST_STRING, p);
5940 if (n < 20)
5941 int_values[n] = exp;
5943 return exp;
5946 static void
5947 extend_range (range, min, max)
5948 struct range *range;
5949 int min;
5950 int max;
5952 if (range->min > min)
5953 range->min = min;
5954 if (range->max < max)
5955 range->max = max;
5958 static rtx
5959 copy_rtx_unchanging (orig)
5960 rtx orig;
5962 #if 0
5963 rtx copy;
5964 RTX_CODE code;
5965 #endif
5967 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig))
5968 return orig;
5970 ATTR_CURR_SIMPLIFIED_P (orig) = 1;
5971 return orig;
5973 #if 0
5974 code = GET_CODE (orig);
5975 switch (code)
5977 case CONST_INT:
5978 case CONST_DOUBLE:
5979 case SYMBOL_REF:
5980 case CODE_LABEL:
5981 return orig;
5983 default:
5984 break;
5987 copy = rtx_alloc (code);
5988 PUT_MODE (copy, GET_MODE (orig));
5989 ATTR_IND_SIMPLIFIED_P (copy) = 1;
5991 memcpy (&XEXP (copy, 0), &XEXP (orig, 0),
5992 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
5993 return copy;
5994 #endif
5997 /* Determine if an insn has a constant number of delay slots, i.e., the
5998 number of delay slots is not a function of the length of the insn. */
6000 static void
6001 write_const_num_delay_slots ()
6003 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
6004 struct attr_value *av;
6005 struct insn_ent *ie;
6007 if (attr)
6009 printf ("int\nconst_num_delay_slots (insn)\n");
6010 printf (" rtx insn;\n");
6011 printf ("{\n");
6012 printf (" switch (recog_memoized (insn))\n");
6013 printf (" {\n");
6015 for (av = attr->first_value; av; av = av->next)
6017 length_used = 0;
6018 walk_attr_value (av->value);
6019 if (length_used)
6021 for (ie = av->first_insn; ie; ie = ie->next)
6022 if (ie->insn_code != -1)
6023 printf (" case %d:\n", ie->insn_code);
6024 printf (" return 0;\n");
6028 printf (" default:\n");
6029 printf (" return 1;\n");
6030 printf (" }\n}\n\n");
6034 extern int main PARAMS ((int, char **));
6037 main (argc, argv)
6038 int argc;
6039 char **argv;
6041 rtx desc;
6042 struct attr_desc *attr;
6043 struct insn_def *id;
6044 rtx tem;
6045 int i;
6047 progname = "genattrtab";
6049 if (argc <= 1)
6050 fatal ("no input file name");
6052 if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
6053 return (FATAL_EXIT_CODE);
6055 obstack_init (hash_obstack);
6056 obstack_init (temp_obstack);
6058 /* Set up true and false rtx's */
6059 true_rtx = rtx_alloc (CONST_INT);
6060 XWINT (true_rtx, 0) = 1;
6061 false_rtx = rtx_alloc (CONST_INT);
6062 XWINT (false_rtx, 0) = 0;
6063 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1;
6064 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1;
6066 alternative_name = attr_string ("alternative", strlen ("alternative"));
6068 printf ("/* Generated automatically by the program `genattrtab'\n\
6069 from the machine description file `md'. */\n\n");
6071 /* Read the machine description. */
6073 initiate_automaton_gen (argc, argv);
6074 while (1)
6076 int lineno;
6078 desc = read_md_rtx (&lineno, &insn_code_number);
6079 if (desc == NULL)
6080 break;
6082 switch (GET_CODE (desc))
6084 case DEFINE_INSN:
6085 case DEFINE_PEEPHOLE:
6086 case DEFINE_ASM_ATTRIBUTES:
6087 gen_insn (desc, lineno);
6088 break;
6090 case DEFINE_ATTR:
6091 gen_attr (desc, lineno);
6092 break;
6094 case DEFINE_DELAY:
6095 gen_delay (desc, lineno);
6096 break;
6098 case DEFINE_FUNCTION_UNIT:
6099 gen_unit (desc, lineno);
6100 break;
6102 case DEFINE_CPU_UNIT:
6103 gen_cpu_unit (desc);
6104 break;
6106 case DEFINE_QUERY_CPU_UNIT:
6107 gen_query_cpu_unit (desc);
6108 break;
6110 case DEFINE_BYPASS:
6111 gen_bypass (desc);
6112 break;
6114 case EXCLUSION_SET:
6115 gen_excl_set (desc);
6116 break;
6118 case PRESENCE_SET:
6119 gen_presence_set (desc);
6120 break;
6122 case FINAL_PRESENCE_SET:
6123 gen_final_presence_set (desc);
6124 break;
6126 case ABSENCE_SET:
6127 gen_absence_set (desc);
6128 break;
6130 case FINAL_ABSENCE_SET:
6131 gen_final_absence_set (desc);
6132 break;
6134 case DEFINE_AUTOMATON:
6135 gen_automaton (desc);
6136 break;
6138 case AUTOMATA_OPTION:
6139 gen_automata_option (desc);
6140 break;
6142 case DEFINE_RESERVATION:
6143 gen_reserv (desc);
6144 break;
6146 case DEFINE_INSN_RESERVATION:
6147 gen_insn_reserv (desc);
6148 break;
6150 default:
6151 break;
6153 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES)
6154 insn_index_number++;
6157 if (have_error)
6158 return FATAL_EXIT_CODE;
6160 insn_code_number++;
6162 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
6163 if (! got_define_asm_attributes)
6165 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
6166 XVEC (tem, 0) = rtvec_alloc (0);
6167 gen_insn (tem, 0);
6170 /* Expand DEFINE_DELAY information into new attribute. */
6171 if (num_delays)
6172 expand_delays ();
6174 if (num_units || num_dfa_decls)
6176 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
6177 expand_units ();
6178 /* Build DFA, output some functions and expand DFA information
6179 into new attributes. */
6180 expand_automata ();
6183 printf ("#include \"config.h\"\n");
6184 printf ("#include \"system.h\"\n");
6185 printf ("#include \"coretypes.h\"\n");
6186 printf ("#include \"tm.h\"\n");
6187 printf ("#include \"rtl.h\"\n");
6188 printf ("#include \"tm_p.h\"\n");
6189 printf ("#include \"insn-config.h\"\n");
6190 printf ("#include \"recog.h\"\n");
6191 printf ("#include \"regs.h\"\n");
6192 printf ("#include \"real.h\"\n");
6193 printf ("#include \"output.h\"\n");
6194 printf ("#include \"insn-attr.h\"\n");
6195 printf ("#include \"toplev.h\"\n");
6196 printf ("#include \"flags.h\"\n");
6197 printf ("#include \"function.h\"\n");
6198 printf ("\n");
6199 printf ("#define operands recog_data.operand\n\n");
6201 /* Make `insn_alternatives'. */
6202 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6203 for (id = defs; id; id = id->next)
6204 if (id->insn_code >= 0)
6205 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
6207 /* Make `insn_n_alternatives'. */
6208 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
6209 for (id = defs; id; id = id->next)
6210 if (id->insn_code >= 0)
6211 insn_n_alternatives[id->insn_code] = id->num_alternatives;
6213 /* Prepare to write out attribute subroutines by checking everything stored
6214 away and building the attribute cases. */
6216 check_defs ();
6218 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6219 for (attr = attrs[i]; attr; attr = attr->next)
6220 attr->default_val->value
6221 = check_attr_value (attr->default_val->value, attr);
6223 if (have_error)
6224 return FATAL_EXIT_CODE;
6226 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6227 for (attr = attrs[i]; attr; attr = attr->next)
6228 fill_attr (attr);
6230 /* Construct extra attributes for `length'. */
6231 make_length_attrs ();
6233 /* Perform any possible optimizations to speed up compilation. */
6234 optimize_attrs ();
6236 /* Now write out all the `gen_attr_...' routines. Do these before the
6237 special routines (specifically before write_function_unit_info), so
6238 that they get defined before they are used. */
6240 for (i = 0; i < MAX_ATTRS_INDEX; i++)
6241 for (attr = attrs[i]; attr; attr = attr->next)
6243 if (! attr->is_special && ! attr->is_const)
6245 int insn_alts_p;
6247 insn_alts_p
6248 = (attr->name [0] == '*'
6249 && strcmp (&attr->name [1], INSN_ALTS_FUNC_NAME) == 0);
6250 if (insn_alts_p)
6251 printf ("\n#if AUTOMATON_ALTS\n");
6252 write_attr_get (attr);
6253 if (insn_alts_p)
6254 printf ("#endif\n\n");
6258 /* Write out delay eligibility information, if DEFINE_DELAY present.
6259 (The function to compute the number of delay slots will be written
6260 below.) */
6261 if (num_delays)
6263 write_eligible_delay ("delay");
6264 if (have_annul_true)
6265 write_eligible_delay ("annul_true");
6266 if (have_annul_false)
6267 write_eligible_delay ("annul_false");
6270 if (num_units || num_dfa_decls)
6272 /* Write out information about function units. */
6273 write_function_unit_info ();
6274 /* Output code for pipeline hazards recognition based on DFA
6275 (deterministic finite state automata. */
6276 write_automata ();
6279 /* Write out constant delay slot info */
6280 write_const_num_delay_slots ();
6282 write_length_unit_log ();
6284 fflush (stdout);
6285 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
6288 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
6289 const char *
6290 get_insn_name (code)
6291 int code ATTRIBUTE_UNUSED;
6293 return NULL;