Import final gcc2 snapshot (990109)
[official-gcc.git] / gcc / genattrtab.c
blob041072d5f9b3aa7aa8a6712b527bf1f2b990f09c
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* This program handles insn attributes and the DEFINE_DELAY and
23 DEFINE_FUNCTION_UNIT definitions.
25 It produces a series of functions named `get_attr_...', one for each insn
26 attribute. Each of these is given the rtx for an insn and returns a member
27 of the enum for the attribute.
29 These subroutines have the form of a `switch' on the INSN_CODE (via
30 `recog_memoized'). Each case either returns a constant attribute value
31 or a value that depends on tests on other attributes, the form of
32 operands, or some random C expression (encoded with a SYMBOL_REF
33 expression).
35 If the attribute `alternative', or a random C expression is present,
36 `constrain_operands' is called. If either of these cases of a reference to
37 an operand is found, `insn_extract' is called.
39 The special attribute `length' is also recognized. For this operand,
40 expressions involving the address of an operand or the current insn,
41 (address (pc)), are valid. In this case, an initial pass is made to
42 set all lengths that do not depend on address. Those that do are set to
43 the maximum length. Then each insn that depends on an address is checked
44 and possibly has its length changed. The process repeats until no further
45 changed are made. The resulting lengths are saved for use by
46 `get_attr_length'.
48 A special form of DEFINE_ATTR, where the expression for default value is a
49 CONST expression, indicates an attribute that is constant for a given run
50 of the compiler. The subroutine generated for these attributes has no
51 parameters as it does not depend on any particular insn. Constant
52 attributes are typically used to specify which variety of processor is
53 used.
55 Internal attributes are defined to handle DEFINE_DELAY and
56 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
58 This program works by keeping a list of possible values for each attribute.
59 These include the basic attribute choices, default values for attribute, and
60 all derived quantities.
62 As the description file is read, the definition for each insn is saved in a
63 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
64 is created for each insn and chained to the corresponding attribute value,
65 either that specified, or the default.
67 An optimization phase is then run. This simplifies expressions for each
68 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
69 indicates when the attribute has the specified value for the insn. This
70 avoids recursive calls during compilation.
72 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
73 definitions is to create arbitrarily complex expressions and have the
74 optimization simplify them.
76 Once optimization is complete, any required routines and definitions
77 will be written.
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique
93 (see attr_rtx).
94 `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an
95 EQ_ATTR rtx is true if !volatil and false if volatil. */
98 #include "hconfig.h"
99 #include "system.h"
100 #include "rtl.h"
101 #include "insn-config.h" /* For REGISTER_CONSTRAINTS */
103 #ifdef HAVE_SYS_RESOURCE_H
104 # include <sys/resource.h>
105 #endif
107 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
108 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
109 #include "obstack.h"
111 static struct obstack obstack, obstack1, obstack2;
112 struct obstack *rtl_obstack = &obstack;
113 struct obstack *hash_obstack = &obstack1;
114 struct obstack *temp_obstack = &obstack2;
116 #define obstack_chunk_alloc xmalloc
117 #define obstack_chunk_free free
119 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
120 char **insn_name_ptr = 0;
122 extern void free ();
123 extern rtx read_rtx ();
125 #ifdef HAVE_VPRINTF
126 void fatal PVPROTO((char *, ...));
127 #else
128 /* We must not provide any prototype here, even if ANSI C. */
129 void fatal PROTO(());
130 #endif
131 void fancy_abort ();
133 /* enough space to reserve for printing out ints */
134 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
136 /* Define structures used to record attributes and values. */
138 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
139 encountered, we store all the relevant information into a
140 `struct insn_def'. This is done to allow attribute definitions to occur
141 anywhere in the file. */
143 struct insn_def
145 int insn_code; /* Instruction number. */
146 int insn_index; /* Expression numer in file, for errors. */
147 struct insn_def *next; /* Next insn in chain. */
148 rtx def; /* The DEFINE_... */
149 int num_alternatives; /* Number of alternatives. */
150 int vec_idx; /* Index of attribute vector in `def'. */
153 /* Once everything has been read in, we store in each attribute value a list
154 of insn codes that have that value. Here is the structure used for the
155 list. */
157 struct insn_ent
159 int insn_code; /* Instruction number. */
160 int insn_index; /* Index of definition in file */
161 struct insn_ent *next; /* Next in chain. */
164 /* Each value of an attribute (either constant or computed) is assigned a
165 structure which is used as the listhead of the insns that have that
166 value. */
168 struct attr_value
170 rtx value; /* Value of attribute. */
171 struct attr_value *next; /* Next attribute value in chain. */
172 struct insn_ent *first_insn; /* First insn with this value. */
173 int num_insns; /* Number of insns with this value. */
174 int has_asm_insn; /* True if this value used for `asm' insns */
177 /* Structure for each attribute. */
179 struct attr_desc
181 char *name; /* Name of attribute. */
182 struct attr_desc *next; /* Next attribute. */
183 int is_numeric; /* Values of this attribute are numeric. */
184 int negative_ok; /* Allow negative numeric values. */
185 int unsigned_p; /* Make the output function unsigned int. */
186 int is_const; /* Attribute value constant for each run. */
187 int is_special; /* Don't call `write_attr_set'. */
188 struct attr_value *first_value; /* First value of this attribute. */
189 struct attr_value *default_val; /* Default value for this attribute. */
192 #define NULL_ATTR (struct attr_desc *) NULL
194 /* A range of values. */
196 struct range
198 int min;
199 int max;
202 /* Structure for each DEFINE_DELAY. */
204 struct delay_desc
206 rtx def; /* DEFINE_DELAY expression. */
207 struct delay_desc *next; /* Next DEFINE_DELAY. */
208 int num; /* Number of DEFINE_DELAY, starting at 1. */
211 /* Record information about each DEFINE_FUNCTION_UNIT. */
213 struct function_unit_op
215 rtx condexp; /* Expression TRUE for applicable insn. */
216 struct function_unit_op *next; /* Next operation for this function unit. */
217 int num; /* Ordinal for this operation type in unit. */
218 int ready; /* Cost until data is ready. */
219 int issue_delay; /* Cost until unit can accept another insn. */
220 rtx conflict_exp; /* Expression TRUE for insns incurring issue delay. */
221 rtx issue_exp; /* Expression computing issue delay. */
224 /* Record information about each function unit mentioned in a
225 DEFINE_FUNCTION_UNIT. */
227 struct function_unit
229 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. */
246 /* Listheads of above structures. */
248 /* This one is indexed by the first character of the attribute name. */
249 #define MAX_ATTRS_INDEX 256
250 static struct attr_desc *attrs[MAX_ATTRS_INDEX];
251 static struct insn_def *defs;
252 static struct delay_desc *delays;
253 static struct function_unit *units;
255 /* An expression where all the unknown terms are EQ_ATTR tests can be
256 rearranged into a COND provided we can enumerate all possible
257 combinations of the unknown values. The set of combinations become the
258 tests of the COND; the value of the expression given that combination is
259 computed and becomes the corresponding value. To do this, we must be
260 able to enumerate all values for each attribute used in the expression
261 (currently, we give up if we find a numeric attribute).
263 If the set of EQ_ATTR tests used in an expression tests the value of N
264 different attributes, the list of all possible combinations can be made
265 by walking the N-dimensional attribute space defined by those
266 attributes. We record each of these as a struct dimension.
268 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an
269 expression are the same, the will also have the same address. We find
270 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later
271 represents the value of an EQ_ATTR node, so once all nodes are marked,
272 they are also given an initial value of FALSE.
274 We then separate the set of EQ_ATTR nodes into dimensions for each
275 attribute and put them on the VALUES list. Terms are added as needed by
276 `add_values_to_cover' so that all possible values of the attribute are
277 tested.
279 Each dimension also has a current value. This is the node that is
280 currently considered to be TRUE. If this is one of the nodes added by
281 `add_values_to_cover', all the EQ_ATTR tests in the original expression
282 will be FALSE. Otherwise, only the CURRENT_VALUE will be true.
284 NUM_VALUES is simply the length of the VALUES list and is there for
285 convenience.
287 Once the dimensions are created, the algorithm enumerates all possible
288 values and computes the current value of the given expression. */
290 struct dimension
292 struct attr_desc *attr; /* Attribute for this dimension. */
293 rtx values; /* List of attribute values used. */
294 rtx current_value; /* Position in the list for the TRUE value. */
295 int num_values; /* Length of the values list. */
298 /* Other variables. */
300 static int insn_code_number;
301 static int insn_index_number;
302 static int got_define_asm_attributes;
303 static int must_extract;
304 static int must_constrain;
305 static int address_used;
306 static int length_used;
307 static int num_delays;
308 static int have_annul_true, have_annul_false;
309 static int num_units;
310 static int num_insn_ents;
312 /* Used as operand to `operate_exp': */
314 enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, MAX_OP, MIN_OP, RANGE_OP};
316 /* Stores, for each insn code, the number of constraint alternatives. */
318 static int *insn_n_alternatives;
320 /* Stores, for each insn code, a bitmap that has bits on for each possible
321 alternative. */
323 static int *insn_alternatives;
325 /* If nonzero, assume that the `alternative' attr has this value.
326 This is the hashed, unique string for the numeral
327 whose value is chosen alternative. */
329 static char *current_alternative_string;
331 /* Used to simplify expressions. */
333 static rtx true_rtx, false_rtx;
335 /* Used to reduce calls to `strcmp' */
337 static char *alternative_name;
339 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
340 called. */
342 int reload_completed = 0;
344 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
345 to define it here. */
347 int optimize = 0;
349 /* Simplify an expression. Only call the routine if there is something to
350 simplify. */
351 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
352 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \
353 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
355 /* Simplify (eq_attr ("alternative") ...)
356 when we are working with a particular alternative. */
357 #define SIMPLIFY_ALTERNATIVE(EXP) \
358 if (current_alternative_string \
359 && GET_CODE ((EXP)) == EQ_ATTR \
360 && XSTR ((EXP), 0) == alternative_name) \
361 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
362 ? true_rtx : false_rtx);
364 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
365 They won't actually be used. */
367 rtx frame_pointer_rtx, hard_frame_pointer_rtx, stack_pointer_rtx;
368 rtx arg_pointer_rtx, pic_offset_table_rtx;
370 static rtx attr_rtx PVPROTO((enum rtx_code, ...));
371 #ifdef HAVE_VPRINTF
372 static char *attr_printf PVPROTO((int, char *, ...));
373 #else
374 static char *attr_printf ();
375 #endif
377 static char *attr_string PROTO((char *, int));
378 static rtx check_attr_test PROTO((rtx, int));
379 static rtx check_attr_value PROTO((rtx, struct attr_desc *));
380 static rtx convert_set_attr_alternative PROTO((rtx, int, int, int));
381 static rtx convert_set_attr PROTO((rtx, int, int, int));
382 static void check_defs PROTO((void));
383 static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *));
384 static rtx make_canonical PROTO((struct attr_desc *, rtx));
385 static struct attr_value *get_attr_value PROTO((rtx, struct attr_desc *, int));
386 static rtx copy_rtx_unchanging PROTO((rtx));
387 static rtx copy_boolean PROTO((rtx));
388 static void expand_delays PROTO((void));
389 static rtx operate_exp PROTO((enum operator, rtx, rtx));
390 static void expand_units PROTO((void));
391 static rtx simplify_knowing PROTO((rtx, rtx));
392 static rtx encode_units_mask PROTO((rtx));
393 static void fill_attr PROTO((struct attr_desc *));
394 /* dpx2 compiler chokes if we specify the arg types of the args. */
395 static rtx substitute_address PROTO((rtx, rtx (*) (), rtx (*) ()));
396 static void make_length_attrs PROTO((void));
397 static rtx identity_fn PROTO((rtx));
398 static rtx zero_fn PROTO((rtx));
399 static rtx one_fn PROTO((rtx));
400 static rtx max_fn PROTO((rtx));
401 static rtx simplify_cond PROTO((rtx, int, int));
402 #if 0
403 static rtx simplify_by_alternatives PROTO((rtx, int, int));
404 #endif
405 static rtx simplify_by_exploding PROTO((rtx));
406 static int find_and_mark_used_attributes PROTO((rtx, rtx *, int *));
407 static void unmark_used_attributes PROTO((rtx, struct dimension *, int));
408 static int add_values_to_cover PROTO((struct dimension *));
409 static int increment_current_value PROTO((struct dimension *, int));
410 static rtx test_for_current_value PROTO((struct dimension *, int));
411 static rtx simplify_with_current_value PROTO((rtx, struct dimension *, int));
412 static rtx simplify_with_current_value_aux PROTO((rtx));
413 static void clear_struct_flag PROTO((rtx));
414 static int count_sub_rtxs PROTO((rtx, int));
415 static void remove_insn_ent PROTO((struct attr_value *, struct insn_ent *));
416 static void insert_insn_ent PROTO((struct attr_value *, struct insn_ent *));
417 static rtx insert_right_side PROTO((enum rtx_code, rtx, rtx, int, int));
418 static rtx make_alternative_compare PROTO((int));
419 static int compute_alternative_mask PROTO((rtx, enum rtx_code));
420 static rtx evaluate_eq_attr PROTO((rtx, rtx, int, int));
421 static rtx simplify_and_tree PROTO((rtx, rtx *, int, int));
422 static rtx simplify_or_tree PROTO((rtx, rtx *, int, int));
423 static rtx simplify_test_exp PROTO((rtx, int, int));
424 static void optimize_attrs PROTO((void));
425 static void gen_attr PROTO((rtx));
426 static int count_alternatives PROTO((rtx));
427 static int compares_alternatives_p PROTO((rtx));
428 static int contained_in_p PROTO((rtx, rtx));
429 static void gen_insn PROTO((rtx));
430 static void gen_delay PROTO((rtx));
431 static void gen_unit PROTO((rtx));
432 static void write_test_expr PROTO((rtx, int));
433 static int max_attr_value PROTO((rtx));
434 static void walk_attr_value PROTO((rtx));
435 static void write_attr_get PROTO((struct attr_desc *));
436 static rtx eliminate_known_true PROTO((rtx, rtx, int, int));
437 static void write_attr_set PROTO((struct attr_desc *, int, rtx, char *,
438 char *, rtx, int, int));
439 static void write_attr_case PROTO((struct attr_desc *, struct attr_value *,
440 int, char *, char *, int, rtx));
441 static void write_attr_valueq PROTO((struct attr_desc *, char *));
442 static void write_attr_value PROTO((struct attr_desc *, rtx));
443 static void write_upcase PROTO((char *));
444 static void write_indent PROTO((int));
445 static void write_eligible_delay PROTO((char *));
446 static void write_function_unit_info PROTO((void));
447 static void write_complex_function PROTO((struct function_unit *, char *,
448 char *));
449 static int n_comma_elts PROTO((char *));
450 static char *next_comma_elt PROTO((char **));
451 static struct attr_desc *find_attr PROTO((char *, int));
452 static void make_internal_attr PROTO((char *, rtx, int));
453 static struct attr_value *find_most_used PROTO((struct attr_desc *));
454 static rtx find_single_value PROTO((struct attr_desc *));
455 static rtx make_numeric_value PROTO((int));
456 static void extend_range PROTO((struct range *, int, int));
457 char *xrealloc PROTO((char *, unsigned));
458 char *xmalloc PROTO((unsigned));
460 #define oballoc(size) obstack_alloc (hash_obstack, size)
463 /* Hash table for sharing RTL and strings. */
465 /* Each hash table slot is a bucket containing a chain of these structures.
466 Strings are given negative hash codes; RTL expressions are given positive
467 hash codes. */
469 struct attr_hash
471 struct attr_hash *next; /* Next structure in the bucket. */
472 int hashcode; /* Hash code of this rtx or string. */
473 union
475 char *str; /* The string (negative hash codes) */
476 rtx rtl; /* or the RTL recorded here. */
477 } u;
480 /* Now here is the hash table. When recording an RTL, it is added to
481 the slot whose index is the hash code mod the table size. Note
482 that the hash table is used for several kinds of RTL (see attr_rtx)
483 and for strings. While all these live in the same table, they are
484 completely independent, and the hash code is computed differently
485 for each. */
487 #define RTL_HASH_SIZE 4093
488 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
490 /* Here is how primitive or already-shared RTL's hash
491 codes are made. */
492 #define RTL_HASH(RTL) ((HOST_WIDE_INT) (RTL) & 0777777)
494 rtx pc_rtx;
496 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
498 static void
499 attr_hash_add_rtx (hashcode, rtl)
500 int hashcode;
501 rtx rtl;
503 register struct attr_hash *h;
505 h = (struct attr_hash *) obstack_alloc (hash_obstack,
506 sizeof (struct attr_hash));
507 h->hashcode = hashcode;
508 h->u.rtl = rtl;
509 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
510 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
513 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
515 static void
516 attr_hash_add_string (hashcode, str)
517 int hashcode;
518 char *str;
520 register struct attr_hash *h;
522 h = (struct attr_hash *) obstack_alloc (hash_obstack,
523 sizeof (struct attr_hash));
524 h->hashcode = -hashcode;
525 h->u.str = str;
526 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
527 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
530 /* Generate an RTL expression, but avoid duplicates.
531 Set the RTX_INTEGRATED_P flag for these permanent objects.
533 In some cases we cannot uniquify; then we return an ordinary
534 impermanent rtx with RTX_INTEGRATED_P clear.
536 Args are like gen_rtx, but without the mode:
538 rtx attr_rtx (code, [element1, ..., elementn]) */
540 /*VARARGS1*/
541 static rtx
542 attr_rtx VPROTO((enum rtx_code code, ...))
544 #ifndef ANSI_PROTOTYPES
545 enum rtx_code code;
546 #endif
547 va_list p;
548 register int i; /* Array indices... */
549 register char *fmt; /* Current rtx's format... */
550 register rtx rt_val; /* RTX to return to caller... */
551 int hashcode;
552 register struct attr_hash *h;
553 struct obstack *old_obstack = rtl_obstack;
555 VA_START (p, code);
557 #ifndef ANSI_PROTOTYPES
558 code = va_arg (p, enum rtx_code);
559 #endif
561 /* For each of several cases, search the hash table for an existing entry.
562 Use that entry if one is found; otherwise create a new RTL and add it
563 to the table. */
565 if (GET_RTX_CLASS (code) == '1')
567 rtx arg0 = va_arg (p, rtx);
569 /* A permanent object cannot point to impermanent ones. */
570 if (! RTX_INTEGRATED_P (arg0))
572 rt_val = rtx_alloc (code);
573 XEXP (rt_val, 0) = arg0;
574 va_end (p);
575 return rt_val;
578 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
579 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
580 if (h->hashcode == hashcode
581 && GET_CODE (h->u.rtl) == code
582 && XEXP (h->u.rtl, 0) == arg0)
583 goto found;
585 if (h == 0)
587 rtl_obstack = hash_obstack;
588 rt_val = rtx_alloc (code);
589 XEXP (rt_val, 0) = arg0;
592 else if (GET_RTX_CLASS (code) == 'c'
593 || GET_RTX_CLASS (code) == '2'
594 || GET_RTX_CLASS (code) == '<')
596 rtx arg0 = va_arg (p, rtx);
597 rtx arg1 = va_arg (p, rtx);
599 /* A permanent object cannot point to impermanent ones. */
600 if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1))
602 rt_val = rtx_alloc (code);
603 XEXP (rt_val, 0) = arg0;
604 XEXP (rt_val, 1) = arg1;
605 va_end (p);
606 return rt_val;
609 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
610 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
611 if (h->hashcode == hashcode
612 && GET_CODE (h->u.rtl) == code
613 && XEXP (h->u.rtl, 0) == arg0
614 && XEXP (h->u.rtl, 1) == arg1)
615 goto found;
617 if (h == 0)
619 rtl_obstack = hash_obstack;
620 rt_val = rtx_alloc (code);
621 XEXP (rt_val, 0) = arg0;
622 XEXP (rt_val, 1) = arg1;
625 else if (GET_RTX_LENGTH (code) == 1
626 && GET_RTX_FORMAT (code)[0] == 's')
628 char * arg0 = va_arg (p, char *);
630 if (code == SYMBOL_REF)
631 arg0 = attr_string (arg0, strlen (arg0));
633 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0));
634 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
635 if (h->hashcode == hashcode
636 && GET_CODE (h->u.rtl) == code
637 && XSTR (h->u.rtl, 0) == arg0)
638 goto found;
640 if (h == 0)
642 rtl_obstack = hash_obstack;
643 rt_val = rtx_alloc (code);
644 XSTR (rt_val, 0) = arg0;
647 else if (GET_RTX_LENGTH (code) == 2
648 && GET_RTX_FORMAT (code)[0] == 's'
649 && GET_RTX_FORMAT (code)[1] == 's')
651 char *arg0 = va_arg (p, char *);
652 char *arg1 = va_arg (p, char *);
654 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1));
655 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
656 if (h->hashcode == hashcode
657 && GET_CODE (h->u.rtl) == code
658 && XSTR (h->u.rtl, 0) == arg0
659 && XSTR (h->u.rtl, 1) == arg1)
660 goto found;
662 if (h == 0)
664 rtl_obstack = hash_obstack;
665 rt_val = rtx_alloc (code);
666 XSTR (rt_val, 0) = arg0;
667 XSTR (rt_val, 1) = arg1;
670 else if (code == CONST_INT)
672 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT);
673 if (arg0 == 0)
674 return false_rtx;
675 if (arg0 == 1)
676 return true_rtx;
677 goto nohash;
679 else
681 nohash:
682 rt_val = rtx_alloc (code); /* Allocate the storage space. */
684 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
685 for (i = 0; i < GET_RTX_LENGTH (code); i++)
687 switch (*fmt++)
689 case '0': /* Unused field. */
690 break;
692 case 'i': /* An integer? */
693 XINT (rt_val, i) = va_arg (p, int);
694 break;
696 case 'w': /* A wide integer? */
697 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT);
698 break;
700 case 's': /* A string? */
701 XSTR (rt_val, i) = va_arg (p, char *);
702 break;
704 case 'e': /* An expression? */
705 case 'u': /* An insn? Same except when printing. */
706 XEXP (rt_val, i) = va_arg (p, rtx);
707 break;
709 case 'E': /* An RTX vector? */
710 XVEC (rt_val, i) = va_arg (p, rtvec);
711 break;
713 default:
714 abort();
717 va_end (p);
718 return rt_val;
721 rtl_obstack = old_obstack;
722 va_end (p);
723 attr_hash_add_rtx (hashcode, rt_val);
724 RTX_INTEGRATED_P (rt_val) = 1;
725 return rt_val;
727 found:
728 va_end (p);
729 return h->u.rtl;
732 /* Create a new string printed with the printf line arguments into a space
733 of at most LEN bytes:
735 rtx attr_printf (len, format, [arg1, ..., argn]) */
737 #ifdef HAVE_VPRINTF
739 /*VARARGS2*/
740 static char *
741 attr_printf VPROTO((register int len, char *fmt, ...))
743 #ifndef ANSI_PROTOTYPES
744 register int len;
745 char *fmt;
746 #endif
747 va_list p;
748 register char *str;
750 VA_START (p, fmt);
752 #ifndef ANSI_PROTOTYPES
753 len = va_arg (p, int);
754 fmt = va_arg (p, char *);
755 #endif
757 /* Print the string into a temporary location. */
758 str = (char *) alloca (len);
759 vsprintf (str, fmt, p);
760 va_end (p);
762 return attr_string (str, strlen (str));
765 #else /* not HAVE_VPRINTF */
767 static char *
768 attr_printf (len, fmt, arg1, arg2, arg3)
769 int len;
770 char *fmt;
771 char *arg1, *arg2, *arg3; /* also int */
773 register char *str;
775 /* Print the string into a temporary location. */
776 str = (char *) alloca (len);
777 sprintf (str, fmt, arg1, arg2, arg3);
779 return attr_string (str, strlen (str));
781 #endif /* not HAVE_VPRINTF */
784 attr_eq (name, value)
785 char *name, *value;
787 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)),
788 attr_string (value, strlen (value)));
791 char *
792 attr_numeral (n)
793 int n;
795 return XSTR (make_numeric_value (n), 0);
798 /* Return a permanent (possibly shared) copy of a string STR (not assumed
799 to be null terminated) with LEN bytes. */
801 static char *
802 attr_string (str, len)
803 char *str;
804 int len;
806 register struct attr_hash *h;
807 int hashcode;
808 int i;
809 register char *new_str;
811 /* Compute the hash code. */
812 hashcode = (len + 1) * 613 + (unsigned)str[0];
813 for (i = 1; i <= len; i += 2)
814 hashcode = ((hashcode * 613) + (unsigned)str[i]);
815 if (hashcode < 0)
816 hashcode = -hashcode;
818 /* Search the table for the string. */
819 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
820 if (h->hashcode == -hashcode && h->u.str[0] == str[0]
821 && !strncmp (h->u.str, str, len))
822 return h->u.str; /* <-- return if found. */
824 /* Not found; create a permanent copy and add it to the hash table. */
825 new_str = (char *) obstack_alloc (hash_obstack, len + 1);
826 bcopy (str, new_str, len);
827 new_str[len] = '\0';
828 attr_hash_add_string (hashcode, new_str);
830 return new_str; /* Return the new string. */
833 /* Check two rtx's for equality of contents,
834 taking advantage of the fact that if both are hashed
835 then they can't be equal unless they are the same object. */
838 attr_equal_p (x, y)
839 rtx x, y;
841 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y))
842 && rtx_equal_p (x, y)));
845 /* Copy an attribute value expression,
846 descending to all depths, but not copying any
847 permanent hashed subexpressions. */
850 attr_copy_rtx (orig)
851 register rtx orig;
853 register rtx copy;
854 register int i, j;
855 register RTX_CODE code;
856 register char *format_ptr;
858 /* No need to copy a permanent object. */
859 if (RTX_INTEGRATED_P (orig))
860 return orig;
862 code = GET_CODE (orig);
864 switch (code)
866 case REG:
867 case QUEUED:
868 case CONST_INT:
869 case CONST_DOUBLE:
870 case SYMBOL_REF:
871 case CODE_LABEL:
872 case PC:
873 case CC0:
874 return orig;
876 default:
877 break;
880 copy = rtx_alloc (code);
881 PUT_MODE (copy, GET_MODE (orig));
882 copy->in_struct = orig->in_struct;
883 copy->volatil = orig->volatil;
884 copy->unchanging = orig->unchanging;
885 copy->integrated = orig->integrated;
887 format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
889 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
891 switch (*format_ptr++)
893 case 'e':
894 XEXP (copy, i) = XEXP (orig, i);
895 if (XEXP (orig, i) != NULL)
896 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i));
897 break;
899 case 'E':
900 case 'V':
901 XVEC (copy, i) = XVEC (orig, i);
902 if (XVEC (orig, i) != NULL)
904 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
905 for (j = 0; j < XVECLEN (copy, i); j++)
906 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j));
908 break;
910 case 'n':
911 case 'i':
912 XINT (copy, i) = XINT (orig, i);
913 break;
915 case 'w':
916 XWINT (copy, i) = XWINT (orig, i);
917 break;
919 case 's':
920 case 'S':
921 XSTR (copy, i) = XSTR (orig, i);
922 break;
924 default:
925 abort ();
928 return copy;
931 /* Given a test expression for an attribute, ensure it is validly formed.
932 IS_CONST indicates whether the expression is constant for each compiler
933 run (a constant expression may not test any particular insn).
935 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
936 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
937 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
939 Update the string address in EQ_ATTR expression to be the same used
940 in the attribute (or `alternative_name') to speed up subsequent
941 `find_attr' calls and eliminate most `strcmp' calls.
943 Return the new expression, if any. */
945 static rtx
946 check_attr_test (exp, is_const)
947 rtx exp;
948 int is_const;
950 struct attr_desc *attr;
951 struct attr_value *av;
952 char *name_ptr, *p;
953 rtx orexp, newexp;
955 switch (GET_CODE (exp))
957 case EQ_ATTR:
958 /* Handle negation test. */
959 if (XSTR (exp, 1)[0] == '!')
960 return check_attr_test (attr_rtx (NOT,
961 attr_eq (XSTR (exp, 0),
962 &XSTR (exp, 1)[1])),
963 is_const);
965 else if (n_comma_elts (XSTR (exp, 1)) == 1)
967 attr = find_attr (XSTR (exp, 0), 0);
968 if (attr == NULL)
970 if (! strcmp (XSTR (exp, 0), "alternative"))
972 XSTR (exp, 0) = alternative_name;
973 /* This can't be simplified any further. */
974 RTX_UNCHANGING_P (exp) = 1;
975 return exp;
977 else
978 fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp, 0));
981 if (is_const && ! attr->is_const)
982 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
983 XEXP (exp, 0));
985 /* Copy this just to make it permanent,
986 so expressions using it can be permanent too. */
987 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1));
989 /* It shouldn't be possible to simplify the value given to a
990 constant attribute, so don't expand this until it's time to
991 write the test expression. */
992 if (attr->is_const)
993 RTX_UNCHANGING_P (exp) = 1;
995 if (attr->is_numeric)
997 for (p = XSTR (exp, 1); *p; p++)
998 if (*p < '0' || *p > '9')
999 fatal ("Attribute `%s' takes only numeric values",
1000 XEXP (exp, 0));
1002 else
1004 for (av = attr->first_value; av; av = av->next)
1005 if (GET_CODE (av->value) == CONST_STRING
1006 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
1007 break;
1009 if (av == NULL)
1010 fatal ("Unknown value `%s' for `%s' attribute",
1011 XEXP (exp, 1), XEXP (exp, 0));
1014 else
1016 /* Make an IOR tree of the possible values. */
1017 orexp = false_rtx;
1018 name_ptr = XSTR (exp, 1);
1019 while ((p = next_comma_elt (&name_ptr)) != NULL)
1021 newexp = attr_eq (XSTR (exp, 0), p);
1022 orexp = insert_right_side (IOR, orexp, newexp, -2, -2);
1025 return check_attr_test (orexp, is_const);
1027 break;
1029 case ATTR_FLAG:
1030 break;
1032 case CONST_INT:
1033 /* Either TRUE or FALSE. */
1034 if (XWINT (exp, 0))
1035 return true_rtx;
1036 else
1037 return false_rtx;
1039 case IOR:
1040 case AND:
1041 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
1042 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const);
1043 break;
1045 case NOT:
1046 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
1047 break;
1049 case MATCH_OPERAND:
1050 if (is_const)
1051 fatal ("RTL operator \"%s\" not valid in constant attribute test",
1052 GET_RTX_NAME (MATCH_OPERAND));
1053 /* These cases can't be simplified. */
1054 RTX_UNCHANGING_P (exp) = 1;
1055 break;
1057 case LE: case LT: case GT: case GE:
1058 case LEU: case LTU: case GTU: case GEU:
1059 case NE: case EQ:
1060 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF
1061 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF)
1062 exp = attr_rtx (GET_CODE (exp),
1063 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)),
1064 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0)));
1065 /* These cases can't be simplified. */
1066 RTX_UNCHANGING_P (exp) = 1;
1067 break;
1069 case SYMBOL_REF:
1070 if (is_const)
1072 /* These cases are valid for constant attributes, but can't be
1073 simplified. */
1074 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1075 RTX_UNCHANGING_P (exp) = 1;
1076 break;
1078 default:
1079 fatal ("RTL operator \"%s\" not valid in attribute test",
1080 GET_RTX_NAME (GET_CODE (exp)));
1083 return exp;
1086 /* Given an expression, ensure that it is validly formed and that all named
1087 attribute values are valid for the given attribute. Issue a fatal error
1088 if not. If no attribute is specified, assume a numeric attribute.
1090 Return a perhaps modified replacement expression for the value. */
1092 static rtx
1093 check_attr_value (exp, attr)
1094 rtx exp;
1095 struct attr_desc *attr;
1097 struct attr_value *av;
1098 char *p;
1099 int i;
1101 switch (GET_CODE (exp))
1103 case CONST_INT:
1104 if (attr && ! attr->is_numeric)
1105 fatal ("CONST_INT not valid for non-numeric `%s' attribute",
1106 attr->name);
1108 if (INTVAL (exp) < 0)
1109 fatal ("Negative numeric value specified for `%s' attribute",
1110 attr->name);
1112 break;
1114 case CONST_STRING:
1115 if (! strcmp (XSTR (exp, 0), "*"))
1116 break;
1118 if (attr == 0 || attr->is_numeric)
1120 p = XSTR (exp, 0);
1121 if (attr && attr->negative_ok && *p == '-')
1122 p++;
1123 for (; *p; p++)
1124 if (*p > '9' || *p < '0')
1125 fatal ("Non-numeric value for numeric `%s' attribute",
1126 attr ? attr->name : "internal");
1127 break;
1130 for (av = attr->first_value; av; av = av->next)
1131 if (GET_CODE (av->value) == CONST_STRING
1132 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
1133 break;
1135 if (av == NULL)
1136 fatal ("Unknown value `%s' for `%s' attribute",
1137 XSTR (exp, 0), attr ? attr->name : "internal");
1139 break;
1141 case IF_THEN_ELSE:
1142 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
1143 attr ? attr->is_const : 0);
1144 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1145 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
1146 break;
1148 case COND:
1149 if (XVECLEN (exp, 0) % 2 != 0)
1150 fatal ("First operand of COND must have even length");
1152 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1154 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
1155 attr ? attr->is_const : 0);
1156 XVECEXP (exp, 0, i + 1)
1157 = check_attr_value (XVECEXP (exp, 0, i + 1), attr);
1160 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr);
1161 break;
1163 case SYMBOL_REF:
1164 if (attr && attr->is_const)
1165 /* A constant SYMBOL_REF is valid as a constant attribute test and
1166 is expanded later by make_canonical into a COND. */
1167 return attr_rtx (SYMBOL_REF, XSTR (exp, 0));
1168 /* Otherwise, fall through... */
1170 default:
1171 fatal ("Invalid operation `%s' for attribute value",
1172 GET_RTX_NAME (GET_CODE (exp)));
1175 return exp;
1178 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1179 It becomes a COND with each test being (eq_attr "alternative "n") */
1181 static rtx
1182 convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
1183 rtx exp;
1184 int num_alt;
1185 int insn_code, insn_index;
1187 rtx condexp;
1188 int i;
1190 if (XVECLEN (exp, 1) != num_alt)
1191 fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
1192 insn_index);
1194 /* Make a COND with all tests but the last. Select the last value via the
1195 default. */
1196 condexp = rtx_alloc (COND);
1197 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1199 for (i = 0; i < num_alt - 1; i++)
1201 char *p;
1202 p = attr_numeral (i);
1204 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p);
1205 #if 0
1206 /* Sharing this EQ_ATTR rtl causes trouble. */
1207 XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
1208 XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
1209 XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p;
1210 #endif
1211 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
1214 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
1216 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
1219 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1220 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1222 static rtx
1223 convert_set_attr (exp, num_alt, insn_code, insn_index)
1224 rtx exp;
1225 int num_alt;
1226 int insn_code, insn_index;
1228 rtx newexp;
1229 char *name_ptr;
1230 char *p;
1231 int n;
1233 /* See how many alternative specified. */
1234 n = n_comma_elts (XSTR (exp, 1));
1235 if (n == 1)
1236 return attr_rtx (SET,
1237 attr_rtx (ATTR, XSTR (exp, 0)),
1238 attr_rtx (CONST_STRING, XSTR (exp, 1)));
1240 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
1241 XSTR (newexp, 0) = XSTR (exp, 0);
1242 XVEC (newexp, 1) = rtvec_alloc (n);
1244 /* Process each comma-separated name. */
1245 name_ptr = XSTR (exp, 1);
1246 n = 0;
1247 while ((p = next_comma_elt (&name_ptr)) != NULL)
1248 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
1250 return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
1253 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1254 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1255 expressions. */
1257 static void
1258 check_defs ()
1260 struct insn_def *id;
1261 struct attr_desc *attr;
1262 int i;
1263 rtx value;
1265 for (id = defs; id; id = id->next)
1267 if (XVEC (id->def, id->vec_idx) == NULL)
1268 continue;
1270 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1272 value = XVECEXP (id->def, id->vec_idx, i);
1273 switch (GET_CODE (value))
1275 case SET:
1276 if (GET_CODE (XEXP (value, 0)) != ATTR)
1277 fatal ("Bad attribute set in pattern %d", id->insn_index);
1278 break;
1280 case SET_ATTR_ALTERNATIVE:
1281 value = convert_set_attr_alternative (value,
1282 id->num_alternatives,
1283 id->insn_code,
1284 id->insn_index);
1285 break;
1287 case SET_ATTR:
1288 value = convert_set_attr (value, id->num_alternatives,
1289 id->insn_code, id->insn_index);
1290 break;
1292 default:
1293 fatal ("Invalid attribute code `%s' for pattern %d",
1294 GET_RTX_NAME (GET_CODE (value)), id->insn_index);
1297 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
1298 fatal ("Unknown attribute `%s' for pattern number %d",
1299 XSTR (XEXP (value, 0), 0), id->insn_index);
1301 XVECEXP (id->def, id->vec_idx, i) = value;
1302 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr);
1307 /* Given a constant SYMBOL_REF expression, convert to a COND that
1308 explicitly tests each enumerated value. */
1310 static rtx
1311 convert_const_symbol_ref (exp, attr)
1312 rtx exp;
1313 struct attr_desc *attr;
1315 rtx condexp;
1316 struct attr_value *av;
1317 int i;
1318 int num_alt = 0;
1320 for (av = attr->first_value; av; av = av->next)
1321 num_alt++;
1323 /* Make a COND with all tests but the last, and in the original order.
1324 Select the last value via the default. Note that the attr values
1325 are constructed in reverse order. */
1327 condexp = rtx_alloc (COND);
1328 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
1329 av = attr->first_value;
1330 XEXP (condexp, 1) = av->value;
1332 for (i = num_alt - 2; av = av->next, i >= 0; i--)
1334 char *p, *string;
1335 rtx value;
1337 string = p = (char *) oballoc (2
1338 + strlen (attr->name)
1339 + strlen (XSTR (av->value, 0)));
1340 strcpy (p, attr->name);
1341 strcat (p, "_");
1342 strcat (p, XSTR (av->value, 0));
1343 for (; *p != '\0'; p++)
1344 if (*p >= 'a' && *p <= 'z')
1345 *p -= 'a' - 'A';
1347 value = attr_rtx (SYMBOL_REF, string);
1348 RTX_UNCHANGING_P (value) = 1;
1350 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value);
1352 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1355 return condexp;
1358 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1359 expressions by converting them into a COND. This removes cases from this
1360 program. Also, replace an attribute value of "*" with the default attribute
1361 value. */
1363 static rtx
1364 make_canonical (attr, exp)
1365 struct attr_desc *attr;
1366 rtx exp;
1368 int i;
1369 rtx newexp;
1371 switch (GET_CODE (exp))
1373 case CONST_INT:
1374 exp = make_numeric_value (INTVAL (exp));
1375 break;
1377 case CONST_STRING:
1378 if (! strcmp (XSTR (exp, 0), "*"))
1380 if (attr == 0 || attr->default_val == 0)
1381 fatal ("(attr_value \"*\") used in invalid context.");
1382 exp = attr->default_val->value;
1385 break;
1387 case SYMBOL_REF:
1388 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1389 break;
1390 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1391 This makes the COND something that won't be considered an arbitrary
1392 expression by walk_attr_value. */
1393 RTX_UNCHANGING_P (exp) = 1;
1394 exp = convert_const_symbol_ref (exp, attr);
1395 RTX_UNCHANGING_P (exp) = 1;
1396 exp = check_attr_value (exp, attr);
1397 /* Goto COND case since this is now a COND. Note that while the
1398 new expression is rescanned, all symbol_ref notes are marked as
1399 unchanging. */
1400 goto cond;
1402 case IF_THEN_ELSE:
1403 newexp = rtx_alloc (COND);
1404 XVEC (newexp, 0) = rtvec_alloc (2);
1405 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1406 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1408 XEXP (newexp, 1) = XEXP (exp, 2);
1410 exp = newexp;
1411 /* Fall through to COND case since this is now a COND. */
1413 case COND:
1414 cond:
1416 int allsame = 1;
1417 rtx defval;
1419 /* First, check for degenerate COND. */
1420 if (XVECLEN (exp, 0) == 0)
1421 return make_canonical (attr, XEXP (exp, 1));
1422 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1424 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1426 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i));
1427 XVECEXP (exp, 0, i + 1)
1428 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1429 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval))
1430 allsame = 0;
1432 if (allsame)
1433 return defval;
1435 break;
1437 default:
1438 break;
1441 return exp;
1444 static rtx
1445 copy_boolean (exp)
1446 rtx exp;
1448 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR)
1449 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)),
1450 copy_boolean (XEXP (exp, 1)));
1451 return exp;
1454 /* Given a value and an attribute description, return a `struct attr_value *'
1455 that represents that value. This is either an existing structure, if the
1456 value has been previously encountered, or a newly-created structure.
1458 `insn_code' is the code of an insn whose attribute has the specified
1459 value (-2 if not processing an insn). We ensure that all insns for
1460 a given value have the same number of alternatives if the value checks
1461 alternatives. */
1463 static struct attr_value *
1464 get_attr_value (value, attr, insn_code)
1465 rtx value;
1466 struct attr_desc *attr;
1467 int insn_code;
1469 struct attr_value *av;
1470 int num_alt = 0;
1472 value = make_canonical (attr, value);
1473 if (compares_alternatives_p (value))
1475 if (insn_code < 0 || insn_alternatives == NULL)
1476 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1477 else
1478 num_alt = insn_alternatives[insn_code];
1481 for (av = attr->first_value; av; av = av->next)
1482 if (rtx_equal_p (value, av->value)
1483 && (num_alt == 0 || av->first_insn == NULL
1484 || insn_alternatives[av->first_insn->insn_code]))
1485 return av;
1487 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
1488 av->value = value;
1489 av->next = attr->first_value;
1490 attr->first_value = av;
1491 av->first_insn = NULL;
1492 av->num_insns = 0;
1493 av->has_asm_insn = 0;
1495 return av;
1498 /* After all DEFINE_DELAYs have been read in, create internal attributes
1499 to generate the required routines.
1501 First, we compute the number of delay slots for each insn (as a COND of
1502 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1503 delay type is specified, we compute a similar function giving the
1504 DEFINE_DELAY ordinal for each insn.
1506 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1507 tells whether a given insn can be in that delay slot.
1509 Normal attribute filling and optimization expands these to contain the
1510 information needed to handle delay slots. */
1512 static void
1513 expand_delays ()
1515 struct delay_desc *delay;
1516 rtx condexp;
1517 rtx newexp;
1518 int i;
1519 char *p;
1521 /* First, generate data for `num_delay_slots' function. */
1523 condexp = rtx_alloc (COND);
1524 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1525 XEXP (condexp, 1) = make_numeric_value (0);
1527 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1529 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1530 XVECEXP (condexp, 0, i + 1)
1531 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1534 make_internal_attr ("*num_delay_slots", condexp, 0);
1536 /* If more than one delay type, do the same for computing the delay type. */
1537 if (num_delays > 1)
1539 condexp = rtx_alloc (COND);
1540 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1541 XEXP (condexp, 1) = make_numeric_value (0);
1543 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1545 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1546 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1549 make_internal_attr ("*delay_type", condexp, 1);
1552 /* For each delay possibility and delay slot, compute an eligibility
1553 attribute for non-annulled insns and for each type of annulled (annul
1554 if true and annul if false). */
1555 for (delay = delays; delay; delay = delay->next)
1557 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1559 condexp = XVECEXP (delay->def, 1, i);
1560 if (condexp == 0) condexp = false_rtx;
1561 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1562 make_numeric_value (1), make_numeric_value (0));
1564 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS*2, "*delay_%d_%d",
1565 delay->num, i / 3);
1566 make_internal_attr (p, newexp, 1);
1568 if (have_annul_true)
1570 condexp = XVECEXP (delay->def, 1, i + 1);
1571 if (condexp == 0) condexp = false_rtx;
1572 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1573 make_numeric_value (1),
1574 make_numeric_value (0));
1575 p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS*2,
1576 "*annul_true_%d_%d", delay->num, i / 3);
1577 make_internal_attr (p, newexp, 1);
1580 if (have_annul_false)
1582 condexp = XVECEXP (delay->def, 1, i + 2);
1583 if (condexp == 0) condexp = false_rtx;
1584 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1585 make_numeric_value (1),
1586 make_numeric_value (0));
1587 p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS*2,
1588 "*annul_false_%d_%d", delay->num, i / 3);
1589 make_internal_attr (p, newexp, 1);
1595 /* This function is given a left and right side expression and an operator.
1596 Each side is a conditional expression, each alternative of which has a
1597 numerical value. The function returns another conditional expression
1598 which, for every possible set of condition values, returns a value that is
1599 the operator applied to the values of the two sides.
1601 Since this is called early, it must also support IF_THEN_ELSE. */
1603 static rtx
1604 operate_exp (op, left, right)
1605 enum operator op;
1606 rtx left, right;
1608 int left_value, right_value;
1609 rtx newexp;
1610 int i;
1612 /* If left is a string, apply operator to it and the right side. */
1613 if (GET_CODE (left) == CONST_STRING)
1615 /* If right is also a string, just perform the operation. */
1616 if (GET_CODE (right) == CONST_STRING)
1618 left_value = atoi (XSTR (left, 0));
1619 right_value = atoi (XSTR (right, 0));
1620 switch (op)
1622 case PLUS_OP:
1623 i = left_value + right_value;
1624 break;
1626 case MINUS_OP:
1627 i = left_value - right_value;
1628 break;
1630 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */
1631 if (left_value > right_value)
1632 i = left_value - right_value;
1633 else
1634 i = 0;
1635 break;
1637 case OR_OP:
1638 i = left_value | right_value;
1639 break;
1641 case EQ_OP:
1642 i = left_value == right_value;
1643 break;
1645 case RANGE_OP:
1646 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value;
1647 break;
1649 case MAX_OP:
1650 if (left_value > right_value)
1651 i = left_value;
1652 else
1653 i = right_value;
1654 break;
1656 case MIN_OP:
1657 if (left_value < right_value)
1658 i = left_value;
1659 else
1660 i = right_value;
1661 break;
1663 default:
1664 abort ();
1667 return make_numeric_value (i);
1669 else if (GET_CODE (right) == IF_THEN_ELSE)
1671 /* Apply recursively to all values within. */
1672 rtx newleft = operate_exp (op, left, XEXP (right, 1));
1673 rtx newright = operate_exp (op, left, XEXP (right, 2));
1674 if (rtx_equal_p (newleft, newright))
1675 return newleft;
1676 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright);
1678 else if (GET_CODE (right) == COND)
1680 int allsame = 1;
1681 rtx defval;
1683 newexp = rtx_alloc (COND);
1684 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1685 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1687 for (i = 0; i < XVECLEN (right, 0); i += 2)
1689 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1690 XVECEXP (newexp, 0, i + 1)
1691 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1692 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1693 defval))
1694 allsame = 0;
1697 /* If the resulting cond is trivial (all alternatives
1698 give the same value), optimize it away. */
1699 if (allsame)
1701 obstack_free (rtl_obstack, newexp);
1702 return operate_exp (op, left, XEXP (right, 1));
1705 /* If the result is the same as the RIGHT operand,
1706 just use that. */
1707 if (rtx_equal_p (newexp, right))
1709 obstack_free (rtl_obstack, newexp);
1710 return right;
1713 return newexp;
1715 else
1716 fatal ("Badly formed attribute value");
1719 /* Otherwise, do recursion the other way. */
1720 else if (GET_CODE (left) == IF_THEN_ELSE)
1722 rtx newleft = operate_exp (op, XEXP (left, 1), right);
1723 rtx newright = operate_exp (op, XEXP (left, 2), right);
1724 if (rtx_equal_p (newleft, newright))
1725 return newleft;
1726 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright);
1728 else if (GET_CODE (left) == COND)
1730 int allsame = 1;
1731 rtx defval;
1733 newexp = rtx_alloc (COND);
1734 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1735 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1737 for (i = 0; i < XVECLEN (left, 0); i += 2)
1739 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1740 XVECEXP (newexp, 0, i + 1)
1741 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1742 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1),
1743 defval))
1744 allsame = 0;
1747 /* If the cond is trivial (all alternatives give the same value),
1748 optimize it away. */
1749 if (allsame)
1751 obstack_free (rtl_obstack, newexp);
1752 return operate_exp (op, XEXP (left, 1), right);
1755 /* If the result is the same as the LEFT operand,
1756 just use that. */
1757 if (rtx_equal_p (newexp, left))
1759 obstack_free (rtl_obstack, newexp);
1760 return left;
1763 return newexp;
1766 else
1767 fatal ("Badly formed attribute value.");
1768 /* NOTREACHED */
1769 return NULL;
1772 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1773 construct a number of attributes.
1775 The first produces a function `function_units_used' which is given an
1776 insn and produces an encoding showing which function units are required
1777 for the execution of that insn. If the value is non-negative, the insn
1778 uses that unit; otherwise, the value is a one's compliment mask of units
1779 used.
1781 The second produces a function `result_ready_cost' which is used to
1782 determine the time that the result of an insn will be ready and hence
1783 a worst-case schedule.
1785 Both of these produce quite complex expressions which are then set as the
1786 default value of internal attributes. Normal attribute simplification
1787 should produce reasonable expressions.
1789 For each unit, a `<name>_unit_ready_cost' function will take an
1790 insn and give the delay until that unit will be ready with the result
1791 and a `<name>_unit_conflict_cost' function is given an insn already
1792 executing on the unit and a candidate to execute and will give the
1793 cost from the time the executing insn started until the candidate
1794 can start (ignore limitations on the number of simultaneous insns).
1796 For each unit, a `<name>_unit_blockage' function is given an insn
1797 already executing on the unit and a candidate to execute and will
1798 give the delay incurred due to function unit conflicts. The range of
1799 blockage cost values for a given executing insn is given by the
1800 `<name>_unit_blockage_range' function. These values are encoded in
1801 an int where the upper half gives the minimum value and the lower
1802 half gives the maximum value. */
1804 static void
1805 expand_units ()
1807 struct function_unit *unit, **unit_num;
1808 struct function_unit_op *op, **op_array, ***unit_ops;
1809 rtx unitsmask;
1810 rtx readycost;
1811 rtx newexp;
1812 char *str;
1813 int i, j, u, num, nvalues;
1815 /* Rebuild the condition for the unit to share the RTL expressions.
1816 Sharing is required by simplify_by_exploding. Build the issue delay
1817 expressions. Validate the expressions we were given for the conditions
1818 and conflict vector. Then make attributes for use in the conflict
1819 function. */
1821 for (unit = units; unit; unit = unit->next)
1823 unit->condexp = check_attr_test (unit->condexp, 0);
1825 for (op = unit->ops; op; op = op->next)
1827 rtx issue_delay = make_numeric_value (op->issue_delay);
1828 rtx issue_exp = issue_delay;
1830 /* Build, validate, and simplify the issue delay expression. */
1831 if (op->conflict_exp != true_rtx)
1832 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp,
1833 issue_exp, make_numeric_value (0));
1834 issue_exp = check_attr_value (make_canonical (NULL_ATTR,
1835 issue_exp),
1836 NULL_ATTR);
1837 issue_exp = simplify_knowing (issue_exp, unit->condexp);
1838 op->issue_exp = issue_exp;
1840 /* Make an attribute for use in the conflict function if needed. */
1841 unit->needs_conflict_function = (unit->issue_delay.min
1842 != unit->issue_delay.max);
1843 if (unit->needs_conflict_function)
1845 str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS,
1846 "*%s_cost_%d", unit->name, op->num);
1847 make_internal_attr (str, issue_exp, 1);
1850 /* Validate the condition. */
1851 op->condexp = check_attr_test (op->condexp, 0);
1855 /* Compute the mask of function units used. Initially, the unitsmask is
1856 zero. Set up a conditional to compute each unit's contribution. */
1857 unitsmask = make_numeric_value (0);
1858 newexp = rtx_alloc (IF_THEN_ELSE);
1859 XEXP (newexp, 2) = make_numeric_value (0);
1861 /* Merge each function unit into the unit mask attributes. */
1862 for (unit = units; unit; unit = unit->next)
1864 XEXP (newexp, 0) = unit->condexp;
1865 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1866 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1869 /* Simplify the unit mask expression, encode it, and make an attribute
1870 for the function_units_used function. */
1871 unitsmask = simplify_by_exploding (unitsmask);
1872 unitsmask = encode_units_mask (unitsmask);
1873 make_internal_attr ("*function_units_used", unitsmask, 2);
1875 /* Create an array of ops for each unit. Add an extra unit for the
1876 result_ready_cost function that has the ops of all other units. */
1877 unit_ops = (struct function_unit_op ***)
1878 alloca ((num_units + 1) * sizeof (struct function_unit_op **));
1879 unit_num = (struct function_unit **)
1880 alloca ((num_units + 1) * sizeof (struct function_unit *));
1882 unit_num[num_units] = unit = (struct function_unit *)
1883 alloca (sizeof (struct function_unit));
1884 unit->num = num_units;
1885 unit->num_opclasses = 0;
1887 for (unit = units; unit; unit = unit->next)
1889 unit_num[num_units]->num_opclasses += unit->num_opclasses;
1890 unit_num[unit->num] = unit;
1891 unit_ops[unit->num] = op_array = (struct function_unit_op **)
1892 alloca (unit->num_opclasses * sizeof (struct function_unit_op *));
1894 for (op = unit->ops; op; op = op->next)
1895 op_array[op->num] = op;
1898 /* Compose the array of ops for the extra unit. */
1899 unit_ops[num_units] = op_array = (struct function_unit_op **)
1900 alloca (unit_num[num_units]->num_opclasses
1901 * sizeof (struct function_unit_op *));
1903 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next)
1904 bcopy ((char *) unit_ops[unit->num], (char *) &op_array[i],
1905 unit->num_opclasses * sizeof (struct function_unit_op *));
1907 /* Compute the ready cost function for each unit by computing the
1908 condition for each non-default value. */
1909 for (u = 0; u <= num_units; u++)
1911 rtx orexp;
1912 int value;
1914 unit = unit_num[u];
1915 op_array = unit_ops[unit->num];
1916 num = unit->num_opclasses;
1918 /* Sort the array of ops into increasing ready cost order. */
1919 for (i = 0; i < num; i++)
1920 for (j = num - 1; j > i; j--)
1921 if (op_array[j-1]->ready < op_array[j]->ready)
1923 op = op_array[j];
1924 op_array[j] = op_array[j-1];
1925 op_array[j-1] = op;
1928 /* Determine how many distinct non-default ready cost values there
1929 are. We use a default ready cost value of 1. */
1930 nvalues = 0; value = 1;
1931 for (i = num - 1; i >= 0; i--)
1932 if (op_array[i]->ready > value)
1934 value = op_array[i]->ready;
1935 nvalues++;
1938 if (nvalues == 0)
1939 readycost = make_numeric_value (1);
1940 else
1942 /* Construct the ready cost expression as a COND of each value from
1943 the largest to the smallest. */
1944 readycost = rtx_alloc (COND);
1945 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2);
1946 XEXP (readycost, 1) = make_numeric_value (1);
1948 nvalues = 0; orexp = false_rtx; value = op_array[0]->ready;
1949 for (i = 0; i < num; i++)
1951 op = op_array[i];
1952 if (op->ready <= 1)
1953 break;
1954 else if (op->ready == value)
1955 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2);
1956 else
1958 XVECEXP (readycost, 0, nvalues * 2) = orexp;
1959 XVECEXP (readycost, 0, nvalues * 2 + 1)
1960 = make_numeric_value (value);
1961 nvalues++;
1962 value = op->ready;
1963 orexp = op->condexp;
1966 XVECEXP (readycost, 0, nvalues * 2) = orexp;
1967 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value);
1970 if (u < num_units)
1972 rtx max_blockage = 0, min_blockage = 0;
1974 /* Simplify the readycost expression by only considering insns
1975 that use the unit. */
1976 readycost = simplify_knowing (readycost, unit->condexp);
1978 /* Determine the blockage cost the executing insn (E) given
1979 the candidate insn (C). This is the maximum of the issue
1980 delay, the pipeline delay, and the simultaneity constraint.
1981 Each function_unit_op represents the characteristics of the
1982 candidate insn, so in the expressions below, C is a known
1983 term and E is an unknown term.
1985 We compute the blockage cost for each E for every possible C.
1986 Thus OP represents E, and READYCOST is a list of values for
1987 every possible C.
1989 The issue delay function for C is op->issue_exp and is used to
1990 write the `<name>_unit_conflict_cost' function. Symbolicly
1991 this is "ISSUE-DELAY (E,C)".
1993 The pipeline delay results form the FIFO constraint on the
1994 function unit and is "READY-COST (E) + 1 - READY-COST (C)".
1996 The simultaneity constraint is based on how long it takes to
1997 fill the unit given the minimum issue delay. FILL-TIME is the
1998 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and
1999 the simultaneity constraint is "READY-COST (E) - FILL-TIME"
2000 if SIMULTANEITY is non-zero and zero otherwise.
2002 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is
2004 MAX (ISSUE-DELAY (E,C),
2005 READY-COST (E) - (READY-COST (C) - 1))
2007 and otherwise
2009 MAX (ISSUE-DELAY (E,C),
2010 READY-COST (E) - (READY-COST (C) - 1),
2011 READY-COST (E) - FILL-TIME)
2013 The `<name>_unit_blockage' function is computed by determining
2014 this value for each candidate insn. As these values are
2015 computed, we also compute the upper and lower bounds for
2016 BLOCKAGE (E,*). These are combined to form the function
2017 `<name>_unit_blockage_range'. Finally, the maximum blockage
2018 cost, MAX (BLOCKAGE (*,*)), is computed. */
2020 for (op = unit->ops; op; op = op->next)
2022 rtx blockage = operate_exp (POS_MINUS_OP, readycost,
2023 make_numeric_value (1));
2025 if (unit->simultaneity != 0)
2027 rtx filltime = make_numeric_value ((unit->simultaneity - 1)
2028 * unit->issue_delay.min);
2029 blockage = operate_exp (MIN_OP, blockage, filltime);
2032 blockage = operate_exp (POS_MINUS_OP,
2033 make_numeric_value (op->ready),
2034 blockage);
2036 blockage = operate_exp (MAX_OP, blockage, op->issue_exp);
2037 blockage = simplify_knowing (blockage, unit->condexp);
2039 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and
2040 MIN (BLOCKAGE (E,*)). */
2041 if (max_blockage == 0)
2042 max_blockage = min_blockage = blockage;
2043 else
2045 max_blockage
2046 = simplify_knowing (operate_exp (MAX_OP, max_blockage,
2047 blockage),
2048 unit->condexp);
2049 min_blockage
2050 = simplify_knowing (operate_exp (MIN_OP, min_blockage,
2051 blockage),
2052 unit->condexp);
2055 /* Make an attribute for use in the blockage function. */
2056 str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS,
2057 "*%s_block_%d", unit->name, op->num);
2058 make_internal_attr (str, blockage, 1);
2061 /* Record MAX (BLOCKAGE (*,*)). */
2062 unit->max_blockage = max_attr_value (max_blockage);
2064 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the
2065 same. If so, the blockage function carries no additional
2066 information and is not written. */
2067 newexp = operate_exp (EQ_OP, max_blockage, min_blockage);
2068 newexp = simplify_knowing (newexp, unit->condexp);
2069 unit->needs_blockage_function
2070 = (GET_CODE (newexp) != CONST_STRING
2071 || atoi (XSTR (newexp, 0)) != 1);
2073 /* If the all values of BLOCKAGE (E,C) have the same value,
2074 neither blockage function is written. */
2075 unit->needs_range_function
2076 = (unit->needs_blockage_function
2077 || GET_CODE (max_blockage) != CONST_STRING);
2079 if (unit->needs_range_function)
2081 /* Compute the blockage range function and make an attribute
2082 for writing its value. */
2083 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage);
2084 newexp = simplify_knowing (newexp, unit->condexp);
2086 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"),
2087 "*%s_unit_blockage_range", unit->name);
2088 make_internal_attr (str, newexp, 4);
2091 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"),
2092 "*%s_unit_ready_cost", unit->name);
2094 else
2095 str = "*result_ready_cost";
2097 /* Make an attribute for the ready_cost function. Simplifying
2098 further with simplify_by_exploding doesn't win. */
2099 make_internal_attr (str, readycost, 0);
2102 /* For each unit that requires a conflict cost function, make an attribute
2103 that maps insns to the operation number. */
2104 for (unit = units; unit; unit = unit->next)
2106 rtx caseexp;
2108 if (! unit->needs_conflict_function
2109 && ! unit->needs_blockage_function)
2110 continue;
2112 caseexp = rtx_alloc (COND);
2113 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
2115 for (op = unit->ops; op; op = op->next)
2117 /* Make our adjustment to the COND being computed. If we are the
2118 last operation class, place our values into the default of the
2119 COND. */
2120 if (op->num == unit->num_opclasses - 1)
2122 XEXP (caseexp, 1) = make_numeric_value (op->num);
2124 else
2126 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
2127 XVECEXP (caseexp, 0, op->num * 2 + 1)
2128 = make_numeric_value (op->num);
2132 /* Simplifying caseexp with simplify_by_exploding doesn't win. */
2133 str = attr_printf (strlen (unit->name) + sizeof ("*_cases"),
2134 "*%s_cases", unit->name);
2135 make_internal_attr (str, caseexp, 1);
2139 /* Simplify EXP given KNOWN_TRUE. */
2141 static rtx
2142 simplify_knowing (exp, known_true)
2143 rtx exp, known_true;
2145 if (GET_CODE (exp) != CONST_STRING)
2147 exp = attr_rtx (IF_THEN_ELSE, known_true, exp,
2148 make_numeric_value (max_attr_value (exp)));
2149 exp = simplify_by_exploding (exp);
2151 return exp;
2154 /* Translate the CONST_STRING expressions in X to change the encoding of
2155 value. On input, the value is a bitmask with a one bit for each unit
2156 used; on output, the value is the unit number (zero based) if one
2157 and only one unit is used or the one's compliment of the bitmask. */
2159 static rtx
2160 encode_units_mask (x)
2161 rtx x;
2163 register int i;
2164 register int j;
2165 register enum rtx_code code;
2166 register char *fmt;
2168 code = GET_CODE (x);
2170 switch (code)
2172 case CONST_STRING:
2173 i = atoi (XSTR (x, 0));
2174 if (i < 0)
2175 abort (); /* The sign bit encodes a one's compliment mask. */
2176 else if (i != 0 && i == (i & -i))
2177 /* Only one bit is set, so yield that unit number. */
2178 for (j = 0; (i >>= 1) != 0; j++)
2180 else
2181 j = ~i;
2182 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j));
2184 case REG:
2185 case QUEUED:
2186 case CONST_INT:
2187 case CONST_DOUBLE:
2188 case SYMBOL_REF:
2189 case CODE_LABEL:
2190 case PC:
2191 case CC0:
2192 case EQ_ATTR:
2193 return x;
2195 default:
2196 break;
2199 /* Compare the elements. If any pair of corresponding elements
2200 fail to match, return 0 for the whole things. */
2202 fmt = GET_RTX_FORMAT (code);
2203 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
2205 switch (fmt[i])
2207 case 'V':
2208 case 'E':
2209 for (j = 0; j < XVECLEN (x, i); j++)
2210 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j));
2211 break;
2213 case 'e':
2214 XEXP (x, i) = encode_units_mask (XEXP (x, i));
2215 break;
2218 return x;
2221 /* Once all attributes and insns have been read and checked, we construct for
2222 each attribute value a list of all the insns that have that value for
2223 the attribute. */
2225 static void
2226 fill_attr (attr)
2227 struct attr_desc *attr;
2229 struct attr_value *av;
2230 struct insn_ent *ie;
2231 struct insn_def *id;
2232 int i;
2233 rtx value;
2235 /* Don't fill constant attributes. The value is independent of
2236 any particular insn. */
2237 if (attr->is_const)
2238 return;
2240 for (id = defs; id; id = id->next)
2242 /* If no value is specified for this insn for this attribute, use the
2243 default. */
2244 value = NULL;
2245 if (XVEC (id->def, id->vec_idx))
2246 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
2247 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
2248 attr->name))
2249 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
2251 if (value == NULL)
2252 av = attr->default_val;
2253 else
2254 av = get_attr_value (value, attr, id->insn_code);
2256 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2257 ie->insn_code = id->insn_code;
2258 ie->insn_index = id->insn_code;
2259 insert_insn_ent (av, ie);
2263 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
2264 test that checks relative positions of insns (uses MATCH_DUP or PC).
2265 If so, replace it with what is obtained by passing the expression to
2266 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
2267 recursively on each value (including the default value). Otherwise,
2268 return the value returned by NO_ADDRESS_FN applied to EXP. */
2270 static rtx
2271 substitute_address (exp, no_address_fn, address_fn)
2272 rtx exp;
2273 rtx (*no_address_fn) ();
2274 rtx (*address_fn) ();
2276 int i;
2277 rtx newexp;
2279 if (GET_CODE (exp) == COND)
2281 /* See if any tests use addresses. */
2282 address_used = 0;
2283 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2284 walk_attr_value (XVECEXP (exp, 0, i));
2286 if (address_used)
2287 return (*address_fn) (exp);
2289 /* Make a new copy of this COND, replacing each element. */
2290 newexp = rtx_alloc (COND);
2291 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
2292 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2294 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
2295 XVECEXP (newexp, 0, i + 1)
2296 = substitute_address (XVECEXP (exp, 0, i + 1),
2297 no_address_fn, address_fn);
2300 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
2301 no_address_fn, address_fn);
2303 return newexp;
2306 else if (GET_CODE (exp) == IF_THEN_ELSE)
2308 address_used = 0;
2309 walk_attr_value (XEXP (exp, 0));
2310 if (address_used)
2311 return (*address_fn) (exp);
2313 return attr_rtx (IF_THEN_ELSE,
2314 substitute_address (XEXP (exp, 0),
2315 no_address_fn, address_fn),
2316 substitute_address (XEXP (exp, 1),
2317 no_address_fn, address_fn),
2318 substitute_address (XEXP (exp, 2),
2319 no_address_fn, address_fn));
2322 return (*no_address_fn) (exp);
2325 /* Make new attributes from the `length' attribute. The following are made,
2326 each corresponding to a function called from `shorten_branches' or
2327 `get_attr_length':
2329 *insn_default_length This is the length of the insn to be returned
2330 by `get_attr_length' before `shorten_branches'
2331 has been called. In each case where the length
2332 depends on relative addresses, the largest
2333 possible is used. This routine is also used
2334 to compute the initial size of the insn.
2336 *insn_variable_length_p This returns 1 if the insn's length depends
2337 on relative addresses, zero otherwise.
2339 *insn_current_length This is only called when it is known that the
2340 insn has a variable length and returns the
2341 current length, based on relative addresses.
2344 static void
2345 make_length_attrs ()
2347 static char *new_names[] = {"*insn_default_length",
2348 "*insn_variable_length_p",
2349 "*insn_current_length"};
2350 static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn};
2351 static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn};
2352 int i;
2353 struct attr_desc *length_attr, *new_attr;
2354 struct attr_value *av, *new_av;
2355 struct insn_ent *ie, *new_ie;
2357 /* See if length attribute is defined. If so, it must be numeric. Make
2358 it special so we don't output anything for it. */
2359 length_attr = find_attr ("length", 0);
2360 if (length_attr == 0)
2361 return;
2363 if (! length_attr->is_numeric)
2364 fatal ("length attribute must be numeric.");
2366 length_attr->is_const = 0;
2367 length_attr->is_special = 1;
2369 /* Make each new attribute, in turn. */
2370 for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
2372 make_internal_attr (new_names[i],
2373 substitute_address (length_attr->default_val->value,
2374 no_address_fn[i], address_fn[i]),
2376 new_attr = find_attr (new_names[i], 0);
2377 for (av = length_attr->first_value; av; av = av->next)
2378 for (ie = av->first_insn; ie; ie = ie->next)
2380 new_av = get_attr_value (substitute_address (av->value,
2381 no_address_fn[i],
2382 address_fn[i]),
2383 new_attr, ie->insn_code);
2384 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent));
2385 new_ie->insn_code = ie->insn_code;
2386 new_ie->insn_index = ie->insn_index;
2387 insert_insn_ent (new_av, new_ie);
2392 /* Utility functions called from above routine. */
2394 static rtx
2395 identity_fn (exp)
2396 rtx exp;
2398 return exp;
2401 static rtx
2402 zero_fn (exp)
2403 rtx exp;
2405 return make_numeric_value (0);
2408 static rtx
2409 one_fn (exp)
2410 rtx exp;
2412 return make_numeric_value (1);
2415 static rtx
2416 max_fn (exp)
2417 rtx exp;
2419 return make_numeric_value (max_attr_value (exp));
2422 /* Take a COND expression and see if any of the conditions in it can be
2423 simplified. If any are known true or known false for the particular insn
2424 code, the COND can be further simplified.
2426 Also call ourselves on any COND operations that are values of this COND.
2428 We do not modify EXP; rather, we make and return a new rtx. */
2430 static rtx
2431 simplify_cond (exp, insn_code, insn_index)
2432 rtx exp;
2433 int insn_code, insn_index;
2435 int i, j;
2436 /* We store the desired contents here,
2437 then build a new expression if they don't match EXP. */
2438 rtx defval = XEXP (exp, 1);
2439 rtx new_defval = XEXP (exp, 1);
2440 int len = XVECLEN (exp, 0);
2441 rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion));
2442 int allsame = 1;
2443 char *first_spacer;
2445 /* This lets us free all storage allocated below, if appropriate. */
2446 first_spacer = (char *) obstack_finish (rtl_obstack);
2448 bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion));
2450 /* See if default value needs simplification. */
2451 if (GET_CODE (defval) == COND)
2452 new_defval = simplify_cond (defval, insn_code, insn_index);
2454 /* Simplify the subexpressions, and see what tests we can get rid of. */
2456 for (i = 0; i < len; i += 2)
2458 rtx newtest, newval;
2460 /* Simplify this test. */
2461 newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index);
2462 tests[i].rtx = newtest;
2464 newval = tests[i + 1].rtx;
2465 /* See if this value may need simplification. */
2466 if (GET_CODE (newval) == COND)
2467 newval = simplify_cond (newval, insn_code, insn_index);
2469 /* Look for ways to delete or combine this test. */
2470 if (newtest == true_rtx)
2472 /* If test is true, make this value the default
2473 and discard this + any following tests. */
2474 len = i;
2475 defval = tests[i + 1].rtx;
2476 new_defval = newval;
2479 else if (newtest == false_rtx)
2481 /* If test is false, discard it and its value. */
2482 for (j = i; j < len - 2; j++)
2483 tests[j].rtx = tests[j + 2].rtx;
2484 len -= 2;
2487 else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx))
2489 /* If this value and the value for the prev test are the same,
2490 merge the tests. */
2492 tests[i - 2].rtx
2493 = insert_right_side (IOR, tests[i - 2].rtx, newtest,
2494 insn_code, insn_index);
2496 /* Delete this test/value. */
2497 for (j = i; j < len - 2; j++)
2498 tests[j].rtx = tests[j + 2].rtx;
2499 len -= 2;
2502 else
2503 tests[i + 1].rtx = newval;
2506 /* If the last test in a COND has the same value
2507 as the default value, that test isn't needed. */
2509 while (len > 0 && attr_equal_p (tests[len - 1].rtx, new_defval))
2510 len -= 2;
2512 /* See if we changed anything. */
2513 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1))
2514 allsame = 0;
2515 else
2516 for (i = 0; i < len; i++)
2517 if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i)))
2519 allsame = 0;
2520 break;
2523 if (len == 0)
2525 obstack_free (rtl_obstack, first_spacer);
2526 if (GET_CODE (defval) == COND)
2527 return simplify_cond (defval, insn_code, insn_index);
2528 return defval;
2530 else if (allsame)
2532 obstack_free (rtl_obstack, first_spacer);
2533 return exp;
2535 else
2537 rtx newexp = rtx_alloc (COND);
2539 XVEC (newexp, 0) = rtvec_alloc (len);
2540 bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem,
2541 len * sizeof (rtunion));
2542 XEXP (newexp, 1) = new_defval;
2543 return newexp;
2547 /* Remove an insn entry from an attribute value. */
2549 static void
2550 remove_insn_ent (av, ie)
2551 struct attr_value *av;
2552 struct insn_ent *ie;
2554 struct insn_ent *previe;
2556 if (av->first_insn == ie)
2557 av->first_insn = ie->next;
2558 else
2560 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
2562 previe->next = ie->next;
2565 av->num_insns--;
2566 if (ie->insn_code == -1)
2567 av->has_asm_insn = 0;
2569 num_insn_ents--;
2572 /* Insert an insn entry in an attribute value list. */
2574 static void
2575 insert_insn_ent (av, ie)
2576 struct attr_value *av;
2577 struct insn_ent *ie;
2579 ie->next = av->first_insn;
2580 av->first_insn = ie;
2581 av->num_insns++;
2582 if (ie->insn_code == -1)
2583 av->has_asm_insn = 1;
2585 num_insn_ents++;
2588 /* This is a utility routine to take an expression that is a tree of either
2589 AND or IOR expressions and insert a new term. The new term will be
2590 inserted at the right side of the first node whose code does not match
2591 the root. A new node will be created with the root's code. Its left
2592 side will be the old right side and its right side will be the new
2593 term.
2595 If the `term' is itself a tree, all its leaves will be inserted. */
2597 static rtx
2598 insert_right_side (code, exp, term, insn_code, insn_index)
2599 enum rtx_code code;
2600 rtx exp;
2601 rtx term;
2602 int insn_code, insn_index;
2604 rtx newexp;
2606 /* Avoid consing in some special cases. */
2607 if (code == AND && term == true_rtx)
2608 return exp;
2609 if (code == AND && term == false_rtx)
2610 return false_rtx;
2611 if (code == AND && exp == true_rtx)
2612 return term;
2613 if (code == AND && exp == false_rtx)
2614 return false_rtx;
2615 if (code == IOR && term == true_rtx)
2616 return true_rtx;
2617 if (code == IOR && term == false_rtx)
2618 return exp;
2619 if (code == IOR && exp == true_rtx)
2620 return true_rtx;
2621 if (code == IOR && exp == false_rtx)
2622 return term;
2623 if (attr_equal_p (exp, term))
2624 return exp;
2626 if (GET_CODE (term) == code)
2628 exp = insert_right_side (code, exp, XEXP (term, 0),
2629 insn_code, insn_index);
2630 exp = insert_right_side (code, exp, XEXP (term, 1),
2631 insn_code, insn_index);
2633 return exp;
2636 if (GET_CODE (exp) == code)
2638 rtx new = insert_right_side (code, XEXP (exp, 1),
2639 term, insn_code, insn_index);
2640 if (new != XEXP (exp, 1))
2641 /* Make a copy of this expression and call recursively. */
2642 newexp = attr_rtx (code, XEXP (exp, 0), new);
2643 else
2644 newexp = exp;
2646 else
2648 /* Insert the new term. */
2649 newexp = attr_rtx (code, exp, term);
2652 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2655 /* If we have an expression which AND's a bunch of
2656 (not (eq_attrq "alternative" "n"))
2657 terms, we may have covered all or all but one of the possible alternatives.
2658 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
2660 This routine is passed an expression and either AND or IOR. It returns a
2661 bitmask indicating which alternatives are mentioned within EXP. */
2663 static int
2664 compute_alternative_mask (exp, code)
2665 rtx exp;
2666 enum rtx_code code;
2668 char *string;
2669 if (GET_CODE (exp) == code)
2670 return compute_alternative_mask (XEXP (exp, 0), code)
2671 | compute_alternative_mask (XEXP (exp, 1), code);
2673 else if (code == AND && GET_CODE (exp) == NOT
2674 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2675 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2676 string = XSTR (XEXP (exp, 0), 1);
2678 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
2679 && XSTR (exp, 0) == alternative_name)
2680 string = XSTR (exp, 1);
2682 else
2683 return 0;
2685 if (string[1] == 0)
2686 return 1 << (string[0] - '0');
2687 return 1 << atoi (string);
2690 /* Given I, a single-bit mask, return RTX to compare the `alternative'
2691 attribute with the value represented by that bit. */
2693 static rtx
2694 make_alternative_compare (mask)
2695 int mask;
2697 rtx newexp;
2698 int i;
2700 /* Find the bit. */
2701 for (i = 0; (mask & (1 << i)) == 0; i++)
2704 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i));
2705 RTX_UNCHANGING_P (newexp) = 1;
2707 return newexp;
2710 /* If we are processing an (eq_attr "attr" "value") test, we find the value
2711 of "attr" for this insn code. From that value, we can compute a test
2712 showing when the EQ_ATTR will be true. This routine performs that
2713 computation. If a test condition involves an address, we leave the EQ_ATTR
2714 intact because addresses are only valid for the `length' attribute.
2716 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
2717 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2719 static rtx
2720 evaluate_eq_attr (exp, value, insn_code, insn_index)
2721 rtx exp;
2722 rtx value;
2723 int insn_code, insn_index;
2725 rtx orexp, andexp;
2726 rtx right;
2727 rtx newexp;
2728 int i;
2730 if (GET_CODE (value) == CONST_STRING)
2732 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
2733 newexp = true_rtx;
2734 else
2735 newexp = false_rtx;
2737 else if (GET_CODE (value) == COND)
2739 /* We construct an IOR of all the cases for which the requested attribute
2740 value is present. Since we start with FALSE, if it is not present,
2741 FALSE will be returned.
2743 Each case is the AND of the NOT's of the previous conditions with the
2744 current condition; in the default case the current condition is TRUE.
2746 For each possible COND value, call ourselves recursively.
2748 The extra TRUE and FALSE expressions will be eliminated by another
2749 call to the simplification routine. */
2751 orexp = false_rtx;
2752 andexp = true_rtx;
2754 if (current_alternative_string)
2755 clear_struct_flag (value);
2757 for (i = 0; i < XVECLEN (value, 0); i += 2)
2759 rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i),
2760 insn_code, insn_index);
2762 SIMPLIFY_ALTERNATIVE (this);
2764 right = insert_right_side (AND, andexp, this,
2765 insn_code, insn_index);
2766 right = insert_right_side (AND, right,
2767 evaluate_eq_attr (exp,
2768 XVECEXP (value, 0,
2769 i + 1),
2770 insn_code, insn_index),
2771 insn_code, insn_index);
2772 orexp = insert_right_side (IOR, orexp, right,
2773 insn_code, insn_index);
2775 /* Add this condition into the AND expression. */
2776 newexp = attr_rtx (NOT, this);
2777 andexp = insert_right_side (AND, andexp, newexp,
2778 insn_code, insn_index);
2781 /* Handle the default case. */
2782 right = insert_right_side (AND, andexp,
2783 evaluate_eq_attr (exp, XEXP (value, 1),
2784 insn_code, insn_index),
2785 insn_code, insn_index);
2786 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
2788 else
2789 abort ();
2791 /* If uses an address, must return original expression. But set the
2792 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
2794 address_used = 0;
2795 walk_attr_value (newexp);
2797 if (address_used)
2799 /* This had `&& current_alternative_string', which seems to be wrong. */
2800 if (! RTX_UNCHANGING_P (exp))
2801 return copy_rtx_unchanging (exp);
2802 return exp;
2804 else
2805 return newexp;
2808 /* This routine is called when an AND of a term with a tree of AND's is
2809 encountered. If the term or its complement is present in the tree, it
2810 can be replaced with TRUE or FALSE, respectively.
2812 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2813 be true and hence are complementary.
2815 There is one special case: If we see
2816 (and (not (eq_attr "att" "v1"))
2817 (eq_attr "att" "v2"))
2818 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2819 replace the term, not anything in the AND tree. So we pass a pointer to
2820 the term. */
2822 static rtx
2823 simplify_and_tree (exp, pterm, insn_code, insn_index)
2824 rtx exp;
2825 rtx *pterm;
2826 int insn_code, insn_index;
2828 rtx left, right;
2829 rtx newexp;
2830 rtx temp;
2831 int left_eliminates_term, right_eliminates_term;
2833 if (GET_CODE (exp) == AND)
2835 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2836 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2837 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2839 newexp = attr_rtx (GET_CODE (exp), left, right);
2841 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2845 else if (GET_CODE (exp) == IOR)
2847 /* For the IOR case, we do the same as above, except that we can
2848 only eliminate `term' if both sides of the IOR would do so. */
2849 temp = *pterm;
2850 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2851 left_eliminates_term = (temp == true_rtx);
2853 temp = *pterm;
2854 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2855 right_eliminates_term = (temp == true_rtx);
2857 if (left_eliminates_term && right_eliminates_term)
2858 *pterm = true_rtx;
2860 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2862 newexp = attr_rtx (GET_CODE (exp), left, right);
2864 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2868 /* Check for simplifications. Do some extra checking here since this
2869 routine is called so many times. */
2871 if (exp == *pterm)
2872 return true_rtx;
2874 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2875 return false_rtx;
2877 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2878 return false_rtx;
2880 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2882 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2883 return exp;
2885 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
2886 return true_rtx;
2887 else
2888 return false_rtx;
2891 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2892 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2894 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2895 return exp;
2897 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2898 return false_rtx;
2899 else
2900 return true_rtx;
2903 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2904 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2906 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2907 return exp;
2909 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2910 return false_rtx;
2911 else
2912 *pterm = true_rtx;
2915 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2917 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2918 return true_rtx;
2921 else if (GET_CODE (exp) == NOT)
2923 if (attr_equal_p (XEXP (exp, 0), *pterm))
2924 return false_rtx;
2927 else if (GET_CODE (*pterm) == NOT)
2929 if (attr_equal_p (XEXP (*pterm, 0), exp))
2930 return false_rtx;
2933 else if (attr_equal_p (exp, *pterm))
2934 return true_rtx;
2936 return exp;
2939 /* Similar to `simplify_and_tree', but for IOR trees. */
2941 static rtx
2942 simplify_or_tree (exp, pterm, insn_code, insn_index)
2943 rtx exp;
2944 rtx *pterm;
2945 int insn_code, insn_index;
2947 rtx left, right;
2948 rtx newexp;
2949 rtx temp;
2950 int left_eliminates_term, right_eliminates_term;
2952 if (GET_CODE (exp) == IOR)
2954 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2955 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2956 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2958 newexp = attr_rtx (GET_CODE (exp), left, right);
2960 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2964 else if (GET_CODE (exp) == AND)
2966 /* For the AND case, we do the same as above, except that we can
2967 only eliminate `term' if both sides of the AND would do so. */
2968 temp = *pterm;
2969 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2970 left_eliminates_term = (temp == false_rtx);
2972 temp = *pterm;
2973 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2974 right_eliminates_term = (temp == false_rtx);
2976 if (left_eliminates_term && right_eliminates_term)
2977 *pterm = false_rtx;
2979 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2981 newexp = attr_rtx (GET_CODE (exp), left, right);
2983 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2987 if (attr_equal_p (exp, *pterm))
2988 return false_rtx;
2990 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm))
2991 return true_rtx;
2993 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp))
2994 return true_rtx;
2996 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2997 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2998 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2999 *pterm = false_rtx;
3001 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
3002 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
3003 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
3004 return false_rtx;
3006 return exp;
3009 /* Given an expression, see if it can be simplified for a particular insn
3010 code based on the values of other attributes being tested. This can
3011 eliminate nested get_attr_... calls.
3013 Note that if an endless recursion is specified in the patterns, the
3014 optimization will loop. However, it will do so in precisely the cases where
3015 an infinite recursion loop could occur during compilation. It's better that
3016 it occurs here! */
3018 static rtx
3019 simplify_test_exp (exp, insn_code, insn_index)
3020 rtx exp;
3021 int insn_code, insn_index;
3023 rtx left, right;
3024 struct attr_desc *attr;
3025 struct attr_value *av;
3026 struct insn_ent *ie;
3027 int i;
3028 rtx newexp = exp;
3029 char *spacer = (char *) obstack_finish (rtl_obstack);
3031 /* Don't re-simplify something we already simplified. */
3032 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp))
3033 return exp;
3035 switch (GET_CODE (exp))
3037 case AND:
3038 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3039 SIMPLIFY_ALTERNATIVE (left);
3040 if (left == false_rtx)
3042 obstack_free (rtl_obstack, spacer);
3043 return false_rtx;
3045 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3046 SIMPLIFY_ALTERNATIVE (right);
3047 if (left == false_rtx)
3049 obstack_free (rtl_obstack, spacer);
3050 return false_rtx;
3053 /* If either side is an IOR and we have (eq_attr "alternative" ..")
3054 present on both sides, apply the distributive law since this will
3055 yield simplifications. */
3056 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
3057 && compute_alternative_mask (left, IOR)
3058 && compute_alternative_mask (right, IOR))
3060 if (GET_CODE (left) == IOR)
3062 rtx tem = left;
3063 left = right;
3064 right = tem;
3067 newexp = attr_rtx (IOR,
3068 attr_rtx (AND, left, XEXP (right, 0)),
3069 attr_rtx (AND, left, XEXP (right, 1)));
3071 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3074 /* Try with the term on both sides. */
3075 right = simplify_and_tree (right, &left, insn_code, insn_index);
3076 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3077 left = simplify_and_tree (left, &right, insn_code, insn_index);
3079 if (left == false_rtx || right == false_rtx)
3081 obstack_free (rtl_obstack, spacer);
3082 return false_rtx;
3084 else if (left == true_rtx)
3086 return right;
3088 else if (right == true_rtx)
3090 return left;
3092 /* See if all or all but one of the insn's alternatives are specified
3093 in this tree. Optimize if so. */
3095 else if (insn_code >= 0
3096 && (GET_CODE (left) == AND
3097 || (GET_CODE (left) == NOT
3098 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
3099 && XSTR (XEXP (left, 0), 0) == alternative_name)
3100 || GET_CODE (right) == AND
3101 || (GET_CODE (right) == NOT
3102 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
3103 && XSTR (XEXP (right, 0), 0) == alternative_name)))
3105 i = compute_alternative_mask (exp, AND);
3106 if (i & ~insn_alternatives[insn_code])
3107 fatal ("Invalid alternative specified for pattern number %d",
3108 insn_index);
3110 /* If all alternatives are excluded, this is false. */
3111 i ^= insn_alternatives[insn_code];
3112 if (i == 0)
3113 return false_rtx;
3114 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3116 /* If just one excluded, AND a comparison with that one to the
3117 front of the tree. The others will be eliminated by
3118 optimization. We do not want to do this if the insn has one
3119 alternative and we have tested none of them! */
3120 left = make_alternative_compare (i);
3121 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3122 newexp = attr_rtx (AND, left, right);
3124 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3128 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3130 newexp = attr_rtx (AND, left, right);
3131 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3133 break;
3135 case IOR:
3136 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3137 SIMPLIFY_ALTERNATIVE (left);
3138 if (left == true_rtx)
3140 obstack_free (rtl_obstack, spacer);
3141 return true_rtx;
3143 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
3144 SIMPLIFY_ALTERNATIVE (right);
3145 if (right == true_rtx)
3147 obstack_free (rtl_obstack, spacer);
3148 return true_rtx;
3151 right = simplify_or_tree (right, &left, insn_code, insn_index);
3152 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
3153 left = simplify_or_tree (left, &right, insn_code, insn_index);
3155 if (right == true_rtx || left == true_rtx)
3157 obstack_free (rtl_obstack, spacer);
3158 return true_rtx;
3160 else if (left == false_rtx)
3162 return right;
3164 else if (right == false_rtx)
3166 return left;
3169 /* Test for simple cases where the distributive law is useful. I.e.,
3170 convert (ior (and (x) (y))
3171 (and (x) (z)))
3172 to (and (x)
3173 (ior (y) (z)))
3176 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
3177 && attr_equal_p (XEXP (left, 0), XEXP (right, 0)))
3179 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
3181 left = XEXP (left, 0);
3182 right = newexp;
3183 newexp = attr_rtx (AND, left, right);
3184 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3187 /* See if all or all but one of the insn's alternatives are specified
3188 in this tree. Optimize if so. */
3190 else if (insn_code >= 0
3191 && (GET_CODE (left) == IOR
3192 || (GET_CODE (left) == EQ_ATTR
3193 && XSTR (left, 0) == alternative_name)
3194 || GET_CODE (right) == IOR
3195 || (GET_CODE (right) == EQ_ATTR
3196 && XSTR (right, 0) == alternative_name)))
3198 i = compute_alternative_mask (exp, IOR);
3199 if (i & ~insn_alternatives[insn_code])
3200 fatal ("Invalid alternative specified for pattern number %d",
3201 insn_index);
3203 /* If all alternatives are included, this is true. */
3204 i ^= insn_alternatives[insn_code];
3205 if (i == 0)
3206 return true_rtx;
3207 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
3209 /* If just one excluded, IOR a comparison with that one to the
3210 front of the tree. The others will be eliminated by
3211 optimization. We do not want to do this if the insn has one
3212 alternative and we have tested none of them! */
3213 left = make_alternative_compare (i);
3214 right = simplify_and_tree (exp, &left, insn_code, insn_index);
3215 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
3217 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3221 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
3223 newexp = attr_rtx (IOR, left, right);
3224 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3226 break;
3228 case NOT:
3229 if (GET_CODE (XEXP (exp, 0)) == NOT)
3231 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0),
3232 insn_code, insn_index);
3233 SIMPLIFY_ALTERNATIVE (left);
3234 return left;
3237 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
3238 SIMPLIFY_ALTERNATIVE (left);
3239 if (GET_CODE (left) == NOT)
3240 return XEXP (left, 0);
3242 if (left == false_rtx)
3244 obstack_free (rtl_obstack, spacer);
3245 return true_rtx;
3247 else if (left == true_rtx)
3249 obstack_free (rtl_obstack, spacer);
3250 return false_rtx;
3253 /* Try to apply De`Morgan's laws. */
3254 else if (GET_CODE (left) == IOR)
3256 newexp = attr_rtx (AND,
3257 attr_rtx (NOT, XEXP (left, 0)),
3258 attr_rtx (NOT, XEXP (left, 1)));
3260 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3262 else if (GET_CODE (left) == AND)
3264 newexp = attr_rtx (IOR,
3265 attr_rtx (NOT, XEXP (left, 0)),
3266 attr_rtx (NOT, XEXP (left, 1)));
3268 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
3270 else if (left != XEXP (exp, 0))
3272 newexp = attr_rtx (NOT, left);
3274 break;
3276 case EQ_ATTR:
3277 if (current_alternative_string && XSTR (exp, 0) == alternative_name)
3278 return (XSTR (exp, 1) == current_alternative_string
3279 ? true_rtx : false_rtx);
3281 /* Look at the value for this insn code in the specified attribute.
3282 We normally can replace this comparison with the condition that
3283 would give this insn the values being tested for. */
3284 if (XSTR (exp, 0) != alternative_name
3285 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
3286 for (av = attr->first_value; av; av = av->next)
3287 for (ie = av->first_insn; ie; ie = ie->next)
3288 if (ie->insn_code == insn_code)
3289 return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
3290 break;
3292 default:
3293 break;
3296 /* We have already simplified this expression. Simplifying it again
3297 won't buy anything unless we weren't given a valid insn code
3298 to process (i.e., we are canonicalizing something.). */
3299 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */
3300 && ! RTX_UNCHANGING_P (newexp))
3301 return copy_rtx_unchanging (newexp);
3303 return newexp;
3306 /* Optimize the attribute lists by seeing if we can determine conditional
3307 values from the known values of other attributes. This will save subroutine
3308 calls during the compilation. */
3310 static void
3311 optimize_attrs ()
3313 struct attr_desc *attr;
3314 struct attr_value *av;
3315 struct insn_ent *ie;
3316 rtx newexp;
3317 int something_changed = 1;
3318 int i;
3319 struct attr_value_list { struct attr_value *av;
3320 struct insn_ent *ie;
3321 struct attr_desc * attr;
3322 struct attr_value_list *next; };
3323 struct attr_value_list **insn_code_values;
3324 struct attr_value_list *ivbuf;
3325 struct attr_value_list *iv;
3327 /* For each insn code, make a list of all the insn_ent's for it,
3328 for all values for all attributes. */
3330 if (num_insn_ents == 0)
3331 return;
3333 /* Make 2 extra elements, for "code" values -2 and -1. */
3334 insn_code_values
3335 = (struct attr_value_list **) alloca ((insn_code_number + 2)
3336 * sizeof (struct attr_value_list *));
3337 bzero ((char *) insn_code_values,
3338 (insn_code_number + 2) * sizeof (struct attr_value_list *));
3340 /* Offset the table address so we can index by -2 or -1. */
3341 insn_code_values += 2;
3343 /* Allocate the attr_value_list structures using xmalloc rather than
3344 alloca, because using alloca can overflow the maximum permitted
3345 stack limit on SPARC Lynx. */
3346 iv = ivbuf = ((struct attr_value_list *)
3347 xmalloc (num_insn_ents * sizeof (struct attr_value_list)));
3349 for (i = 0; i < MAX_ATTRS_INDEX; i++)
3350 for (attr = attrs[i]; attr; attr = attr->next)
3351 for (av = attr->first_value; av; av = av->next)
3352 for (ie = av->first_insn; ie; ie = ie->next)
3354 iv->attr = attr;
3355 iv->av = av;
3356 iv->ie = ie;
3357 iv->next = insn_code_values[ie->insn_code];
3358 insn_code_values[ie->insn_code] = iv;
3359 iv++;
3362 /* Sanity check on num_insn_ents. */
3363 if (iv != ivbuf + num_insn_ents)
3364 abort ();
3366 /* Process one insn code at a time. */
3367 for (i = -2; i < insn_code_number; i++)
3369 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant.
3370 We use it to mean "already simplified for this insn". */
3371 for (iv = insn_code_values[i]; iv; iv = iv->next)
3372 clear_struct_flag (iv->av->value);
3374 /* Loop until nothing changes for one iteration. */
3375 something_changed = 1;
3376 while (something_changed)
3378 something_changed = 0;
3379 for (iv = insn_code_values[i]; iv; iv = iv->next)
3381 struct obstack *old = rtl_obstack;
3382 char *spacer = (char *) obstack_finish (temp_obstack);
3384 attr = iv->attr;
3385 av = iv->av;
3386 ie = iv->ie;
3387 if (GET_CODE (av->value) != COND)
3388 continue;
3390 rtl_obstack = temp_obstack;
3391 #if 0 /* This was intended as a speed up, but it was slower. */
3392 if (insn_n_alternatives[ie->insn_code] > 6
3393 && count_sub_rtxs (av->value, 200) >= 200)
3394 newexp = simplify_by_alternatives (av->value, ie->insn_code,
3395 ie->insn_index);
3396 else
3397 #endif
3398 newexp = simplify_cond (av->value, ie->insn_code,
3399 ie->insn_index);
3401 rtl_obstack = old;
3402 if (newexp != av->value)
3404 newexp = attr_copy_rtx (newexp);
3405 remove_insn_ent (av, ie);
3406 av = get_attr_value (newexp, attr, ie->insn_code);
3407 iv->av = av;
3408 insert_insn_ent (av, ie);
3409 something_changed = 1;
3411 obstack_free (temp_obstack, spacer);
3416 free (ivbuf);
3419 #if 0
3420 static rtx
3421 simplify_by_alternatives (exp, insn_code, insn_index)
3422 rtx exp;
3423 int insn_code, insn_index;
3425 int i;
3426 int len = insn_n_alternatives[insn_code];
3427 rtx newexp = rtx_alloc (COND);
3428 rtx ultimate;
3431 XVEC (newexp, 0) = rtvec_alloc (len * 2);
3433 /* It will not matter what value we use as the default value
3434 of the new COND, since that default will never be used.
3435 Choose something of the right type. */
3436 for (ultimate = exp; GET_CODE (ultimate) == COND;)
3437 ultimate = XEXP (ultimate, 1);
3438 XEXP (newexp, 1) = ultimate;
3440 for (i = 0; i < insn_n_alternatives[insn_code]; i++)
3442 current_alternative_string = attr_numeral (i);
3443 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i);
3444 XVECEXP (newexp, 0, i * 2 + 1)
3445 = simplify_cond (exp, insn_code, insn_index);
3448 current_alternative_string = 0;
3449 return simplify_cond (newexp, insn_code, insn_index);
3451 #endif
3453 /* If EXP is a suitable expression, reorganize it by constructing an
3454 equivalent expression that is a COND with the tests being all combinations
3455 of attribute values and the values being simple constants. */
3457 static rtx
3458 simplify_by_exploding (exp)
3459 rtx exp;
3461 rtx list = 0, link, condexp, defval;
3462 struct dimension *space;
3463 rtx *condtest, *condval;
3464 int i, j, total, ndim = 0;
3465 int most_tests, num_marks, new_marks;
3467 /* Locate all the EQ_ATTR expressions. */
3468 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0)
3470 unmark_used_attributes (list, 0, 0);
3471 return exp;
3474 /* Create an attribute space from the list of used attributes. For each
3475 dimension in the attribute space, record the attribute, list of values
3476 used, and number of values used. Add members to the list of values to
3477 cover the domain of the attribute. This makes the expanded COND form
3478 order independent. */
3480 space = (struct dimension *) alloca (ndim * sizeof (struct dimension));
3482 total = 1;
3483 for (ndim = 0; list; ndim++)
3485 /* Pull the first attribute value from the list and record that
3486 attribute as another dimension in the attribute space. */
3487 char *name = XSTR (XEXP (list, 0), 0);
3488 rtx *prev;
3490 if ((space[ndim].attr = find_attr (name, 0)) == 0
3491 || space[ndim].attr->is_numeric)
3493 unmark_used_attributes (list, space, ndim);
3494 return exp;
3497 /* Add all remaining attribute values that refer to this attribute. */
3498 space[ndim].num_values = 0;
3499 space[ndim].values = 0;
3500 prev = &list;
3501 for (link = list; link; link = *prev)
3502 if (! strcmp (XSTR (XEXP (link, 0), 0), name))
3504 space[ndim].num_values++;
3505 *prev = XEXP (link, 1);
3506 XEXP (link, 1) = space[ndim].values;
3507 space[ndim].values = link;
3509 else
3510 prev = &XEXP (link, 1);
3512 /* Add sufficient members to the list of values to make the list
3513 mutually exclusive and record the total size of the attribute
3514 space. */
3515 total *= add_values_to_cover (&space[ndim]);
3518 /* Sort the attribute space so that the attributes go from non-constant
3519 to constant and from most values to least values. */
3520 for (i = 0; i < ndim; i++)
3521 for (j = ndim - 1; j > i; j--)
3522 if ((space[j-1].attr->is_const && !space[j].attr->is_const)
3523 || space[j-1].num_values < space[j].num_values)
3525 struct dimension tmp;
3526 tmp = space[j];
3527 space[j] = space[j-1];
3528 space[j-1] = tmp;
3531 /* Establish the initial current value. */
3532 for (i = 0; i < ndim; i++)
3533 space[i].current_value = space[i].values;
3535 condtest = (rtx *) alloca (total * sizeof (rtx));
3536 condval = (rtx *) alloca (total * sizeof (rtx));
3538 /* Expand the tests and values by iterating over all values in the
3539 attribute space. */
3540 for (i = 0;; i++)
3542 condtest[i] = test_for_current_value (space, ndim);
3543 condval[i] = simplify_with_current_value (exp, space, ndim);
3544 if (! increment_current_value (space, ndim))
3545 break;
3547 if (i != total - 1)
3548 abort ();
3550 /* We are now finished with the original expression. */
3551 unmark_used_attributes (0, space, ndim);
3553 /* Find the most used constant value and make that the default. */
3554 most_tests = -1;
3555 for (i = num_marks = 0; i < total; i++)
3556 if (GET_CODE (condval[i]) == CONST_STRING
3557 && ! MEM_VOLATILE_P (condval[i]))
3559 /* Mark the unmarked constant value and count how many are marked. */
3560 MEM_VOLATILE_P (condval[i]) = 1;
3561 for (j = new_marks = 0; j < total; j++)
3562 if (GET_CODE (condval[j]) == CONST_STRING
3563 && MEM_VOLATILE_P (condval[j]))
3564 new_marks++;
3565 if (new_marks - num_marks > most_tests)
3567 most_tests = new_marks - num_marks;
3568 defval = condval[i];
3570 num_marks = new_marks;
3572 /* Clear all the marks. */
3573 for (i = 0; i < total; i++)
3574 MEM_VOLATILE_P (condval[i]) = 0;
3576 /* Give up if nothing is constant. */
3577 if (num_marks == 0)
3578 return exp;
3580 /* If all values are the default, use that. */
3581 if (total == most_tests)
3582 return defval;
3584 /* Make a COND with the most common constant value the default. (A more
3585 complex method where tests with the same value were combined didn't
3586 seem to improve things.) */
3587 condexp = rtx_alloc (COND);
3588 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2);
3589 XEXP (condexp, 1) = defval;
3590 for (i = j = 0; i < total; i++)
3591 if (condval[i] != defval)
3593 XVECEXP (condexp, 0, 2 * j) = condtest[i];
3594 XVECEXP (condexp, 0, 2 * j + 1) = condval[i];
3595 j++;
3598 return condexp;
3601 /* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and
3602 verify that EXP can be simplified to a constant term if all the EQ_ATTR
3603 tests have known value. */
3605 static int
3606 find_and_mark_used_attributes (exp, terms, nterms)
3607 rtx exp, *terms;
3608 int *nterms;
3610 int i;
3612 switch (GET_CODE (exp))
3614 case EQ_ATTR:
3615 if (! MEM_VOLATILE_P (exp))
3617 rtx link = rtx_alloc (EXPR_LIST);
3618 XEXP (link, 0) = exp;
3619 XEXP (link, 1) = *terms;
3620 *terms = link;
3621 *nterms += 1;
3622 MEM_VOLATILE_P (exp) = 1;
3624 case CONST_STRING:
3625 return 1;
3627 case IF_THEN_ELSE:
3628 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms))
3629 return 0;
3630 case IOR:
3631 case AND:
3632 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3633 return 0;
3634 case NOT:
3635 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms))
3636 return 0;
3637 return 1;
3639 case COND:
3640 for (i = 0; i < XVECLEN (exp, 0); i++)
3641 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms))
3642 return 0;
3643 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms))
3644 return 0;
3645 return 1;
3647 default:
3648 return 0;
3652 /* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and
3653 in the values of the NDIM-dimensional attribute space SPACE. */
3655 static void
3656 unmark_used_attributes (list, space, ndim)
3657 rtx list;
3658 struct dimension *space;
3659 int ndim;
3661 rtx link, exp;
3662 int i;
3664 for (i = 0; i < ndim; i++)
3665 unmark_used_attributes (space[i].values, 0, 0);
3667 for (link = list; link; link = XEXP (link, 1))
3669 exp = XEXP (link, 0);
3670 if (GET_CODE (exp) == EQ_ATTR)
3671 MEM_VOLATILE_P (exp) = 0;
3675 /* Update the attribute dimension DIM so that all values of the attribute
3676 are tested. Return the updated number of values. */
3678 static int
3679 add_values_to_cover (dim)
3680 struct dimension *dim;
3682 struct attr_value *av;
3683 rtx exp, link, *prev;
3684 int nalt = 0;
3686 for (av = dim->attr->first_value; av; av = av->next)
3687 if (GET_CODE (av->value) == CONST_STRING)
3688 nalt++;
3690 if (nalt < dim->num_values)
3691 abort ();
3692 else if (nalt == dim->num_values)
3693 ; /* Ok. */
3694 else if (nalt * 2 < dim->num_values * 3)
3696 /* Most all the values of the attribute are used, so add all the unused
3697 values. */
3698 prev = &dim->values;
3699 for (link = dim->values; link; link = *prev)
3700 prev = &XEXP (link, 1);
3702 for (av = dim->attr->first_value; av; av = av->next)
3703 if (GET_CODE (av->value) == CONST_STRING)
3705 exp = attr_eq (dim->attr->name, XSTR (av->value, 0));
3706 if (MEM_VOLATILE_P (exp))
3707 continue;
3709 link = rtx_alloc (EXPR_LIST);
3710 XEXP (link, 0) = exp;
3711 XEXP (link, 1) = 0;
3712 *prev = link;
3713 prev = &XEXP (link, 1);
3715 dim->num_values = nalt;
3717 else
3719 rtx orexp = false_rtx;
3721 /* Very few values are used, so compute a mutually exclusive
3722 expression. (We could do this for numeric values if that becomes
3723 important.) */
3724 prev = &dim->values;
3725 for (link = dim->values; link; link = *prev)
3727 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2);
3728 prev = &XEXP (link, 1);
3730 link = rtx_alloc (EXPR_LIST);
3731 XEXP (link, 0) = attr_rtx (NOT, orexp);
3732 XEXP (link, 1) = 0;
3733 *prev = link;
3734 dim->num_values++;
3736 return dim->num_values;
3739 /* Increment the current value for the NDIM-dimensional attribute space SPACE
3740 and return FALSE if the increment overflowed. */
3742 static int
3743 increment_current_value (space, ndim)
3744 struct dimension *space;
3745 int ndim;
3747 int i;
3749 for (i = ndim - 1; i >= 0; i--)
3751 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0)
3752 space[i].current_value = space[i].values;
3753 else
3754 return 1;
3756 return 0;
3759 /* Construct an expression corresponding to the current value for the
3760 NDIM-dimensional attribute space SPACE. */
3762 static rtx
3763 test_for_current_value (space, ndim)
3764 struct dimension *space;
3765 int ndim;
3767 int i;
3768 rtx exp = true_rtx;
3770 for (i = 0; i < ndim; i++)
3771 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0),
3772 -2, -2);
3774 return exp;
3777 /* Given the current value of the NDIM-dimensional attribute space SPACE,
3778 set the corresponding EQ_ATTR expressions to that value and reduce
3779 the expression EXP as much as possible. On input [and output], all
3780 known EQ_ATTR expressions are set to FALSE. */
3782 static rtx
3783 simplify_with_current_value (exp, space, ndim)
3784 rtx exp;
3785 struct dimension *space;
3786 int ndim;
3788 int i;
3789 rtx x;
3791 /* Mark each current value as TRUE. */
3792 for (i = 0; i < ndim; i++)
3794 x = XEXP (space[i].current_value, 0);
3795 if (GET_CODE (x) == EQ_ATTR)
3796 MEM_VOLATILE_P (x) = 0;
3799 exp = simplify_with_current_value_aux (exp);
3801 /* Change each current value back to FALSE. */
3802 for (i = 0; i < ndim; i++)
3804 x = XEXP (space[i].current_value, 0);
3805 if (GET_CODE (x) == EQ_ATTR)
3806 MEM_VOLATILE_P (x) = 1;
3809 return exp;
3812 /* Reduce the expression EXP based on the MEM_VOLATILE_P settings of
3813 all EQ_ATTR expressions. */
3815 static rtx
3816 simplify_with_current_value_aux (exp)
3817 rtx exp;
3819 register int i;
3820 rtx cond;
3822 switch (GET_CODE (exp))
3824 case EQ_ATTR:
3825 if (MEM_VOLATILE_P (exp))
3826 return false_rtx;
3827 else
3828 return true_rtx;
3829 case CONST_STRING:
3830 return exp;
3832 case IF_THEN_ELSE:
3833 cond = simplify_with_current_value_aux (XEXP (exp, 0));
3834 if (cond == true_rtx)
3835 return simplify_with_current_value_aux (XEXP (exp, 1));
3836 else if (cond == false_rtx)
3837 return simplify_with_current_value_aux (XEXP (exp, 2));
3838 else
3839 return attr_rtx (IF_THEN_ELSE, cond,
3840 simplify_with_current_value_aux (XEXP (exp, 1)),
3841 simplify_with_current_value_aux (XEXP (exp, 2)));
3843 case IOR:
3844 cond = simplify_with_current_value_aux (XEXP (exp, 1));
3845 if (cond == true_rtx)
3846 return cond;
3847 else if (cond == false_rtx)
3848 return simplify_with_current_value_aux (XEXP (exp, 0));
3849 else
3850 return attr_rtx (IOR, cond,
3851 simplify_with_current_value_aux (XEXP (exp, 0)));
3853 case AND:
3854 cond = simplify_with_current_value_aux (XEXP (exp, 1));
3855 if (cond == true_rtx)
3856 return simplify_with_current_value_aux (XEXP (exp, 0));
3857 else if (cond == false_rtx)
3858 return cond;
3859 else
3860 return attr_rtx (AND, cond,
3861 simplify_with_current_value_aux (XEXP (exp, 0)));
3863 case NOT:
3864 cond = simplify_with_current_value_aux (XEXP (exp, 0));
3865 if (cond == true_rtx)
3866 return false_rtx;
3867 else if (cond == false_rtx)
3868 return true_rtx;
3869 else
3870 return attr_rtx (NOT, cond);
3872 case COND:
3873 for (i = 0; i < XVECLEN (exp, 0); i += 2)
3875 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i));
3876 if (cond == true_rtx)
3877 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1));
3878 else if (cond == false_rtx)
3879 continue;
3880 else
3881 abort (); /* With all EQ_ATTR's of known value, a case should
3882 have been selected. */
3884 return simplify_with_current_value_aux (XEXP (exp, 1));
3886 default:
3887 abort ();
3891 /* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */
3893 static void
3894 clear_struct_flag (x)
3895 rtx x;
3897 register int i;
3898 register int j;
3899 register enum rtx_code code;
3900 register char *fmt;
3902 MEM_IN_STRUCT_P (x) = 0;
3903 if (RTX_UNCHANGING_P (x))
3904 return;
3906 code = GET_CODE (x);
3908 switch (code)
3910 case REG:
3911 case QUEUED:
3912 case CONST_INT:
3913 case CONST_DOUBLE:
3914 case SYMBOL_REF:
3915 case CODE_LABEL:
3916 case PC:
3917 case CC0:
3918 case EQ_ATTR:
3919 case ATTR_FLAG:
3920 return;
3922 default:
3923 break;
3926 /* Compare the elements. If any pair of corresponding elements
3927 fail to match, return 0 for the whole things. */
3929 fmt = GET_RTX_FORMAT (code);
3930 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3932 switch (fmt[i])
3934 case 'V':
3935 case 'E':
3936 for (j = 0; j < XVECLEN (x, i); j++)
3937 clear_struct_flag (XVECEXP (x, i, j));
3938 break;
3940 case 'e':
3941 clear_struct_flag (XEXP (x, i));
3942 break;
3947 /* Return the number of RTX objects making up the expression X.
3948 But if we count more more than MAX objects, stop counting. */
3950 static int
3951 count_sub_rtxs (x, max)
3952 rtx x;
3953 int max;
3955 register int i;
3956 register int j;
3957 register enum rtx_code code;
3958 register char *fmt;
3959 int total = 0;
3961 code = GET_CODE (x);
3963 switch (code)
3965 case REG:
3966 case QUEUED:
3967 case CONST_INT:
3968 case CONST_DOUBLE:
3969 case SYMBOL_REF:
3970 case CODE_LABEL:
3971 case PC:
3972 case CC0:
3973 case EQ_ATTR:
3974 case ATTR_FLAG:
3975 return 1;
3977 default:
3978 break;
3981 /* Compare the elements. If any pair of corresponding elements
3982 fail to match, return 0 for the whole things. */
3984 fmt = GET_RTX_FORMAT (code);
3985 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
3987 if (total >= max)
3988 return total;
3990 switch (fmt[i])
3992 case 'V':
3993 case 'E':
3994 for (j = 0; j < XVECLEN (x, i); j++)
3995 total += count_sub_rtxs (XVECEXP (x, i, j), max);
3996 break;
3998 case 'e':
3999 total += count_sub_rtxs (XEXP (x, i), max);
4000 break;
4003 return total;
4007 /* Create table entries for DEFINE_ATTR. */
4009 static void
4010 gen_attr (exp)
4011 rtx exp;
4013 struct attr_desc *attr;
4014 struct attr_value *av;
4015 char *name_ptr;
4016 char *p;
4018 /* Make a new attribute structure. Check for duplicate by looking at
4019 attr->default_val, since it is initialized by this routine. */
4020 attr = find_attr (XSTR (exp, 0), 1);
4021 if (attr->default_val)
4022 fatal ("Duplicate definition for `%s' attribute", attr->name);
4024 if (*XSTR (exp, 1) == '\0')
4025 attr->is_numeric = 1;
4026 else
4028 name_ptr = XSTR (exp, 1);
4029 while ((p = next_comma_elt (&name_ptr)) != NULL)
4031 av = (struct attr_value *) oballoc (sizeof (struct attr_value));
4032 av->value = attr_rtx (CONST_STRING, p);
4033 av->next = attr->first_value;
4034 attr->first_value = av;
4035 av->first_insn = NULL;
4036 av->num_insns = 0;
4037 av->has_asm_insn = 0;
4041 if (GET_CODE (XEXP (exp, 2)) == CONST)
4043 attr->is_const = 1;
4044 if (attr->is_numeric)
4045 fatal ("Constant attributes may not take numeric values");
4046 /* Get rid of the CONST node. It is allowed only at top-level. */
4047 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
4050 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
4051 fatal ("`length' attribute must take numeric values");
4053 /* Set up the default value. */
4054 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr);
4055 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
4058 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
4059 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
4060 number of alternatives as this should be checked elsewhere. */
4062 static int
4063 count_alternatives (exp)
4064 rtx exp;
4066 int i, j, n;
4067 char *fmt;
4069 if (GET_CODE (exp) == MATCH_OPERAND)
4070 return n_comma_elts (XSTR (exp, 2));
4072 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4073 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4074 switch (*fmt++)
4076 case 'e':
4077 case 'u':
4078 n = count_alternatives (XEXP (exp, i));
4079 if (n)
4080 return n;
4081 break;
4083 case 'E':
4084 case 'V':
4085 if (XVEC (exp, i) != NULL)
4086 for (j = 0; j < XVECLEN (exp, i); j++)
4088 n = count_alternatives (XVECEXP (exp, i, j));
4089 if (n)
4090 return n;
4094 return 0;
4097 /* Returns non-zero if the given expression contains an EQ_ATTR with the
4098 `alternative' attribute. */
4100 static int
4101 compares_alternatives_p (exp)
4102 rtx exp;
4104 int i, j;
4105 char *fmt;
4107 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
4108 return 1;
4110 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4111 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4112 switch (*fmt++)
4114 case 'e':
4115 case 'u':
4116 if (compares_alternatives_p (XEXP (exp, i)))
4117 return 1;
4118 break;
4120 case 'E':
4121 for (j = 0; j < XVECLEN (exp, i); j++)
4122 if (compares_alternatives_p (XVECEXP (exp, i, j)))
4123 return 1;
4124 break;
4127 return 0;
4130 /* Returns non-zero is INNER is contained in EXP. */
4132 static int
4133 contained_in_p (inner, exp)
4134 rtx inner;
4135 rtx exp;
4137 int i, j;
4138 char *fmt;
4140 if (rtx_equal_p (inner, exp))
4141 return 1;
4143 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
4144 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
4145 switch (*fmt++)
4147 case 'e':
4148 case 'u':
4149 if (contained_in_p (inner, XEXP (exp, i)))
4150 return 1;
4151 break;
4153 case 'E':
4154 for (j = 0; j < XVECLEN (exp, i); j++)
4155 if (contained_in_p (inner, XVECEXP (exp, i, j)))
4156 return 1;
4157 break;
4160 return 0;
4163 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
4165 static void
4166 gen_insn (exp)
4167 rtx exp;
4169 struct insn_def *id;
4171 id = (struct insn_def *) oballoc (sizeof (struct insn_def));
4172 id->next = defs;
4173 defs = id;
4174 id->def = exp;
4176 switch (GET_CODE (exp))
4178 case DEFINE_INSN:
4179 id->insn_code = insn_code_number++;
4180 id->insn_index = insn_index_number++;
4181 id->num_alternatives = count_alternatives (exp);
4182 if (id->num_alternatives == 0)
4183 id->num_alternatives = 1;
4184 id->vec_idx = 4;
4185 break;
4187 case DEFINE_PEEPHOLE:
4188 id->insn_code = insn_code_number++;
4189 id->insn_index = insn_index_number++;
4190 id->num_alternatives = count_alternatives (exp);
4191 if (id->num_alternatives == 0)
4192 id->num_alternatives = 1;
4193 id->vec_idx = 3;
4194 break;
4196 case DEFINE_ASM_ATTRIBUTES:
4197 id->insn_code = -1;
4198 id->insn_index = -1;
4199 id->num_alternatives = 1;
4200 id->vec_idx = 0;
4201 got_define_asm_attributes = 1;
4202 break;
4204 default:
4205 abort ();
4209 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
4210 true or annul false is specified, and make a `struct delay_desc'. */
4212 static void
4213 gen_delay (def)
4214 rtx def;
4216 struct delay_desc *delay;
4217 int i;
4219 if (XVECLEN (def, 1) % 3 != 0)
4220 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
4222 for (i = 0; i < XVECLEN (def, 1); i += 3)
4224 if (XVECEXP (def, 1, i + 1))
4225 have_annul_true = 1;
4226 if (XVECEXP (def, 1, i + 2))
4227 have_annul_false = 1;
4230 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc));
4231 delay->def = def;
4232 delay->num = ++num_delays;
4233 delay->next = delays;
4234 delays = delay;
4237 /* Process a DEFINE_FUNCTION_UNIT.
4239 This gives information about a function unit contained in the CPU.
4240 We fill in a `struct function_unit_op' and a `struct function_unit'
4241 with information used later by `expand_unit'. */
4243 static void
4244 gen_unit (def)
4245 rtx def;
4247 struct function_unit *unit;
4248 struct function_unit_op *op;
4249 char *name = XSTR (def, 0);
4250 int multiplicity = XINT (def, 1);
4251 int simultaneity = XINT (def, 2);
4252 rtx condexp = XEXP (def, 3);
4253 int ready_cost = MAX (XINT (def, 4), 1);
4254 int issue_delay = MAX (XINT (def, 5), 1);
4256 /* See if we have already seen this function unit. If so, check that
4257 the multiplicity and simultaneity values are the same. If not, make
4258 a structure for this function unit. */
4259 for (unit = units; unit; unit = unit->next)
4260 if (! strcmp (unit->name, name))
4262 if (unit->multiplicity != multiplicity
4263 || unit->simultaneity != simultaneity)
4264 fatal ("Differing specifications given for `%s' function unit.",
4265 unit->name);
4266 break;
4269 if (unit == 0)
4271 unit = (struct function_unit *) oballoc (sizeof (struct function_unit));
4272 unit->name = name;
4273 unit->multiplicity = multiplicity;
4274 unit->simultaneity = simultaneity;
4275 unit->issue_delay.min = unit->issue_delay.max = issue_delay;
4276 unit->num = num_units++;
4277 unit->num_opclasses = 0;
4278 unit->condexp = false_rtx;
4279 unit->ops = 0;
4280 unit->next = units;
4281 units = unit;
4284 /* Make a new operation class structure entry and initialize it. */
4285 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op));
4286 op->condexp = condexp;
4287 op->num = unit->num_opclasses++;
4288 op->ready = ready_cost;
4289 op->issue_delay = issue_delay;
4290 op->next = unit->ops;
4291 unit->ops = op;
4293 /* Set our issue expression based on whether or not an optional conflict
4294 vector was specified. */
4295 if (XVEC (def, 6))
4297 /* Compute the IOR of all the specified expressions. */
4298 rtx orexp = false_rtx;
4299 int i;
4301 for (i = 0; i < XVECLEN (def, 6); i++)
4302 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2);
4304 op->conflict_exp = orexp;
4305 extend_range (&unit->issue_delay, 1, issue_delay);
4307 else
4309 op->conflict_exp = true_rtx;
4310 extend_range (&unit->issue_delay, issue_delay, issue_delay);
4313 /* Merge our conditional into that of the function unit so we can determine
4314 which insns are used by the function unit. */
4315 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2);
4318 /* Given a piece of RTX, print a C expression to test its truth value.
4319 We use AND and IOR both for logical and bit-wise operations, so
4320 interpret them as logical unless they are inside a comparison expression.
4321 The second operand of this function will be non-zero in that case. */
4323 static void
4324 write_test_expr (exp, in_comparison)
4325 rtx exp;
4326 int in_comparison;
4328 int comparison_operator = 0;
4329 RTX_CODE code;
4330 struct attr_desc *attr;
4332 /* In order not to worry about operator precedence, surround our part of
4333 the expression with parentheses. */
4335 printf ("(");
4336 code = GET_CODE (exp);
4337 switch (code)
4339 /* Binary operators. */
4340 case EQ: case NE:
4341 case GE: case GT: case GEU: case GTU:
4342 case LE: case LT: case LEU: case LTU:
4343 comparison_operator = 1;
4345 case PLUS: case MINUS: case MULT: case DIV: case MOD:
4346 case AND: case IOR: case XOR:
4347 case ASHIFT: case LSHIFTRT: case ASHIFTRT:
4348 write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator);
4349 switch (code)
4351 case EQ:
4352 printf (" == ");
4353 break;
4354 case NE:
4355 printf (" != ");
4356 break;
4357 case GE:
4358 printf (" >= ");
4359 break;
4360 case GT:
4361 printf (" > ");
4362 break;
4363 case GEU:
4364 printf (" >= (unsigned) ");
4365 break;
4366 case GTU:
4367 printf (" > (unsigned) ");
4368 break;
4369 case LE:
4370 printf (" <= ");
4371 break;
4372 case LT:
4373 printf (" < ");
4374 break;
4375 case LEU:
4376 printf (" <= (unsigned) ");
4377 break;
4378 case LTU:
4379 printf (" < (unsigned) ");
4380 break;
4381 case PLUS:
4382 printf (" + ");
4383 break;
4384 case MINUS:
4385 printf (" - ");
4386 break;
4387 case MULT:
4388 printf (" * ");
4389 break;
4390 case DIV:
4391 printf (" / ");
4392 break;
4393 case MOD:
4394 printf (" %% ");
4395 break;
4396 case AND:
4397 if (in_comparison)
4398 printf (" & ");
4399 else
4400 printf (" && ");
4401 break;
4402 case IOR:
4403 if (in_comparison)
4404 printf (" | ");
4405 else
4406 printf (" || ");
4407 break;
4408 case XOR:
4409 printf (" ^ ");
4410 break;
4411 case ASHIFT:
4412 printf (" << ");
4413 break;
4414 case LSHIFTRT:
4415 case ASHIFTRT:
4416 printf (" >> ");
4417 break;
4418 default:
4419 abort ();
4422 write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator);
4423 break;
4425 case NOT:
4426 /* Special-case (not (eq_attrq "alternative" "x")) */
4427 if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
4428 && XSTR (XEXP (exp, 0), 0) == alternative_name)
4430 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
4431 break;
4434 /* Otherwise, fall through to normal unary operator. */
4436 /* Unary operators. */
4437 case ABS: case NEG:
4438 switch (code)
4440 case NOT:
4441 if (in_comparison)
4442 printf ("~ ");
4443 else
4444 printf ("! ");
4445 break;
4446 case ABS:
4447 printf ("abs ");
4448 break;
4449 case NEG:
4450 printf ("-");
4451 break;
4452 default:
4453 abort ();
4456 write_test_expr (XEXP (exp, 0), in_comparison);
4457 break;
4459 /* Comparison test of an attribute with a value. Most of these will
4460 have been removed by optimization. Handle "alternative"
4461 specially and give error if EQ_ATTR present inside a comparison. */
4462 case EQ_ATTR:
4463 if (in_comparison)
4464 fatal ("EQ_ATTR not valid inside comparison");
4466 if (XSTR (exp, 0) == alternative_name)
4468 printf ("which_alternative == %s", XSTR (exp, 1));
4469 break;
4472 attr = find_attr (XSTR (exp, 0), 0);
4473 if (! attr) abort ();
4475 /* Now is the time to expand the value of a constant attribute. */
4476 if (attr->is_const)
4478 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value,
4479 -2, -2),
4480 in_comparison);
4482 else
4484 printf ("get_attr_%s (insn) == ", attr->name);
4485 write_attr_valueq (attr, XSTR (exp, 1));
4487 break;
4489 /* Comparison test of flags for define_delays. */
4490 case ATTR_FLAG:
4491 if (in_comparison)
4492 fatal ("ATTR_FLAG not valid inside comparison");
4493 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0));
4494 break;
4496 /* See if an operand matches a predicate. */
4497 case MATCH_OPERAND:
4498 /* If only a mode is given, just ensure the mode matches the operand.
4499 If neither a mode nor predicate is given, error. */
4500 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
4502 if (GET_MODE (exp) == VOIDmode)
4503 fatal ("Null MATCH_OPERAND specified as test");
4504 else
4505 printf ("GET_MODE (operands[%d]) == %smode",
4506 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4508 else
4509 printf ("%s (operands[%d], %smode)",
4510 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
4511 break;
4513 /* Constant integer. */
4514 case CONST_INT:
4515 #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
4516 printf ("%d", XWINT (exp, 0));
4517 #else
4518 printf ("%ld", XWINT (exp, 0));
4519 #endif
4520 break;
4522 /* A random C expression. */
4523 case SYMBOL_REF:
4524 printf ("%s", XSTR (exp, 0));
4525 break;
4527 /* The address of the branch target. */
4528 case MATCH_DUP:
4529 printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]",
4530 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0));
4531 break;
4533 /* The address of the current insn. It would be more consistent with
4534 other usage to make this the address of the NEXT insn, but this gets
4535 too confusing because of the ambiguity regarding the length of the
4536 current insn. */
4537 case PC:
4538 printf ("insn_current_address");
4539 break;
4541 default:
4542 fatal ("bad RTX code `%s' in attribute calculation\n",
4543 GET_RTX_NAME (code));
4546 printf (")");
4549 /* Given an attribute value, return the maximum CONST_STRING argument
4550 encountered. It is assumed that they are all numeric. */
4552 static int
4553 max_attr_value (exp)
4554 rtx exp;
4556 int current_max = 0;
4557 int n;
4558 int i;
4560 if (GET_CODE (exp) == CONST_STRING)
4561 return atoi (XSTR (exp, 0));
4563 else if (GET_CODE (exp) == COND)
4565 for (i = 0; i < XVECLEN (exp, 0); i += 2)
4567 n = max_attr_value (XVECEXP (exp, 0, i + 1));
4568 if (n > current_max)
4569 current_max = n;
4572 n = max_attr_value (XEXP (exp, 1));
4573 if (n > current_max)
4574 current_max = n;
4577 else if (GET_CODE (exp) == IF_THEN_ELSE)
4579 current_max = max_attr_value (XEXP (exp, 1));
4580 n = max_attr_value (XEXP (exp, 2));
4581 if (n > current_max)
4582 current_max = n;
4585 else
4586 abort ();
4588 return current_max;
4591 /* Scan an attribute value, possibly a conditional, and record what actions
4592 will be required to do any conditional tests in it.
4594 Specifically, set
4595 `must_extract' if we need to extract the insn operands
4596 `must_constrain' if we must compute `which_alternative'
4597 `address_used' if an address expression was used
4598 `length_used' if an (eq_attr "length" ...) was used
4601 static void
4602 walk_attr_value (exp)
4603 rtx exp;
4605 register int i, j;
4606 register char *fmt;
4607 RTX_CODE code;
4609 if (exp == NULL)
4610 return;
4612 code = GET_CODE (exp);
4613 switch (code)
4615 case SYMBOL_REF:
4616 if (! RTX_UNCHANGING_P (exp))
4617 /* Since this is an arbitrary expression, it can look at anything.
4618 However, constant expressions do not depend on any particular
4619 insn. */
4620 must_extract = must_constrain = 1;
4621 return;
4623 case MATCH_OPERAND:
4624 must_extract = 1;
4625 return;
4627 case EQ_ATTR:
4628 if (XSTR (exp, 0) == alternative_name)
4629 must_extract = must_constrain = 1;
4630 else if (strcmp (XSTR (exp, 0), "length") == 0)
4631 length_used = 1;
4632 return;
4634 case MATCH_DUP:
4635 must_extract = 1;
4636 address_used = 1;
4637 return;
4639 case PC:
4640 address_used = 1;
4641 return;
4643 case ATTR_FLAG:
4644 return;
4646 default:
4647 break;
4650 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
4651 switch (*fmt++)
4653 case 'e':
4654 case 'u':
4655 walk_attr_value (XEXP (exp, i));
4656 break;
4658 case 'E':
4659 if (XVEC (exp, i) != NULL)
4660 for (j = 0; j < XVECLEN (exp, i); j++)
4661 walk_attr_value (XVECEXP (exp, i, j));
4662 break;
4666 /* Write out a function to obtain the attribute for a given INSN. */
4668 static void
4669 write_attr_get (attr)
4670 struct attr_desc *attr;
4672 struct attr_value *av, *common_av;
4674 /* Find the most used attribute value. Handle that as the `default' of the
4675 switch we will generate. */
4676 common_av = find_most_used (attr);
4678 /* Write out start of function, then all values with explicit `case' lines,
4679 then a `default', then the value with the most uses. */
4680 if (!attr->is_numeric)
4681 printf ("enum attr_%s\n", attr->name);
4682 else if (attr->unsigned_p)
4683 printf ("unsigned int\n");
4684 else
4685 printf ("int\n");
4687 /* If the attribute name starts with a star, the remainder is the name of
4688 the subroutine to use, instead of `get_attr_...'. */
4689 if (attr->name[0] == '*')
4690 printf ("%s (insn)\n", &attr->name[1]);
4691 else if (attr->is_const == 0)
4692 printf ("get_attr_%s (insn)\n", attr->name);
4693 else
4695 printf ("get_attr_%s ()\n", attr->name);
4696 printf ("{\n");
4698 for (av = attr->first_value; av; av = av->next)
4699 if (av->num_insns != 0)
4700 write_attr_set (attr, 2, av->value, "return", ";",
4701 true_rtx, av->first_insn->insn_code,
4702 av->first_insn->insn_index);
4704 printf ("}\n\n");
4705 return;
4707 printf (" rtx insn;\n");
4708 printf ("{\n");
4709 printf (" switch (recog_memoized (insn))\n");
4710 printf (" {\n");
4712 for (av = attr->first_value; av; av = av->next)
4713 if (av != common_av)
4714 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
4716 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
4717 printf (" }\n}\n\n");
4720 /* Given an AND tree of known true terms (because we are inside an `if' with
4721 that as the condition or are in an `else' clause) and an expression,
4722 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4723 the bulk of the work. */
4725 static rtx
4726 eliminate_known_true (known_true, exp, insn_code, insn_index)
4727 rtx known_true;
4728 rtx exp;
4729 int insn_code, insn_index;
4731 rtx term;
4733 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
4735 if (GET_CODE (known_true) == AND)
4737 exp = eliminate_known_true (XEXP (known_true, 0), exp,
4738 insn_code, insn_index);
4739 exp = eliminate_known_true (XEXP (known_true, 1), exp,
4740 insn_code, insn_index);
4742 else
4744 term = known_true;
4745 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
4748 return exp;
4751 /* Write out a series of tests and assignment statements to perform tests and
4752 sets of an attribute value. We are passed an indentation amount and prefix
4753 and suffix strings to write around each attribute value (e.g., "return"
4754 and ";"). */
4756 static void
4757 write_attr_set (attr, indent, value, prefix, suffix, known_true,
4758 insn_code, insn_index)
4759 struct attr_desc *attr;
4760 int indent;
4761 rtx value;
4762 char *prefix;
4763 char *suffix;
4764 rtx known_true;
4765 int insn_code, insn_index;
4767 if (GET_CODE (value) == CONST_STRING)
4769 write_indent (indent);
4770 printf ("%s ", prefix);
4771 write_attr_value (attr, value);
4772 printf ("%s\n", suffix);
4774 else if (GET_CODE (value) == COND)
4776 /* Assume the default value will be the default of the COND unless we
4777 find an always true expression. */
4778 rtx default_val = XEXP (value, 1);
4779 rtx our_known_true = known_true;
4780 rtx newexp;
4781 int first_if = 1;
4782 int i;
4784 for (i = 0; i < XVECLEN (value, 0); i += 2)
4786 rtx testexp;
4787 rtx inner_true;
4789 testexp = eliminate_known_true (our_known_true,
4790 XVECEXP (value, 0, i),
4791 insn_code, insn_index);
4792 newexp = attr_rtx (NOT, testexp);
4793 newexp = insert_right_side (AND, our_known_true, newexp,
4794 insn_code, insn_index);
4796 /* If the test expression is always true or if the next `known_true'
4797 expression is always false, this is the last case, so break
4798 out and let this value be the `else' case. */
4799 if (testexp == true_rtx || newexp == false_rtx)
4801 default_val = XVECEXP (value, 0, i + 1);
4802 break;
4805 /* Compute the expression to pass to our recursive call as being
4806 known true. */
4807 inner_true = insert_right_side (AND, our_known_true,
4808 testexp, insn_code, insn_index);
4810 /* If this is always false, skip it. */
4811 if (inner_true == false_rtx)
4812 continue;
4814 write_indent (indent);
4815 printf ("%sif ", first_if ? "" : "else ");
4816 first_if = 0;
4817 write_test_expr (testexp, 0);
4818 printf ("\n");
4819 write_indent (indent + 2);
4820 printf ("{\n");
4822 write_attr_set (attr, indent + 4,
4823 XVECEXP (value, 0, i + 1), prefix, suffix,
4824 inner_true, insn_code, insn_index);
4825 write_indent (indent + 2);
4826 printf ("}\n");
4827 our_known_true = newexp;
4830 if (! first_if)
4832 write_indent (indent);
4833 printf ("else\n");
4834 write_indent (indent + 2);
4835 printf ("{\n");
4838 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
4839 prefix, suffix, our_known_true, insn_code, insn_index);
4841 if (! first_if)
4843 write_indent (indent + 2);
4844 printf ("}\n");
4847 else
4848 abort ();
4851 /* Write out the computation for one attribute value. */
4853 static void
4854 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent,
4855 known_true)
4856 struct attr_desc *attr;
4857 struct attr_value *av;
4858 int write_case_lines;
4859 char *prefix, *suffix;
4860 int indent;
4861 rtx known_true;
4863 struct insn_ent *ie;
4865 if (av->num_insns == 0)
4866 return;
4868 if (av->has_asm_insn)
4870 write_indent (indent);
4871 printf ("case -1:\n");
4872 write_indent (indent + 2);
4873 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4874 write_indent (indent + 2);
4875 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
4876 write_indent (indent + 2);
4877 printf (" fatal_insn_not_found (insn);\n");
4880 if (write_case_lines)
4882 for (ie = av->first_insn; ie; ie = ie->next)
4883 if (ie->insn_code != -1)
4885 write_indent (indent);
4886 printf ("case %d:\n", ie->insn_code);
4889 else
4891 write_indent (indent);
4892 printf ("default:\n");
4895 /* See what we have to do to output this value. */
4896 must_extract = must_constrain = address_used = 0;
4897 walk_attr_value (av->value);
4899 if (must_extract)
4901 write_indent (indent + 2);
4902 printf ("insn_extract (insn);\n");
4905 if (must_constrain)
4907 #ifdef REGISTER_CONSTRAINTS
4908 write_indent (indent + 2);
4909 printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
4910 write_indent (indent + 2);
4911 printf (" fatal_insn_not_found (insn);\n");
4912 #endif
4915 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
4916 known_true, av->first_insn->insn_code,
4917 av->first_insn->insn_index);
4919 if (strncmp (prefix, "return", 6))
4921 write_indent (indent + 2);
4922 printf ("break;\n");
4924 printf ("\n");
4927 /* Utilities to write names in various forms. */
4929 static void
4930 write_attr_valueq (attr, s)
4931 struct attr_desc *attr;
4932 char *s;
4934 if (attr->is_numeric)
4936 printf ("%s", s);
4937 /* Make the blockage range values easier to read. */
4938 if (strlen (s) > 1)
4939 printf (" /* 0x%x */", atoi (s));
4941 else
4943 write_upcase (attr->name);
4944 printf ("_");
4945 write_upcase (s);
4949 static void
4950 write_attr_value (attr, value)
4951 struct attr_desc *attr;
4952 rtx value;
4954 if (GET_CODE (value) != CONST_STRING)
4955 abort ();
4957 write_attr_valueq (attr, XSTR (value, 0));
4960 static void
4961 write_upcase (str)
4962 char *str;
4964 while (*str)
4965 if (*str < 'a' || *str > 'z')
4966 printf ("%c", *str++);
4967 else
4968 printf ("%c", *str++ - 'a' + 'A');
4971 static void
4972 write_indent (indent)
4973 int indent;
4975 for (; indent > 8; indent -= 8)
4976 printf ("\t");
4978 for (; indent; indent--)
4979 printf (" ");
4982 /* Write a subroutine that is given an insn that requires a delay slot, a
4983 delay slot ordinal, and a candidate insn. It returns non-zero if the
4984 candidate can be placed in the specified delay slot of the insn.
4986 We can write as many as three subroutines. `eligible_for_delay'
4987 handles normal delay slots, `eligible_for_annul_true' indicates that
4988 the specified insn can be annulled if the branch is true, and likewise
4989 for `eligible_for_annul_false'.
4991 KIND is a string distinguishing these three cases ("delay", "annul_true",
4992 or "annul_false"). */
4994 static void
4995 write_eligible_delay (kind)
4996 char *kind;
4998 struct delay_desc *delay;
4999 int max_slots;
5000 char str[50];
5001 struct attr_desc *attr;
5002 struct attr_value *av, *common_av;
5003 int i;
5005 /* Compute the maximum number of delay slots required. We use the delay
5006 ordinal times this number plus one, plus the slot number as an index into
5007 the appropriate predicate to test. */
5009 for (delay = delays, max_slots = 0; delay; delay = delay->next)
5010 if (XVECLEN (delay->def, 1) / 3 > max_slots)
5011 max_slots = XVECLEN (delay->def, 1) / 3;
5013 /* Write function prelude. */
5015 printf ("int\n");
5016 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n",
5017 kind);
5018 printf (" rtx delay_insn;\n");
5019 printf (" int slot;\n");
5020 printf (" rtx candidate_insn;\n");
5021 printf (" int flags;\n");
5022 printf ("{\n");
5023 printf (" rtx insn;\n");
5024 printf ("\n");
5025 printf (" if (slot >= %d)\n", max_slots);
5026 printf (" abort ();\n");
5027 printf ("\n");
5029 /* If more than one delay type, find out which type the delay insn is. */
5031 if (num_delays > 1)
5033 attr = find_attr ("*delay_type", 0);
5034 if (! attr) abort ();
5035 common_av = find_most_used (attr);
5037 printf (" insn = delay_insn;\n");
5038 printf (" switch (recog_memoized (insn))\n");
5039 printf (" {\n");
5041 sprintf (str, " * %d;\n break;", max_slots);
5042 for (av = attr->first_value; av; av = av->next)
5043 if (av != common_av)
5044 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
5046 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
5047 printf (" }\n\n");
5049 /* Ensure matched. Otherwise, shouldn't have been called. */
5050 printf (" if (slot < %d)\n", max_slots);
5051 printf (" abort ();\n\n");
5054 /* If just one type of delay slot, write simple switch. */
5055 if (num_delays == 1 && max_slots == 1)
5057 printf (" insn = candidate_insn;\n");
5058 printf (" switch (recog_memoized (insn))\n");
5059 printf (" {\n");
5061 attr = find_attr ("*delay_1_0", 0);
5062 if (! attr) abort ();
5063 common_av = find_most_used (attr);
5065 for (av = attr->first_value; av; av = av->next)
5066 if (av != common_av)
5067 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
5069 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
5070 printf (" }\n");
5073 else
5075 /* Write a nested CASE. The first indicates which condition we need to
5076 test, and the inner CASE tests the condition. */
5077 printf (" insn = candidate_insn;\n");
5078 printf (" switch (slot)\n");
5079 printf (" {\n");
5081 for (delay = delays; delay; delay = delay->next)
5082 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
5084 printf (" case %d:\n",
5085 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
5086 printf (" switch (recog_memoized (insn))\n");
5087 printf ("\t{\n");
5089 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
5090 attr = find_attr (str, 0);
5091 if (! attr) abort ();
5092 common_av = find_most_used (attr);
5094 for (av = attr->first_value; av; av = av->next)
5095 if (av != common_av)
5096 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
5098 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
5099 printf (" }\n");
5102 printf (" default:\n");
5103 printf (" abort ();\n");
5104 printf (" }\n");
5107 printf ("}\n\n");
5110 /* Write routines to compute conflict cost for function units. Then write a
5111 table describing the available function units. */
5113 static void
5114 write_function_unit_info ()
5116 struct function_unit *unit;
5117 int i;
5119 /* Write out conflict routines for function units. Don't bother writing
5120 one if there is only one issue delay value. */
5122 for (unit = units; unit; unit = unit->next)
5124 if (unit->needs_blockage_function)
5125 write_complex_function (unit, "blockage", "block");
5127 /* If the minimum and maximum conflict costs are the same, there
5128 is only one value, so we don't need a function. */
5129 if (! unit->needs_conflict_function)
5131 unit->default_cost = make_numeric_value (unit->issue_delay.max);
5132 continue;
5135 /* The function first computes the case from the candidate insn. */
5136 unit->default_cost = make_numeric_value (0);
5137 write_complex_function (unit, "conflict_cost", "cost");
5140 /* Now that all functions have been written, write the table describing
5141 the function units. The name is included for documentation purposes
5142 only. */
5144 printf ("struct function_unit_desc function_units[] = {\n");
5146 /* Write out the descriptions in numeric order, but don't force that order
5147 on the list. Doing so increases the runtime of genattrtab.c. */
5148 for (i = 0; i < num_units; i++)
5150 for (unit = units; unit; unit = unit->next)
5151 if (unit->num == i)
5152 break;
5154 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ",
5155 unit->name, 1 << unit->num, unit->multiplicity,
5156 unit->simultaneity, XSTR (unit->default_cost, 0),
5157 unit->issue_delay.max, unit->name);
5159 if (unit->needs_conflict_function)
5160 printf ("%s_unit_conflict_cost, ", unit->name);
5161 else
5162 printf ("0, ");
5164 printf ("%d, ", unit->max_blockage);
5166 if (unit->needs_range_function)
5167 printf ("%s_unit_blockage_range, ", unit->name);
5168 else
5169 printf ("0, ");
5171 if (unit->needs_blockage_function)
5172 printf ("%s_unit_blockage", unit->name);
5173 else
5174 printf ("0");
5176 printf ("}, \n");
5179 printf ("};\n\n");
5182 static void
5183 write_complex_function (unit, name, connection)
5184 struct function_unit *unit;
5185 char *name, *connection;
5187 struct attr_desc *case_attr, *attr;
5188 struct attr_value *av, *common_av;
5189 rtx value;
5190 char *str;
5191 int using_case;
5192 int i;
5194 printf ("static int\n");
5195 printf ("%s_unit_%s (executing_insn, candidate_insn)\n",
5196 unit->name, name);
5197 printf (" rtx executing_insn;\n");
5198 printf (" rtx candidate_insn;\n");
5199 printf ("{\n");
5200 printf (" rtx insn;\n");
5201 printf (" int casenum;\n\n");
5202 printf (" insn = executing_insn;\n");
5203 printf (" switch (recog_memoized (insn))\n");
5204 printf (" {\n");
5206 /* Write the `switch' statement to get the case value. */
5207 str = (char *) alloca (strlen (unit->name) + strlen (name) + strlen (connection) + 10);
5208 sprintf (str, "*%s_cases", unit->name);
5209 case_attr = find_attr (str, 0);
5210 if (! case_attr) abort ();
5211 common_av = find_most_used (case_attr);
5213 for (av = case_attr->first_value; av; av = av->next)
5214 if (av != common_av)
5215 write_attr_case (case_attr, av, 1,
5216 "casenum =", ";", 4, unit->condexp);
5218 write_attr_case (case_attr, common_av, 0,
5219 "casenum =", ";", 4, unit->condexp);
5220 printf (" }\n\n");
5222 /* Now write an outer switch statement on each case. Then write
5223 the tests on the executing function within each. */
5224 printf (" insn = candidate_insn;\n");
5225 printf (" switch (casenum)\n");
5226 printf (" {\n");
5228 for (i = 0; i < unit->num_opclasses; i++)
5230 /* Ensure using this case. */
5231 using_case = 0;
5232 for (av = case_attr->first_value; av; av = av->next)
5233 if (av->num_insns
5234 && contained_in_p (make_numeric_value (i), av->value))
5235 using_case = 1;
5237 if (! using_case)
5238 continue;
5240 printf (" case %d:\n", i);
5241 sprintf (str, "*%s_%s_%d", unit->name, connection, i);
5242 attr = find_attr (str, 0);
5243 if (! attr) abort ();
5245 /* If single value, just write it. */
5246 value = find_single_value (attr);
5247 if (value)
5248 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2);
5249 else
5251 common_av = find_most_used (attr);
5252 printf (" switch (recog_memoized (insn))\n");
5253 printf ("\t{\n");
5255 for (av = attr->first_value; av; av = av->next)
5256 if (av != common_av)
5257 write_attr_case (attr, av, 1,
5258 "return", ";", 8, unit->condexp);
5260 write_attr_case (attr, common_av, 0,
5261 "return", ";", 8, unit->condexp);
5262 printf (" }\n\n");
5266 printf (" }\n}\n\n");
5269 /* This page contains miscellaneous utility routines. */
5271 /* Given a string, return the number of comma-separated elements in it.
5272 Return 0 for the null string. */
5274 static int
5275 n_comma_elts (s)
5276 char *s;
5278 int n;
5280 if (*s == '\0')
5281 return 0;
5283 for (n = 1; *s; s++)
5284 if (*s == ',')
5285 n++;
5287 return n;
5290 /* Given a pointer to a (char *), return a malloc'ed string containing the
5291 next comma-separated element. Advance the pointer to after the string
5292 scanned, or the end-of-string. Return NULL if at end of string. */
5294 static char *
5295 next_comma_elt (pstr)
5296 char **pstr;
5298 char *out_str;
5299 char *p;
5301 if (**pstr == '\0')
5302 return NULL;
5304 /* Find end of string to compute length. */
5305 for (p = *pstr; *p != ',' && *p != '\0'; p++)
5308 out_str = attr_string (*pstr, p - *pstr);
5309 *pstr = p;
5311 if (**pstr == ',')
5312 (*pstr)++;
5314 return out_str;
5317 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
5318 is non-zero, build a new attribute, if one does not exist. */
5320 static struct attr_desc *
5321 find_attr (name, create)
5322 char *name;
5323 int create;
5325 struct attr_desc *attr;
5326 int index;
5328 /* Before we resort to using `strcmp', see if the string address matches
5329 anywhere. In most cases, it should have been canonicalized to do so. */
5330 if (name == alternative_name)
5331 return NULL;
5333 index = name[0] & (MAX_ATTRS_INDEX - 1);
5334 for (attr = attrs[index]; attr; attr = attr->next)
5335 if (name == attr->name)
5336 return attr;
5338 /* Otherwise, do it the slow way. */
5339 for (attr = attrs[index]; attr; attr = attr->next)
5340 if (name[0] == attr->name[0] && ! strcmp (name, attr->name))
5341 return attr;
5343 if (! create)
5344 return NULL;
5346 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc));
5347 attr->name = attr_string (name, strlen (name));
5348 attr->first_value = attr->default_val = NULL;
5349 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0;
5350 attr->next = attrs[index];
5351 attrs[index] = attr;
5353 return attr;
5356 /* Create internal attribute with the given default value. */
5358 static void
5359 make_internal_attr (name, value, special)
5360 char *name;
5361 rtx value;
5362 int special;
5364 struct attr_desc *attr;
5366 attr = find_attr (name, 1);
5367 if (attr->default_val)
5368 abort ();
5370 attr->is_numeric = 1;
5371 attr->is_const = 0;
5372 attr->is_special = (special & 1) != 0;
5373 attr->negative_ok = (special & 2) != 0;
5374 attr->unsigned_p = (special & 4) != 0;
5375 attr->default_val = get_attr_value (value, attr, -2);
5378 /* Find the most used value of an attribute. */
5380 static struct attr_value *
5381 find_most_used (attr)
5382 struct attr_desc *attr;
5384 struct attr_value *av;
5385 struct attr_value *most_used;
5386 int nuses;
5388 most_used = NULL;
5389 nuses = -1;
5391 for (av = attr->first_value; av; av = av->next)
5392 if (av->num_insns > nuses)
5393 nuses = av->num_insns, most_used = av;
5395 return most_used;
5398 /* If an attribute only has a single value used, return it. Otherwise
5399 return NULL. */
5401 static rtx
5402 find_single_value (attr)
5403 struct attr_desc *attr;
5405 struct attr_value *av;
5406 rtx unique_value;
5408 unique_value = NULL;
5409 for (av = attr->first_value; av; av = av->next)
5410 if (av->num_insns)
5412 if (unique_value)
5413 return NULL;
5414 else
5415 unique_value = av->value;
5418 return unique_value;
5421 /* Return (attr_value "n") */
5423 static rtx
5424 make_numeric_value (n)
5425 int n;
5427 static rtx int_values[20];
5428 rtx exp;
5429 char *p;
5431 if (n < 0)
5432 abort ();
5434 if (n < 20 && int_values[n])
5435 return int_values[n];
5437 p = attr_printf (MAX_DIGITS, "%d", n);
5438 exp = attr_rtx (CONST_STRING, p);
5440 if (n < 20)
5441 int_values[n] = exp;
5443 return exp;
5446 static void
5447 extend_range (range, min, max)
5448 struct range *range;
5449 int min;
5450 int max;
5452 if (range->min > min) range->min = min;
5453 if (range->max < max) range->max = max;
5456 char *
5457 xrealloc (ptr, size)
5458 char *ptr;
5459 unsigned size;
5461 char *result = (char *) realloc (ptr, size);
5462 if (!result)
5463 fatal ("virtual memory exhausted");
5464 return result;
5467 char *
5468 xmalloc (size)
5469 unsigned size;
5471 register char *val = (char *) malloc (size);
5473 if (val == 0)
5474 fatal ("virtual memory exhausted");
5475 return val;
5478 static rtx
5479 copy_rtx_unchanging (orig)
5480 register rtx orig;
5482 #if 0
5483 register rtx copy;
5484 register RTX_CODE code;
5485 #endif
5487 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig))
5488 return orig;
5490 MEM_IN_STRUCT_P (orig) = 1;
5491 return orig;
5493 #if 0
5494 code = GET_CODE (orig);
5495 switch (code)
5497 case CONST_INT:
5498 case CONST_DOUBLE:
5499 case SYMBOL_REF:
5500 case CODE_LABEL:
5501 return orig;
5503 default:
5504 break;
5507 copy = rtx_alloc (code);
5508 PUT_MODE (copy, GET_MODE (orig));
5509 RTX_UNCHANGING_P (copy) = 1;
5511 bcopy ((char *) &XEXP (orig, 0), (char *) &XEXP (copy, 0),
5512 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx));
5513 return copy;
5514 #endif
5517 #ifdef HAVE_VPRINTF
5518 void
5519 fatal VPROTO((char *s, ...))
5521 #ifndef ANSI_PROTOTYPES
5522 char *s;
5523 #endif
5524 va_list ap;
5526 VA_START (ap, s);
5528 #ifndef ANSI_PROTOTYPES
5529 s = va_arg (ap, char *);
5530 #endif
5532 fprintf (stderr, "genattrtab: ");
5533 vfprintf (stderr, s, ap);
5534 va_end (ap);
5535 fprintf (stderr, "\n");
5536 exit (FATAL_EXIT_CODE);
5538 #else /* not HAVE_VPRINTF */
5540 void
5541 fatal (s, a1, a2)
5542 char *s;
5544 fprintf (stderr, "genattrtab: ");
5545 fprintf (stderr, s, a1, a2);
5546 fprintf (stderr, "\n");
5547 exit (FATAL_EXIT_CODE);
5549 #endif /* not HAVE_VPRINTF */
5551 /* More 'friendly' abort that prints the line and file.
5552 config.h can #define abort fancy_abort if you like that sort of thing. */
5554 void
5555 fancy_abort ()
5557 fatal ("Internal gcc abort.");
5560 /* Determine if an insn has a constant number of delay slots, i.e., the
5561 number of delay slots is not a function of the length of the insn. */
5563 void
5564 write_const_num_delay_slots ()
5566 struct attr_desc *attr = find_attr ("*num_delay_slots", 0);
5567 struct attr_value *av;
5568 struct insn_ent *ie;
5569 int i;
5571 if (attr)
5573 printf ("int\nconst_num_delay_slots (insn)\n");
5574 printf (" rtx insn;\n");
5575 printf ("{\n");
5576 printf (" switch (recog_memoized (insn))\n");
5577 printf (" {\n");
5579 for (av = attr->first_value; av; av = av->next)
5581 length_used = 0;
5582 walk_attr_value (av->value);
5583 if (length_used)
5585 for (ie = av->first_insn; ie; ie = ie->next)
5586 if (ie->insn_code != -1)
5587 printf (" case %d:\n", ie->insn_code);
5588 printf (" return 0;\n");
5592 printf (" default:\n");
5593 printf (" return 1;\n");
5594 printf (" }\n}\n");
5600 main (argc, argv)
5601 int argc;
5602 char **argv;
5604 rtx desc;
5605 FILE *infile;
5606 register int c;
5607 struct attr_desc *attr;
5608 struct insn_def *id;
5609 rtx tem;
5610 int i;
5612 #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
5613 /* Get rid of any avoidable limit on stack size. */
5615 struct rlimit rlim;
5617 /* Set the stack limit huge so that alloca does not fail. */
5618 getrlimit (RLIMIT_STACK, &rlim);
5619 rlim.rlim_cur = rlim.rlim_max;
5620 setrlimit (RLIMIT_STACK, &rlim);
5622 #endif
5624 obstack_init (rtl_obstack);
5625 obstack_init (hash_obstack);
5626 obstack_init (temp_obstack);
5628 if (argc <= 1)
5629 fatal ("No input file name.");
5631 infile = fopen (argv[1], "r");
5632 if (infile == 0)
5634 perror (argv[1]);
5635 exit (FATAL_EXIT_CODE);
5638 init_rtl ();
5640 /* We don't use this, but it is referenced in rtlanal.c.
5641 Set it up correctly just in case someone tries to use it someday. */
5642 pc_rtx = rtx_alloc (PC);
5643 PUT_MODE (pc_rtx, VOIDmode);
5645 /* Set up true and false rtx's */
5646 true_rtx = rtx_alloc (CONST_INT);
5647 XWINT (true_rtx, 0) = 1;
5648 false_rtx = rtx_alloc (CONST_INT);
5649 XWINT (false_rtx, 0) = 0;
5650 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
5651 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1;
5653 alternative_name = attr_string ("alternative", strlen ("alternative"));
5655 printf ("/* Generated automatically by the program `genattrtab'\n\
5656 from the machine description file `md'. */\n\n");
5658 /* Read the machine description. */
5660 while (1)
5662 c = read_skip_spaces (infile);
5663 if (c == EOF)
5664 break;
5665 ungetc (c, infile);
5667 desc = read_rtx (infile);
5668 if (GET_CODE (desc) == DEFINE_INSN
5669 || GET_CODE (desc) == DEFINE_PEEPHOLE
5670 || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
5671 gen_insn (desc);
5673 else if (GET_CODE (desc) == DEFINE_EXPAND)
5674 insn_code_number++, insn_index_number++;
5676 else if (GET_CODE (desc) == DEFINE_SPLIT)
5677 insn_code_number++, insn_index_number++;
5679 else if (GET_CODE (desc) == DEFINE_ATTR)
5681 gen_attr (desc);
5682 insn_index_number++;
5685 else if (GET_CODE (desc) == DEFINE_DELAY)
5687 gen_delay (desc);
5688 insn_index_number++;
5691 else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
5693 gen_unit (desc);
5694 insn_index_number++;
5698 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5699 if (! got_define_asm_attributes)
5701 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
5702 XVEC (tem, 0) = rtvec_alloc (0);
5703 gen_insn (tem);
5706 /* Expand DEFINE_DELAY information into new attribute. */
5707 if (num_delays)
5708 expand_delays ();
5710 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
5711 if (num_units)
5712 expand_units ();
5714 printf ("#include \"config.h\"\n");
5715 printf ("#include \"system.h\"\n");
5716 printf ("#include \"rtl.h\"\n");
5717 printf ("#include \"insn-config.h\"\n");
5718 printf ("#include \"recog.h\"\n");
5719 printf ("#include \"regs.h\"\n");
5720 printf ("#include \"real.h\"\n");
5721 printf ("#include \"output.h\"\n");
5722 printf ("#include \"insn-attr.h\"\n");
5723 printf ("\n");
5724 printf ("#define operands recog_operand\n\n");
5726 /* Make `insn_alternatives'. */
5727 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
5728 for (id = defs; id; id = id->next)
5729 if (id->insn_code >= 0)
5730 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
5732 /* Make `insn_n_alternatives'. */
5733 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int));
5734 for (id = defs; id; id = id->next)
5735 if (id->insn_code >= 0)
5736 insn_n_alternatives[id->insn_code] = id->num_alternatives;
5738 /* Prepare to write out attribute subroutines by checking everything stored
5739 away and building the attribute cases. */
5741 check_defs ();
5742 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5743 for (attr = attrs[i]; attr; attr = attr->next)
5745 attr->default_val->value
5746 = check_attr_value (attr->default_val->value, attr);
5747 fill_attr (attr);
5750 /* Construct extra attributes for `length'. */
5751 make_length_attrs ();
5753 /* Perform any possible optimizations to speed up compilation. */
5754 optimize_attrs ();
5756 /* Now write out all the `gen_attr_...' routines. Do these before the
5757 special routines (specifically before write_function_unit_info), so
5758 that they get defined before they are used. */
5760 for (i = 0; i < MAX_ATTRS_INDEX; i++)
5761 for (attr = attrs[i]; attr; attr = attr->next)
5763 if (! attr->is_special)
5764 write_attr_get (attr);
5767 /* Write out delay eligibility information, if DEFINE_DELAY present.
5768 (The function to compute the number of delay slots will be written
5769 below.) */
5770 if (num_delays)
5772 write_eligible_delay ("delay");
5773 if (have_annul_true)
5774 write_eligible_delay ("annul_true");
5775 if (have_annul_false)
5776 write_eligible_delay ("annul_false");
5779 /* Write out information about function units. */
5780 if (num_units)
5781 write_function_unit_info ();
5783 /* Write out constant delay slot info */
5784 write_const_num_delay_slots ();
5786 fflush (stdout);
5787 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
5788 /* NOTREACHED */
5789 return 0;