1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@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)
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, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* This program handles insn attribues and the DEFINE_DELAY and
22 DEFINE_FUNCTION_UNIT definitions.
24 It produces a series of functions named `get_attr_...', one for each insn
25 attribute. Each of these is given the rtx for an insn and returns a member
26 of the enum for the attribute.
28 These subroutines have the form of a `switch' on the INSN_CODE (via
29 `recog_memoized'). Each case either returns a constant attribute value
30 or a value that depends on tests on other attributes, the form of
31 operands, or some random C expression (encoded with a SYMBOL_REF
34 If the attribute `alternative', or a random C expression is present,
35 `constrain_operands' is called. If either of these cases of a reference to
36 an operand is found, `insn_extract' is called.
38 The special attribute `length' is also recognized. For this operand,
39 expressions involving the address of an operand or the current insn,
40 (address (pc)), are valid. In this case, an initial pass is made to
41 set all lengths that do not depend on address. Those that do are set to
42 the maximum length. Then each insn that depends on an address is checked
43 and possibly has its length changed. The process repeats until no further
44 changed are made. The resulting lengths are saved for use by
47 A special form of DEFINE_ATTR, where the expression for default value is a
48 CONST expression, indicates an attribute that is constant for a given run
49 of the compiler. The subroutine generated for these attributes has no
50 parameters as it does not depend on any particular insn. Constant
51 attributes are typically used to specify which variety of processor is
54 Internal attributes are defined to handle DEFINE_DELAY and
55 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
57 This program works by keeping a list of possible values for each attribute.
58 These include the basic attribute choices, default values for attribute, and
59 all derived quantities.
61 As the description file is read, the definition for each insn is saved in a
62 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
63 is created for each insn and chained to the corresponding attribute value,
64 either that specified, or the default.
66 An optimization phase is then run. This simplifies expressions for each
67 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
68 indicates when the attribute has the specified value for the insn. This
69 avoids recursive calls during compilation.
71 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
72 definitions is to create arbitrarily complex expressions and have the
73 optimization simplify them.
75 Once optimization is complete, any required routines and definitions
78 An optimization that is not yet implemented is to hoist the constant
79 expressions entirely out of the routines and definitions that are written.
80 A way to do this is to iterate over all possible combinations of values
81 for constant attributes and generate a set of functions for that given
82 combination. An initialization function would be written that evaluates
83 the attributes and installs the corresponding set of routines and
84 definitions (each would be accessed through a pointer). */
91 #include "insn-config.h" /* For REGISTER_CONSTRAINTS */
93 static struct obstack obstack;
94 struct obstack *rtl_obstack = &obstack;
96 #define obstack_chunk_alloc xmalloc
97 #define obstack_chunk_free free
99 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
100 char **insn_name_ptr = 0;
103 extern rtx read_rtx ();
105 static void fatal ();
108 /* Define structures used to record attributes and values. */
110 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
111 encountered, we store all the relevant information into a
112 `struct insn_def'. This is done to allow attribute definitions to occur
113 anywhere in the file. */
117 int insn_code; /* Instruction number. */
118 int insn_index; /* Expression numer in file, for errors. */
119 struct insn_def *next; /* Next insn in chain. */
120 rtx def; /* The DEFINE_... */
121 int num_alternatives; /* Number of alternatives. */
122 int vec_idx; /* Index of attribute vector in `def'. */
125 /* Once everything has been read in, we store in each attribute value a list
126 of insn codes that have that value. Here is the structure used for the
131 int insn_code; /* Instruction number. */
132 int insn_index; /* Index of definition in file */
133 struct insn_ent *next; /* Next in chain. */
136 /* Each value of an attribute (either constant or computed) is assigned a
137 structure which is used as the listhead of the insns that have that
142 rtx value; /* Value of attribute. */
143 struct attr_value *next; /* Next attribute value in chain. */
144 struct insn_ent *first_insn; /* First insn with this value. */
145 int num_insns; /* Number of insns with this value. */
146 int has_asm_insn; /* True if this value used for `asm' insns */
149 /* Structure for each attribute. */
153 char *name; /* Name of attribute. */
154 struct attr_desc *next; /* Next attribute. */
155 int is_numeric; /* Values of this attribute are numeric. */
156 int is_const; /* Attribute value constant for each run. */
157 int is_special; /* Don't call `write_attr_set'. */
158 struct attr_value *first_value; /* First value of this attribute. */
159 struct attr_value *default_val; /* Default value for this attribute. */
162 /* Structure for each DEFINE_DELAY. */
166 rtx def; /* DEFINE_DELAY expression. */
167 struct delay_desc *next; /* Next DEFINE_DELAY. */
168 int num; /* Number of DEFINE_DELAY, starting at 1. */
171 /* Record information about each DEFINE_FUNCTION_UNIT. */
173 struct function_unit_op
175 rtx condexp; /* Expression TRUE for applicable insn. */
176 struct function_unit_op *next; /* Next operation for this function unit. */
177 int num; /* Ordinal for this operation type in unit. */
178 int ready; /* Cost until data is ready. */
179 rtx busyexp; /* Expression computing conflict cost. */
182 /* Record information about each function unit mentioned in a
183 DEFINE_FUNCTION_UNIT. */
187 char *name; /* Function unit name. */
188 struct function_unit *next; /* Next function unit. */
189 int num; /* Ordinal of this unit type. */
190 int multiplicity; /* Number of units of this type. */
191 int simultaneity; /* Maximum number of simultaneous insns
192 on this function unit or 0 if unlimited. */
193 rtx condexp; /* Expression TRUE for insn needing unit. */
194 rtx costexp; /* Worst-case cost as function of insn. */
195 int num_opclasses; /* Number of different operation types. */
196 struct function_unit_op *ops; /* Pointer to first operation type. */
197 int needs_conflict_function; /* Nonzero if a conflict function required. */
198 rtx default_cost; /* Conflict cost, if constant. */
201 /* Listheads of above structures. */
203 static struct attr_desc *attrs;
204 static struct insn_def *defs;
205 static struct delay_desc *delays;
206 static struct function_unit *units;
208 /* Other variables. */
210 static int insn_code_number;
211 static int insn_index_number;
212 static int got_define_asm_attributes;
213 static int must_extract;
214 static int must_constrain;
215 static int address_used;
216 static int num_delays;
217 static int have_annul_true, have_annul_false;
218 static int num_units;
220 /* Used as operand to `operate_exp': */
222 enum operator {PLUS_OP, MINUS_OP, OR_OP, MAX_OP};
224 /* Stores, for each insn code, a bitmap that has bits on for each possible
227 static int *insn_alternatives;
229 /* Used to simplify expressions. */
231 static rtx true_rtx, false_rtx;
233 /* Used to reduce calls to `strcmp' */
235 static char *alternative_name = "alternative";
237 /* Simplify an expression. Only call the routine if there is something to
239 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
240 (RTX_UNCHANGING_P (EXP) ? (EXP) \
241 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
243 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
244 They won't actually be used. */
246 rtx frame_pointer_rtx, stack_pointer_rtx, arg_pointer_rtx;
248 static rtx attr_rtx ();
249 static char *attr_printf ();
250 static char *attr_string ();
251 static rtx check_attr_test ();
252 static void check_attr_value ();
253 static rtx convert_set_attr_alternative ();
254 static rtx convert_set_attr ();
255 static void check_defs ();
256 static rtx convert_const_symbol_ref ();
257 static rtx make_canonical ();
258 static struct attr_value *get_attr_value ();
259 static void expand_delays ();
260 static rtx operate_exp ();
261 static void expand_units ();
262 static void fill_attr ();
263 static rtx substitute_address ();
264 static void make_length_attrs ();
265 static rtx identity_fn ();
266 static rtx zero_fn ();
267 static rtx one_fn ();
268 static rtx max_fn ();
269 static rtx simplify_cond ();
270 static void remove_insn_ent ();
271 static void insert_insn_ent ();
272 static rtx insert_right_side ();
273 static rtx make_alternative_compare ();
274 static int compute_alternative_mask ();
275 static rtx evaluate_eq_attr ();
276 static rtx simplify_and_tree ();
277 static rtx simplify_or_tree ();
278 static rtx simplify_test_exp ();
279 static void optimize_attrs ();
280 static void gen_attr ();
281 static int count_alternatives ();
282 static int compares_alternatives_p ();
283 static int contained_in_p ();
284 static void gen_insn ();
285 static void gen_delay ();
286 static void gen_unit ();
287 static void write_test_expr ();
288 static int max_attr_value ();
289 static void walk_attr_value ();
290 static void write_attr_get ();
291 static rtx eliminate_known_true ();
292 static void write_attr_set ();
293 static void write_attr_case ();
294 static void write_attr_value ();
295 static void write_attr_valueq ();
296 static void write_upcase ();
297 static void write_indent ();
298 static void write_eligible_delay ();
299 static void write_function_unit_info ();
300 static int n_comma_elts ();
301 static char *next_comma_elt ();
302 static struct attr_desc *find_attr ();
303 static void make_internal_attr ();
304 static struct attr_value *find_most_used ();
305 static rtx find_single_value ();
306 static rtx make_numeric_value ();
309 static void fatal ();
311 /* Hash table for sharing RTL and strings. */
313 /* Each hash table slot is a bucket containing a chain of these structures.
314 Strings are given negative hash codes; RTL expressions are given positive
319 struct attr_hash *next; /* Next structure in the bucket. */
320 int hashcode; /* Hash code of this rtx or string. */
323 char *str; /* The string (negative hash codes) */
324 rtx rtl; /* or the RTL recorded here. */
328 /* Now here is the hash table. When recording an RTL, it is added to
329 the slot whose index is the hash code mod the table size. Note
330 that the hash table is used for several kinds of RTL (see attr_rtx)
331 and for strings. While all these live in the same table, they are
332 completely independent, and the hash code is computed differently
335 #define RTL_HASH_SIZE 4093
336 struct attr_hash *attr_hash_table[RTL_HASH_SIZE];
338 /* Here is how primitive or already-shared RTL's hash
340 #define RTL_HASH(RTL) ((int) (RTL) & 0777777)
342 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
345 attr_hash_add_rtx (hashcode, rtl)
349 register struct attr_hash *h;
351 h = (struct attr_hash *) xmalloc (sizeof (struct attr_hash));
352 h->hashcode = hashcode;
354 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
355 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
358 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
361 attr_hash_add_string (hashcode, str)
365 register struct attr_hash *h;
367 h = (struct attr_hash *) xmalloc (sizeof (struct attr_hash));
368 h->hashcode = -hashcode;
370 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE];
371 attr_hash_table[hashcode % RTL_HASH_SIZE] = h;
374 /* Generate an RTL expression, but allow sharing. Like gen_rtx, but the
377 rtx attr_rtx (code, [element1, ..., elementn]) */
386 register int i; /* Array indices... */
387 register char *fmt; /* Current rtx's format... */
388 register rtx rt_val; /* RTX to return to caller... */
390 register struct attr_hash *h;
393 code = va_arg (p, enum rtx_code);
395 /* For each of several cases, search the hash table for an existing entry.
396 Use that entry if one is found; otherwise create a new RTL and add it
399 if (GET_RTX_CLASS (code) == '1')
401 rtx arg0 = va_arg (p, rtx);
403 hashcode = ((int) code + RTL_HASH (arg0));
404 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
405 if (h->hashcode == hashcode
406 && GET_CODE (h->u.rtl) == code
407 && XEXP (h->u.rtl, 0) == arg0)
412 rt_val = rtx_alloc (code);
413 XEXP (rt_val, 0) = arg0;
416 else if (GET_RTX_CLASS (code) == 'c'
417 || GET_RTX_CLASS (code) == '2'
418 || GET_RTX_CLASS (code) == '<')
420 rtx arg0 = va_arg (p, rtx);
421 rtx arg1 = va_arg (p, rtx);
423 hashcode = ((int) code + RTL_HASH (arg0) + RTL_HASH (arg1));
424 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
425 if (h->hashcode == hashcode
426 && GET_CODE (h->u.rtl) == code
427 && XEXP (h->u.rtl, 0) == arg0
428 && XEXP (h->u.rtl, 1) == arg1)
433 rt_val = rtx_alloc (code);
434 XEXP (rt_val, 0) = arg0;
435 XEXP (rt_val, 1) = arg1;
438 else if (GET_RTX_LENGTH (code) == 1
439 && GET_RTX_FORMAT (code)[0] == 's')
441 char * arg0 = va_arg (p, char *);
443 hashcode = ((int) code + RTL_HASH (arg0));
444 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
445 if (h->hashcode == hashcode
446 && GET_CODE (h->u.rtl) == code
447 && XSTR (h->u.rtl, 0) == arg0)
452 rt_val = rtx_alloc (code);
453 XSTR (rt_val, 0) = arg0;
456 else if (GET_RTX_LENGTH (code) == 2
457 && GET_RTX_FORMAT (code)[0] == 's'
458 && GET_RTX_FORMAT (code)[1] == 's')
460 char * arg0 = va_arg (p, char *);
461 char * arg1 = va_arg (p, char *);
463 hashcode = ((int) code + RTL_HASH (arg0) + RTL_HASH (arg1));
464 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
465 if (h->hashcode == hashcode
466 && GET_CODE (h->u.rtl) == code
467 && XSTR (h->u.rtl, 0) == arg0
468 && XSTR (h->u.rtl, 1) == arg1)
473 rt_val = rtx_alloc (code);
474 XSTR (rt_val, 0) = arg0;
475 XSTR (rt_val, 1) = arg1;
480 rt_val = rtx_alloc (code); /* Allocate the storage space. */
482 fmt = GET_RTX_FORMAT (code); /* Find the right format... */
483 for (i = 0; i < GET_RTX_LENGTH (code); i++)
487 case '0': /* Unused field. */
490 case 'i': /* An integer? */
491 XINT (rt_val, i) = va_arg (p, int);
494 case 's': /* A string? */
495 XSTR (rt_val, i) = va_arg (p, char *);
498 case 'e': /* An expression? */
499 case 'u': /* An insn? Same except when printing. */
500 XEXP (rt_val, i) = va_arg (p, rtx);
503 case 'E': /* An RTX vector? */
504 XVEC (rt_val, i) = va_arg (p, rtvec);
516 attr_hash_add_rtx (hashcode, rt_val);
524 /* Create a new string printed with the printf line arguments into a space
525 of at most LEN bytes:
527 rtx attr_printf (len, format, [arg1, ..., argn]) */
533 attr_printf (va_alist)
541 /* Print the string into a temporary location. */
543 len = va_arg (p, int);
544 str = (char *) alloca (len);
545 fmt = va_arg (p, char *);
546 vsprintf (str, fmt, p);
549 return attr_string (str, strlen (str));
552 #else /* not HAVE_VPRINTF */
555 attr_printf (len, fmt, arg1, arg2, arg3)
558 char *arg1, *arg2, *arg3; /* also int */
562 /* Print the string into a temporary location. */
563 str = (char *) alloca (len);
564 sprintf (str, fmt, arg1, arg2, arg3);
566 return attr_string (str, strlen (str));
568 #endif /* not HAVE_VPRINTF */
570 /* Return a permanent (possibly shared) copy of a string STR (not assumed
571 to be null terminated) with LEN bytes. */
574 attr_string (str, len)
578 register struct attr_hash *h;
581 register char *new_str;
583 /* Compute the hash code. */
584 hashcode = (len + 1) * 613 + (unsigned)str[0];
585 for (i = 1; i <= len; i += 2)
586 hashcode = ((hashcode * 613) + (unsigned)str[i]);
588 hashcode = -hashcode;
590 /* Search the table for the string. */
591 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
592 if (h->hashcode == -hashcode
593 && !strncmp (h->u.str, str, len))
594 return h->u.str; /* <-- return if found. */
596 /* Not found; create a permanent copy and add it to the hash table. */
597 new_str = (char *) xmalloc (len + 1);
598 bcopy (str, new_str, len);
600 attr_hash_add_string (hashcode, new_str);
602 return new_str; /* Return the new string. */
605 /* Given a test expression for an attribute, ensure it is validly formed.
606 IS_CONST indicates whether the expression is constant for each compiler
607 run (a constant expression may not test any particular insn).
609 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
610 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
611 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
613 Update the string address in EQ_ATTR expression to be the same used
614 in the attribute (or `alternative_name') to speed up subsequent
615 `find_attr' calls and eliminate most `strcmp' calls.
617 Return the new expression, if any. */
620 check_attr_test (exp, is_const)
624 struct attr_desc *attr;
625 struct attr_value *av;
629 switch (GET_CODE (exp))
632 /* Handle negation test. */
633 if (XSTR (exp, 1)[0] == '!')
634 return check_attr_test (attr_rtx (NOT,
640 else if (n_comma_elts (XSTR (exp, 1)) == 1)
642 attr = find_attr (XSTR (exp, 0), 0);
645 if (! strcmp (XSTR (exp, 0), "alternative"))
647 XSTR (exp, 0) = alternative_name;
648 /* This can't be simplified any further. */
649 RTX_UNCHANGING_P (exp) = 1;
653 fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp, 0));
656 if (is_const && ! attr->is_const)
657 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR",
660 XSTR (exp, 0) = attr->name;
662 if (attr->is_numeric)
664 for (p = XSTR (exp, 1); *p; p++)
665 if (*p < '0' || *p > '9')
666 fatal ("Attribute `%s' takes only numeric values",
671 for (av = attr->first_value; av; av = av->next)
672 if (GET_CODE (av->value) == CONST_STRING
673 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
677 fatal ("Unknown value `%s' for `%s' attribute",
678 XEXP (exp, 1), XEXP (exp, 0));
683 /* Make an IOR tree of the possible values. */
685 name_ptr = XSTR (exp, 1);
686 while ((p = next_comma_elt (&name_ptr)) != NULL)
688 newexp = attr_rtx (EQ_ATTR, XSTR (exp, 0), p);
689 orexp = insert_right_side (IOR, orexp, newexp, -2);
692 return check_attr_test (orexp, is_const);
697 /* Either TRUE or FALSE. */
705 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
706 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const);
710 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const);
715 fatal ("RTL operator \"%s\" not valid in constant attribute test",
716 GET_RTX_NAME (MATCH_OPERAND));
718 case LE: case LT: case GT: case GE:
719 case LEU: case LTU: case GTU: case GEU:
721 /* These cases can't be simplified. */
722 RTX_UNCHANGING_P (exp) = 1;
728 /* These cases are valid for constant attributes, but can't be
730 exp = copy_rtx (exp);
731 RTX_UNCHANGING_P (exp) = 1;
735 fatal ("RTL operator \"%s\" not valid in attribute test",
736 GET_RTX_NAME (GET_CODE (exp)));
742 /* Given an expression, ensure that it is validly formed and that all named
743 attribute values are valid for the given attribute. Issue a fatal error
744 if not. If no attribute is specified, assume a numeric attribute. */
747 check_attr_value (exp, attr)
749 struct attr_desc *attr;
751 struct attr_value *av;
755 switch (GET_CODE (exp))
758 if (attr && ! attr->is_numeric)
759 fatal ("CONST_INT not valid for non-numeric `%s' attribute",
762 if (INTVAL (exp) < 0)
763 fatal ("Negative numeric value specified for `%s' attribute",
769 if (! strcmp (XSTR (exp, 0), "*"))
772 if (attr == 0 || attr->is_numeric)
774 for (p = XSTR (exp, 0); *p; p++)
775 if (*p > '9' || *p < '0')
776 fatal ("Non-numeric value for numeric `%s' attribute",
777 attr ? attr->name : "internal");
781 for (av = attr->first_value; av; av = av->next)
782 if (GET_CODE (av->value) == CONST_STRING
783 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
787 fatal ("Unknown value `%s' for `%s' attribute",
788 XSTR (exp, 0), attr ? attr->name : "internal");
793 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0),
794 attr ? attr->is_const : 0);
795 check_attr_value (XEXP (exp, 1), attr);
796 check_attr_value (XEXP (exp, 2), attr);
800 if (XVECLEN (exp, 0) % 2 != 0)
801 fatal ("First operand of COND must have even length");
803 for (i = 0; i < XVECLEN (exp, 0); i += 2)
805 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i),
806 attr ? attr->is_const : 0);
807 check_attr_value (XVECEXP (exp, 0, i + 1), attr);
810 check_attr_value (XEXP (exp, 1), attr);
814 if (attr && attr->is_const)
815 /* A constant SYMBOL_REF is valid as a constant attribute test and
816 is expanded later by make_canonical into a COND. */
818 /* Otherwise, fall through... */
821 fatal ("Illegal operation `%s' for attribute value",
822 GET_RTX_NAME (GET_CODE (exp)));
826 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
827 It becomes a COND with each test being (eq_attr "alternative "n") */
830 convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
833 int insn_code, insn_index;
839 if (XVECLEN (exp, 1) != num_alt)
840 fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
843 /* Make a COND with all tests but the last. Select the last value via the
845 condexp = rtx_alloc (COND);
846 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
848 for (i = 0; i < num_alt - 1; i++)
851 p = attr_printf (3, "%d", i);
853 /* Sharing this EQ_ATTR rtl causes trouble. */
854 XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
855 XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
856 XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p;
857 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
860 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
862 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp);
865 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
866 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
869 convert_set_attr (exp, num_alt, insn_code, insn_index)
872 int insn_code, insn_index;
879 /* See how many alternative specified. */
880 n = n_comma_elts (XSTR (exp, 1));
882 return attr_rtx (SET,
883 attr_rtx (ATTR, XSTR (exp, 0)),
884 attr_rtx (CONST_STRING, XSTR (exp, 1)));
886 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
887 XSTR (newexp, 0) = XSTR (exp, 0);
888 XVEC (newexp, 1) = rtvec_alloc (n);
890 /* Process each comma-separated name. */
891 name_ptr = XSTR (exp, 1);
893 while ((p = next_comma_elt (&name_ptr)) != NULL)
894 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p);
896 return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
899 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
900 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
907 struct attr_desc *attr;
911 for (id = defs; id; id = id->next)
913 if (XVEC (id->def, id->vec_idx) == NULL)
916 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
918 value = XVECEXP (id->def, id->vec_idx, i);
919 switch (GET_CODE (value))
922 if (GET_CODE (XEXP (value, 0)) != ATTR)
923 fatal ("Bad attribute set in pattern %d", id->insn_index);
926 case SET_ATTR_ALTERNATIVE:
927 value = convert_set_attr_alternative (value,
928 id->num_alternatives,
934 value = convert_set_attr (value, id->num_alternatives,
935 id->insn_code, id->insn_index);
939 fatal ("Invalid attribute code `%s' for pattern %d",
940 GET_RTX_NAME (GET_CODE (value)), id->insn_index);
943 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
944 fatal ("Unknown attribute `%s' for pattern number %d",
945 XSTR (XEXP (value, 0), 0), id->insn_index);
947 XVECEXP (id->def, id->vec_idx, i) = value;
948 check_attr_value (XEXP (value, 1), attr);
953 /* Given a constant SYMBOL_REF expression, convert to a COND that
954 explicitly tests each enumerated value. */
957 convert_const_symbol_ref (exp, attr)
959 struct attr_desc *attr;
962 struct attr_value *av;
966 for (av = attr->first_value; av; av = av->next)
969 /* Make a COND with all tests but the last, and in the original order.
970 Select the last value via the default. Note that the attr values
971 are constructed in reverse order. */
973 condexp = rtx_alloc (COND);
974 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
975 av = attr->first_value;
976 XEXP (condexp, 1) = av->value;
978 for (i = num_alt - 2; av = av->next, i >= 0; i--)
983 XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ);
984 XEXP (XVECEXP (condexp, 0, 2 * i), 0) = exp;
985 XEXP (XVECEXP (condexp, 0, 2 * i), 1) = value = rtx_alloc (SYMBOL_REF);
986 RTX_UNCHANGING_P (value) = 1;
987 XSTR (value, 0) = p = (char *) xmalloc (2
988 + strlen (attr->name)
989 + strlen (XSTR (av->value, 0)));
990 strcpy (p, attr->name);
992 strcat (p, XSTR (av->value, 0));
993 for (; *p != '\0'; p++)
994 if (*p >= 'a' && *p <= 'z')
997 XVECEXP (condexp, 0, 2 * i + 1) = av->value;
1003 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1004 expressions by converting them into a COND. This removes cases from this
1005 program. Also, replace an attribute value of "*" with the default attribute
1009 make_canonical (attr, exp)
1010 struct attr_desc *attr;
1016 switch (GET_CODE (exp))
1019 exp = make_numeric_value (INTVAL (exp));
1023 if (! strcmp (XSTR (exp, 0), "*"))
1025 if (attr == 0 || attr->default_val == 0)
1026 fatal ("(attr_value \"*\") used in invalid context.");
1027 exp = attr->default_val->value;
1033 if (!attr->is_const || RTX_UNCHANGING_P (exp))
1035 exp = convert_const_symbol_ref (exp, attr);
1036 RTX_UNCHANGING_P (exp) = 1;
1037 check_attr_value (exp, attr);
1038 /* Goto COND case since this is now a COND. Note that while the
1039 new expression is rescanned, all symbol_ref notes are mared as
1044 newexp = rtx_alloc (COND);
1045 XVEC (newexp, 0) = rtvec_alloc (2);
1046 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
1047 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
1049 XEXP (newexp, 1) = XEXP (exp, 2);
1052 /* Fall through to COND case since this is now a COND. */
1056 /* First, check for degenerate COND. */
1057 if (XVECLEN (exp, 0) == 0)
1058 return make_canonical (attr, XEXP (exp, 1));
1060 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1061 XVECEXP (exp, 0, i + 1)
1062 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
1064 XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
1071 /* Given a value and an attribute description, return a `struct attr_value *'
1072 that represents that value. This is either an existing structure, if the
1073 value has been previously encountered, or a newly-created structure.
1075 `insn_code' is the code of an insn whose attribute has the specified
1076 value (-2 if not processing an insn). We ensure that all insns for
1077 a given value have the same number of alternatives if the value checks
1080 static struct attr_value *
1081 get_attr_value (value, attr, insn_code)
1083 struct attr_desc *attr;
1086 struct attr_value *av;
1089 value = make_canonical (attr, value);
1090 if (compares_alternatives_p (value))
1092 if (insn_code < 0 || insn_alternatives == NULL)
1093 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1095 num_alt = insn_alternatives[insn_code];
1098 for (av = attr->first_value; av; av = av->next)
1099 if (rtx_equal_p (value, av->value)
1100 && (num_alt == 0 || av->first_insn == NULL
1101 || insn_alternatives[av->first_insn->insn_code]))
1104 av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
1106 av->next = attr->first_value;
1107 attr->first_value = av;
1108 av->first_insn = NULL;
1110 av->has_asm_insn = 0;
1115 /* After all DEFINE_DELAYs have been read in, create internal attributes
1116 to generate the required routines.
1118 First, we compute the number of delay slots for each insn (as a COND of
1119 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1120 delay type is specified, we compute a similar function giving the
1121 DEFINE_DELAY ordinal for each insn.
1123 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1124 tells whether a given insn can be in that delay slot.
1126 Normal attrbute filling and optimization expands these to contain the
1127 information needed to handle delay slots. */
1132 struct delay_desc *delay;
1138 /* First, generate data for `num_delay_slots' function. */
1140 condexp = rtx_alloc (COND);
1141 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1142 XEXP (condexp, 1) = make_numeric_value (0);
1144 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1146 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1147 XVECEXP (condexp, 0, i + 1)
1148 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
1151 make_internal_attr ("*num_delay_slots", condexp, 0);
1153 /* If more than one delay type, do the same for computing the delay type. */
1156 condexp = rtx_alloc (COND);
1157 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
1158 XEXP (condexp, 1) = make_numeric_value (0);
1160 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
1162 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
1163 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
1166 make_internal_attr ("*delay_type", condexp, 1);
1169 /* For each delay possibility and delay slot, compute an eligability
1170 attribute for non-anulled insns and for each type of annulled (annul
1171 if true and annul if false). */
1172 for (delay = delays; delay; delay = delay->next)
1174 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
1176 condexp = XVECEXP (delay->def, 1, i);
1177 if (condexp == 0) condexp = false_rtx;
1178 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1179 make_numeric_value (1), make_numeric_value (0));
1181 p = attr_printf (13, "*delay_%d_%d", delay->num, i / 3);
1182 make_internal_attr (p, newexp, 1);
1184 if (have_annul_true)
1186 condexp = XVECEXP (delay->def, 1, i + 1);
1187 if (condexp == 0) condexp = false_rtx;
1188 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1189 make_numeric_value (1),
1190 make_numeric_value (0));
1191 p = attr_printf (18, "*annul_true_%d_%d", delay->num, i / 3);
1192 make_internal_attr (p, newexp, 1);
1195 if (have_annul_false)
1197 condexp = XVECEXP (delay->def, 1, i + 2);
1198 if (condexp == 0) condexp = false_rtx;
1199 newexp = attr_rtx (IF_THEN_ELSE, condexp,
1200 make_numeric_value (1),
1201 make_numeric_value (0));
1202 p = attr_printf (18, "*annul_false_%d_%d", delay->num, i / 3);
1203 make_internal_attr (p, newexp, 1);
1209 /* This function is given a left and right side expression and an operator.
1210 Each side is a conditional expression, each alternative of which has a
1211 numerical value. The function returns another conditional expression
1212 which, for every possible set of condition values, returns a value that is
1213 the operator applied to the values of the two sides.
1215 Since this is called early, it must also support IF_THEN_ELSE. */
1218 operate_exp (op, left, right)
1222 int left_value, right_value;
1226 /* If left is a string, apply operator to it and the right side. */
1227 if (GET_CODE (left) == CONST_STRING)
1229 /* If right is also a string, just perform the operation. */
1230 if (GET_CODE (right) == CONST_STRING)
1232 left_value = atoi (XSTR (left, 0));
1233 right_value = atoi (XSTR (right, 0));
1237 i = left_value + right_value;
1241 i = left_value - right_value;
1245 i = left_value | right_value;
1249 if (left_value > right_value)
1259 return make_numeric_value (i);
1261 else if (GET_CODE (right) == IF_THEN_ELSE)
1263 /* Apply recursively to all values within. */
1264 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0),
1265 operate_exp (op, left, XEXP (right, 1)),
1266 operate_exp (op, left, XEXP (right, 2)));
1268 else if (GET_CODE (right) == COND)
1270 newexp = rtx_alloc (COND);
1271 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
1272 for (i = 0; i < XVECLEN (right, 0); i += 2)
1274 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
1275 XVECEXP (newexp, 0, i + 1)
1276 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
1279 XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
1284 fatal ("Badly formed attribute value");
1287 /* Otherwise, do recursion the other way. */
1288 else if (GET_CODE (left) == IF_THEN_ELSE)
1290 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0),
1291 operate_exp (op, XEXP (left, 1), right),
1292 operate_exp (op, XEXP (left, 2), right));
1295 else if (GET_CODE (left) == COND)
1297 newexp = rtx_alloc (COND);
1298 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
1299 for (i = 0; i < XVECLEN (left, 0); i += 2)
1301 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
1302 XVECEXP (newexp, 0, i + 1)
1303 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
1306 XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
1312 fatal ("Badly formed attribute value.");
1317 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
1318 construct a number of attributes.
1320 The first produces a function `function_units_used' which is given an
1321 insn and produces a mask showing which function units are required for
1322 the execution of that insn.
1324 The second produces a function `result_ready_cost' which is used to
1325 determine the time that the result of an insn will be ready and hence
1326 a worst-case schedule.
1328 Both of these produce quite complex expressions which are then set as the
1329 default value of internal attributes. Normal attribute simplification
1330 should produce reasonable expressions.
1332 For each unit, a `<name>_unit_ready_cost' function will take an
1333 insn and give the delay until that unit will be ready with the result
1334 and a `<name>_unit_busy_delay' function is given an insn already
1335 executing on the unit and a candidate to execute and will give the
1336 cost from the time the executing insn started until the candidate
1337 can start (ignore limitations on the number of simultaneous insns). */
1342 struct function_unit *unit;
1343 struct function_unit_op *op;
1349 /* Initially, cost and masks are zero. */
1350 unitsmask = readycost = make_numeric_value (0);
1352 /* Set up a conditional for costs and unit mask. */
1353 newexp = rtx_alloc (IF_THEN_ELSE);
1354 XEXP (newexp, 2) = make_numeric_value (0);
1356 /* For each unit, insert its contribution to the above three values. */
1357 for (unit = units; unit; unit = unit->next)
1359 /* An expression that computes the ready cost for this unit. */
1360 rtx readyexp = rtx_alloc (COND);
1361 /* An expression that maps insns to operation number for conflicts. */
1362 rtx caseexp = rtx_alloc (COND);
1364 XVEC (readyexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
1365 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
1367 for (op = unit->ops; op; op = op->next)
1369 /* Validate the expressions we were given for the conditions
1370 and busy cost. Then make an attribute for use in the conflict
1372 op->condexp = check_attr_test (op->condexp, 0);
1373 check_attr_value (op->busyexp, 0);
1374 str = attr_printf (strlen (unit->name) + 11, "*%s_case_%d",
1375 unit->name, op->num);
1376 make_internal_attr (str, make_canonical (0, op->busyexp));
1378 /* Make our adjustment to the two COND's being computed. If we are
1379 the last operation class, place our values into the default of
1381 if (op->num == unit->num_opclasses - 1)
1383 XEXP (readyexp, 1) = make_numeric_value (op->ready);
1384 XEXP (caseexp, 1) = make_numeric_value (op->num);
1388 XVECEXP (readyexp, 0, op->num * 2) = op->condexp;
1389 XVECEXP (readyexp, 0, op->num * 2 + 1)
1390 = make_numeric_value (op->ready);
1391 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
1392 XVECEXP (caseexp, 0, op->num * 2 + 1)
1393 = make_numeric_value (op->num);
1397 /* Make an attribute for the case number and ready delay. */
1398 str = attr_printf (strlen (unit->name) + 8, "*%s_cases", unit->name);
1399 make_internal_attr (str, caseexp, 1);
1401 str = attr_printf (strlen (unit->name) + 20, "*%s_unit_ready_cost",
1403 make_internal_attr (str, readyexp, 0);
1405 /* Merge this function unit into the ready cost and unit mask
1407 XEXP (newexp, 0) = check_attr_test (unit->condexp, 0);
1408 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1409 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1411 XEXP (newexp, 1) = readyexp;
1412 readycost = operate_exp (MAX_OP, readycost, newexp);
1415 make_internal_attr ("*function_units_used", unitsmask, 0);
1416 make_internal_attr ("*result_ready_cost", readycost, 0);
1419 /* Once all attributes and insns have been read and checked, we construct for
1420 each attribute value a list of all the insns that have that value for
1425 struct attr_desc *attr;
1427 struct attr_value *av;
1428 struct insn_ent *ie;
1429 struct insn_def *id;
1433 for (id = defs; id; id = id->next)
1435 /* If no value is specified for this insn for this attribute, use the
1438 if (XVEC (id->def, id->vec_idx))
1439 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1440 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1442 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1445 av = attr->default_val;
1447 av = get_attr_value (value, attr, id->insn_code);
1449 ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1450 ie->insn_code = id->insn_code;
1451 ie->insn_index = id->insn_code;
1452 insert_insn_ent (av, ie);
1456 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1457 test that checks relative positions of insns (uses MATCH_DUP or PC).
1458 If so, replace it with what is obtained by passing the expression to
1459 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1460 recursively on each value (including the default value). Otherwise,
1461 return the value returned by NO_ADDRESS_FN applied to EXP. */
1464 substitute_address (exp, no_address_fn, address_fn)
1466 rtx (*no_address_fn) ();
1467 rtx (*address_fn) ();
1472 if (GET_CODE (exp) == COND)
1474 /* See if any tests use addresses. */
1476 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1477 walk_attr_value (XVECEXP (exp, 0, i));
1480 return (*address_fn) (exp);
1482 /* Make a new copy of this COND, replacing each element. */
1483 newexp = rtx_alloc (COND);
1484 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1485 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1487 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1488 XVECEXP (newexp, 0, i + 1)
1489 = substitute_address (XVECEXP (exp, 0, i + 1),
1490 no_address_fn, address_fn);
1493 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1494 no_address_fn, address_fn);
1499 else if (GET_CODE (exp) == IF_THEN_ELSE)
1502 walk_attr_value (XEXP (exp, 0));
1504 return (*address_fn) (exp);
1506 return attr_rtx (IF_THEN_ELSE,
1507 substitute_address (XEXP (exp, 0),
1508 no_address_fn, address_fn),
1509 substitute_address (XEXP (exp, 1),
1510 no_address_fn, address_fn),
1511 substitute_address (XEXP (exp, 2),
1512 no_address_fn, address_fn));
1515 return (*no_address_fn) (exp);
1518 /* Make new attributes from the `length' attribute. The following are made,
1519 each corresponding to a function called from `shorten_branches' or
1522 *insn_default_length This is the length of the insn to be returned
1523 by `get_attr_length' before `shorten_branches'
1524 has been called. In each case where the length
1525 depends on relative addresses, the largest
1526 possible is used. This routine is also used
1527 to compute the initial size of the insn.
1529 *insn_variable_length_p This returns 1 if the insn's length depends
1530 on relative addresses, zero otherwise.
1532 *insn_current_length This is only called when it is known that the
1533 insn has a variable length and returns the
1534 current length, based on relative addresses.
1538 make_length_attrs ()
1540 static char *new_names[] = {"*insn_default_length",
1541 "*insn_variable_length_p",
1542 "*insn_current_length"};
1543 static rtx (*no_address_fn[]) () = {identity_fn, zero_fn, zero_fn};
1544 static rtx (*address_fn[]) () = {max_fn, one_fn, identity_fn};
1546 struct attr_desc *length_attr, *new_attr;
1547 struct attr_value *av, *new_av;
1548 struct insn_ent *ie, *new_ie;
1550 /* See if length attribute is defined. If so, it must be numeric. Make
1551 it special so we don't output anything for it. */
1552 length_attr = find_attr ("length", 0);
1553 if (length_attr == 0)
1556 if (! length_attr->is_numeric)
1557 fatal ("length attribute must be numeric.");
1559 length_attr->is_const = 0;
1560 length_attr->is_special = 1;
1562 /* Make each new attribute, in turn. */
1563 for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
1565 make_internal_attr (new_names[i],
1566 substitute_address (length_attr->default_val->value,
1567 no_address_fn[i], address_fn[i]),
1569 new_attr = find_attr (new_names[i], 0);
1570 for (av = length_attr->first_value; av; av = av->next)
1571 for (ie = av->first_insn; ie; ie = ie->next)
1573 new_av = get_attr_value (substitute_address (av->value,
1576 new_attr, ie->insn_code);
1577 new_ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1578 new_ie->insn_code = ie->insn_code;
1579 new_ie->insn_index = ie->insn_index;
1580 insert_insn_ent (new_av, new_ie);
1585 /* Utility functions called from above routine. */
1598 return make_numeric_value (0);
1605 return make_numeric_value (1);
1612 return make_numeric_value (max_attr_value (exp));
1615 /* Take a COND expression and see if any of the conditions in it can be
1616 simplified. If any are known true or known false for the particular insn
1617 code, the COND can be further simplified.
1619 Also call ourselves on any COND operations that are values of this COND.
1621 We only do the first replacement found directly and call ourselves
1622 recursively for subsequent replacements. */
1625 simplify_cond (exp, insn_code, insn_index)
1627 int insn_code, insn_index;
1634 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1636 newtest = SIMPLIFY_TEST_EXP (XVECEXP (exp, 0, i), insn_code, insn_index);
1637 if (newtest == true_rtx)
1639 /* Make a new COND with any previous conditions and the value for
1640 this pair as the default value. */
1641 newexp = rtx_alloc (COND);
1642 XVEC (newexp, 0) = rtvec_alloc (i);
1643 for (j = 0; j < i; j++)
1644 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1646 XEXP (newexp, 1) = XVECEXP (exp, 0, i + 1);
1650 else if (newtest == false_rtx)
1652 /* Build a new COND without this test. */
1653 newexp = rtx_alloc (COND);
1654 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1655 for (j = 0; j < i; j++)
1656 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1658 for (j = i; j < XVECLEN (newexp, 0); j++)
1659 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
1661 XEXP (newexp, 1) = XEXP (exp, 1);
1665 else if (newtest != XVECEXP (exp, 0, i))
1667 newexp = rtx_alloc (COND);
1668 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1669 for (j = 0; j < XVECLEN (exp, 0); j++)
1670 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1671 XEXP (newexp, 1) = XEXP (exp, 1);
1673 XVECEXP (newexp, 0, i) = newtest;
1677 /* See if this value may need simplification. */
1678 if (GET_CODE (XVECEXP (exp, 0, i + 1)) == COND)
1680 value = simplify_cond (XVECEXP (exp, 0, i + 1),
1681 insn_code, insn_index);
1682 if (value != XVECEXP (exp, 0, i + 1))
1684 newexp = rtx_alloc (COND);
1685 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1686 for (j = 0; j < XVECLEN (exp, 0); j++)
1687 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1688 XEXP (newexp, 1) = XEXP (exp, 1);
1690 XVECEXP (newexp, 0, i + 1) = value;
1695 /* If this is the last condition in a COND and our value is the same
1696 as the default value, our test isn't needed. */
1697 if (i == XVECLEN (exp, 0) - 2
1698 && rtx_equal_p (XVECEXP (exp, 0, i + 1), XEXP (exp, 1)))
1700 newexp = rtx_alloc (COND);
1701 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1702 for (j = 0; j < i; j++)
1703 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1704 XEXP (newexp, 1) = XEXP (exp, 1);
1708 /* If this value and the value for the next test are the same, merge the
1710 else if (i != XVECLEN (exp, 0) - 2
1711 && rtx_equal_p (XVECEXP (exp, 0, i + 1),
1712 XVECEXP (exp, 0, i + 3)))
1714 newexp = rtx_alloc (COND);
1715 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1716 for (j = 0; j < i; j++)
1717 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1719 XVECEXP (newexp, 0, j)
1720 = insert_right_side (IOR, XVECEXP (exp, 0, i),
1721 XVECEXP (exp, 0, i + 2),
1722 insn_code, insn_index);
1723 XVECEXP (newexp, 0, j + 1) = XVECEXP (exp, 0, i + 1);
1725 for (j = i + 2; j < XVECLEN (newexp, 0); j++)
1726 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
1728 XEXP (newexp, 1) = XEXP (exp, 1);
1733 /* See if default value needs simplification. */
1734 if (GET_CODE (XEXP (exp, 1)) == COND)
1736 value = simplify_cond (XEXP (exp, 1), insn_code, insn_index);
1737 if (value != XEXP (exp, 1))
1739 newexp = rtx_alloc (COND);
1740 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1741 for (j = 0; j < XVECLEN (exp, 0); j++)
1742 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1743 XEXP (newexp, 1) = value;
1749 else if (XVECLEN (newexp, 0) == 1)
1750 return XVECEXP (newexp, 0, 0);
1752 return simplify_cond (newexp, insn_code, insn_index);
1755 /* Remove an insn entry from an attribute value. */
1758 remove_insn_ent (av, ie)
1759 struct attr_value *av;
1760 struct insn_ent *ie;
1762 struct insn_ent *previe;
1764 if (av->first_insn == ie)
1765 av->first_insn = ie->next;
1768 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1770 previe->next = ie->next;
1774 if (ie->insn_code == -1)
1775 av->has_asm_insn = 0;
1778 /* Insert an insn entry in an attribute value list. */
1781 insert_insn_ent (av, ie)
1782 struct attr_value *av;
1783 struct insn_ent *ie;
1785 ie->next = av->first_insn;
1786 av->first_insn = ie;
1788 if (ie->insn_code == -1)
1789 av->has_asm_insn = 1;
1792 /* This is a utility routine to take an expression that is a tree of either
1793 AND or IOR expressions and insert a new term. The new term will be
1794 inserted at the right side of the first node whose code does not match
1795 the root. A new node will be created with the root's code. Its left
1796 side will be the old right side and its right side will be the new
1799 If the `term' is itself a tree, all its leaves will be inserted. */
1802 insert_right_side (code, exp, term, insn_code, insn_index)
1806 int insn_code, insn_index;
1810 if (GET_CODE (term) == code)
1812 exp = insert_right_side (code, exp, XEXP (term, 0),
1813 insn_code, insn_index);
1814 exp = insert_right_side (code, exp, XEXP (term, 1),
1815 insn_code, insn_index);
1820 if (GET_CODE (exp) == code)
1822 /* Make a copy of this expression and call recursively. */
1823 newexp = attr_rtx (code, XEXP (exp, 0),
1824 insert_right_side (code, XEXP (exp, 1),
1825 term, insn_code, insn_index));
1829 /* Insert the new term. */
1830 newexp = attr_rtx (code, exp, term);
1833 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1836 /* If we have an expression which AND's a bunch of
1837 (not (eq_attrq "alternative" "n"))
1838 terms, we may have covered all or all but one of the possible alternatives.
1839 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1841 This routine is passed an expression and either AND or IOR. It returns a
1842 bitmask indicating which alternatives are present. */
1845 compute_alternative_mask (exp, code)
1849 if (GET_CODE (exp) == code)
1850 return compute_alternative_mask (XEXP (exp, 0), code)
1851 | compute_alternative_mask (XEXP (exp, 1), code);
1853 else if (code == AND && GET_CODE (exp) == NOT
1854 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1855 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1856 return 1 << atoi (XSTR (XEXP (exp, 0), 1));
1858 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1859 && XSTR (exp, 0) == alternative_name)
1860 return 1 << atoi (XSTR (exp, 1));
1866 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1867 attribute with the value represented by that bit. */
1870 make_alternative_compare (mask)
1878 for (i = 0; (mask & (1 << i)) == 0; i++)
1881 alternative = attr_printf (3, "%d", i);
1883 newexp = attr_rtx (EQ_ATTR, alternative_name, alternative);
1884 RTX_UNCHANGING_P (newexp) = 1;
1889 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1890 of "attr" for this insn code. From that value, we can compute a test
1891 showing when the EQ_ATTR will be true. This routine performs that
1892 computation. If a test condition involves an address, we leave the EQ_ATTR
1893 intact because addresses are only valid for the `length' attribute. */
1896 evaluate_eq_attr (exp, value, insn_code, insn_index)
1899 int insn_code, insn_index;
1906 if (GET_CODE (value) == CONST_STRING)
1908 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
1913 else if (GET_CODE (value) == COND)
1915 /* We construct an IOR of all the cases for which the requested attribute
1916 value is present. Since we start with FALSE, if it is not present,
1917 FALSE will be returned.
1919 Each case is the AND of the NOT's of the previous conditions with the
1920 current condition; in the default case the current condition is TRUE.
1922 For each possible COND value, call ourselves recursively.
1924 The extra TRUE and FALSE expressions will be eliminated by another
1925 call to the simplification routine. */
1930 for (i = 0; i < XVECLEN (value, 0); i += 2)
1932 right = insert_right_side (AND, andexp,
1933 XVECEXP (value, 0, i),
1934 insn_code, insn_index);
1935 right = insert_right_side (AND, right,
1936 evaluate_eq_attr (exp, XVECEXP (value, 0, i + 1),
1937 insn_code, insn_index),
1938 insn_code, insn_index);
1939 orexp = insert_right_side (IOR, orexp, right,
1940 insn_code, insn_index);
1942 /* Add this condition into the AND expression. */
1943 newexp = attr_rtx (NOT, XVECEXP (value, 0, i));
1944 andexp = insert_right_side (AND, andexp, newexp,
1945 insn_code, insn_index);
1948 /* Handle the default case. */
1949 right = insert_right_side (AND, andexp,
1950 evaluate_eq_attr (exp, XEXP (value, 1),
1951 insn_code, insn_index),
1952 insn_code, insn_index);
1953 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
1958 /* If uses an address, must return original expression. But set the
1959 RTX_UNCHANGING_P bit so we don't try to simplify it again. */
1962 walk_attr_value (newexp);
1966 if (! RTX_UNCHANGING_P (exp))
1967 exp = copy_rtx (exp);
1969 RTX_UNCHANGING_P (exp) = 1;
1976 /* This routine is called when an AND of a term with a tree of AND's is
1977 encountered. If the term or its complement is present in the tree, it
1978 can be replaced with TRUE or FALSE, respectively.
1980 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
1981 be true and hence are complementary.
1983 There is one special case: If we see
1984 (and (not (eq_attr "att" "v1"))
1985 (eq_attr "att" "v2"))
1986 this can be replaced by (eq_attr "att" "v2"). To do this we need to
1987 replace the term, not anything in the AND tree. So we pass a pointer to
1991 simplify_and_tree (exp, pterm, insn_code, insn_index)
1994 int insn_code, insn_index;
1999 int left_eliminates_term, right_eliminates_term;
2001 if (GET_CODE (exp) == AND)
2003 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2004 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2005 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2007 newexp = attr_rtx (GET_CODE (exp), left, right);
2009 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2013 else if (GET_CODE (exp) == IOR)
2015 /* For the IOR case, we do the same as above, except that we can
2016 only eliminate `term' if both sides of the IOR would do so. */
2018 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2019 left_eliminates_term = (temp == true_rtx);
2022 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2023 right_eliminates_term = (temp == true_rtx);
2025 if (left_eliminates_term && right_eliminates_term)
2028 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2030 newexp = attr_rtx (GET_CODE (exp), left, right);
2032 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2036 /* Check for simplifications. Do some extra checking here since this
2037 routine is called so many times. */
2042 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
2045 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
2048 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
2050 if (XSTR (exp, 0) != XSTR (*pterm, 0))
2053 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
2059 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2060 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
2062 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
2065 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
2071 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2072 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
2074 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
2077 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
2083 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
2085 if (rtx_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
2089 else if (GET_CODE (exp) == NOT)
2091 if (rtx_equal_p (XEXP (exp, 0), *pterm))
2095 else if (GET_CODE (*pterm) == NOT)
2097 if (rtx_equal_p (XEXP (*pterm, 0), exp))
2101 else if (rtx_equal_p (exp, *pterm))
2107 /* Similiar to `simplify_and_tree', but for IOR trees. */
2110 simplify_or_tree (exp, pterm, insn_code, insn_index)
2113 int insn_code, insn_index;
2118 int left_eliminates_term, right_eliminates_term;
2120 if (GET_CODE (exp) == IOR)
2122 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
2123 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
2124 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2126 newexp = attr_rtx (GET_CODE (exp), left, right);
2128 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2132 else if (GET_CODE (exp) == AND)
2134 /* For the AND case, we do the same as above, except that we can
2135 only eliminate `term' if both sides of the AND would do so. */
2137 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
2138 left_eliminates_term = (temp == false_rtx);
2141 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
2142 right_eliminates_term = (temp == false_rtx);
2144 if (left_eliminates_term && right_eliminates_term)
2147 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2149 newexp = attr_rtx (GET_CODE (exp), left, right);
2151 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2155 if (rtx_equal_p (exp, *pterm))
2158 else if (GET_CODE (exp) == NOT && rtx_equal_p (XEXP (exp, 0), *pterm))
2161 else if (GET_CODE (*pterm) == NOT && rtx_equal_p (XEXP (*pterm, 0), exp))
2164 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
2165 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2166 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
2169 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
2170 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
2171 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
2177 /* Given an expression, see if it can be simplified for a particular insn
2178 code based on the values of other attributes being tested. This can
2179 eliminate nested get_attr_... calls.
2181 Note that if an endless recursion is specified in the patterns, the
2182 optimization will loop. However, it will do so in precisely the cases where
2183 an infinite recursion loop could occur during compilation. It's better that
2187 simplify_test_exp (exp, insn_code, insn_index)
2189 int insn_code, insn_index;
2192 struct attr_desc *attr;
2193 struct attr_value *av;
2194 struct insn_ent *ie;
2198 switch (GET_CODE (exp))
2201 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2202 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2204 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2205 present on both sides, apply the distributive law since this will
2206 yield simplifications. */
2207 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
2208 && compute_alternative_mask (left, IOR)
2209 && compute_alternative_mask (right, IOR))
2211 if (GET_CODE (left) == IOR)
2218 newexp = attr_rtx (IOR,
2219 attr_rtx (AND, left, XEXP (right, 0)),
2220 attr_rtx (AND, left, XEXP (right, 1)));
2222 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2225 /* Try with the term on both sides. */
2226 right = simplify_and_tree (right, &left, insn_code, insn_index);
2227 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2228 left = simplify_and_tree (left, &right, insn_code, insn_index);
2230 if (left == false_rtx || right == false_rtx)
2232 else if (left == true_rtx)
2234 else if (right == true_rtx)
2237 /* See if all or all but one of the insn's alternatives are specified
2238 in this tree. Optimize if so. */
2240 else if (insn_code >= 0
2241 && (GET_CODE (left) == AND
2242 || (GET_CODE (left) == NOT
2243 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
2244 && XSTR (XEXP (left, 0), 0) == alternative_name)
2245 || GET_CODE (right) == AND
2246 || (GET_CODE (right) == NOT
2247 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
2248 && XSTR (XEXP (right, 0), 0) == alternative_name)))
2250 i = compute_alternative_mask (exp, AND);
2251 if (i & ~insn_alternatives[insn_code])
2252 fatal ("Illegal alternative specified for pattern number %d",
2255 /* If all alternatives are excluded, this is false. */
2256 i ^= insn_alternatives[insn_code];
2259 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2261 /* If just one excluded, AND a comparison with that one to the
2262 front of the tree. The others will be eliminated by
2263 optimization. We do not want to do this if the insn has one
2264 alternative and we have tested none of them! */
2265 left = make_alternative_compare (i);
2266 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2267 newexp = attr_rtx (AND, left, right);
2269 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2273 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2275 newexp = attr_rtx (AND, left, right);
2276 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2281 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2282 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
2284 right = simplify_or_tree (right, &left, insn_code, insn_index);
2285 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
2286 left = simplify_or_tree (left, &right, insn_code, insn_index);
2288 if (right == true_rtx || left == true_rtx)
2290 else if (left == false_rtx)
2292 else if (right == false_rtx)
2295 /* Test for simple cases where the distributive law is useful. I.e.,
2296 convert (ior (and (x) (y))
2302 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
2303 && rtx_equal_p (XEXP (left, 0), XEXP (right, 0)))
2305 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1));
2307 left = XEXP (left, 0);
2309 newexp = attr_rtx (AND, left, right);
2310 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2313 /* See if all or all but one of the insn's alternatives are specified
2314 in this tree. Optimize if so. */
2316 else if (insn_code >= 0
2317 && (GET_CODE (left) == IOR
2318 || (GET_CODE (left) == EQ_ATTR
2319 && XSTR (left, 0) == alternative_name)
2320 || GET_CODE (right) == IOR
2321 || (GET_CODE (right) == EQ_ATTR
2322 && XSTR (right, 0) == alternative_name)))
2324 i = compute_alternative_mask (exp, IOR);
2325 if (i & ~insn_alternatives[insn_code])
2326 fatal ("Illegal alternative specified for pattern number %d",
2329 /* If all alternatives are included, this is true. */
2330 i ^= insn_alternatives[insn_code];
2333 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
2335 /* If just one excluded, IOR a comparison with that one to the
2336 front of the tree. The others will be eliminated by
2337 optimization. We do not want to do this if the insn has one
2338 alternative and we have tested none of them! */
2339 left = make_alternative_compare (i);
2340 right = simplify_and_tree (exp, &left, insn_code, insn_index);
2341 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right);
2343 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2347 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
2349 newexp = attr_rtx (IOR, left, right);
2350 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2355 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
2356 if (GET_CODE (left) == NOT)
2357 return XEXP (left, 0);
2359 if (left == false_rtx)
2361 else if (left == true_rtx)
2364 /* Try to apply De`Morgan's laws. */
2365 else if (GET_CODE (left) == IOR)
2367 newexp = attr_rtx (AND,
2368 attr_rtx (NOT, XEXP (left, 0)),
2369 attr_rtx (NOT, XEXP (left, 1)));
2371 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2373 else if (GET_CODE (left) == AND)
2375 newexp = attr_rtx (IOR,
2376 attr_rtx (NOT, XEXP (left, 0)),
2377 attr_rtx (NOT, XEXP (left, 1)));
2379 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2381 else if (left != XEXP (exp, 0))
2383 newexp = attr_rtx (NOT, left);
2388 /* Look at the value for this insn code in the specified attribute.
2389 We normally can replace this comparison with the condition that
2390 would give this insn the values being tested for. */
2391 if (XSTR (exp, 0) != alternative_name
2392 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
2393 for (av = attr->first_value; av; av = av->next)
2394 for (ie = av->first_insn; ie; ie = ie->next)
2395 if (ie->insn_code == insn_code)
2396 return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2399 /* We have already simplified this expression. Simplifying it again
2400 won't buy anything unless we weren't given a valid insn code
2401 to process (i.e., we are canonicalizing something.). */
2402 if (insn_code != -2 && ! RTX_UNCHANGING_P (newexp))
2404 newexp = copy_rtx (newexp);
2405 RTX_UNCHANGING_P (newexp) = 1;
2411 /* Optimize the attribute lists by seeing if we can determine conditional
2412 values from the known values of other attributes. This will save subroutine
2413 calls during the compilation. */
2418 struct attr_desc *attr;
2419 struct attr_value *av;
2420 struct insn_ent *ie, *nextie;
2422 int something_changed = 1;
2424 /* Loop until nothing changes for one iteration. */
2425 while (something_changed)
2427 something_changed = 0;
2428 for (attr = attrs; attr; attr = attr->next)
2429 for (av = attr->first_value; av; av = av->next)
2430 for (ie = av->first_insn; ie; ie = nextie)
2433 if (GET_CODE (av->value) != COND)
2436 newexp = simplify_cond (av->value, ie->insn_code,
2438 if (newexp != av->value)
2440 remove_insn_ent (av, ie);
2441 insert_insn_ent (get_attr_value (newexp, attr,
2442 ie->insn_code), ie);
2443 something_changed = 1;
2449 /* Create table entries for DEFINE_ATTR. */
2455 struct attr_desc *attr;
2456 struct attr_value *av;
2460 /* Make a new attribute structure. Check for duplicate by looking at
2461 attr->default_val, since it is initialized by this routine. */
2462 attr = find_attr (XSTR (exp, 0), 1);
2463 if (attr->default_val)
2464 fatal ("Duplicate definition for `%s' attribute", attr->name);
2466 if (*XSTR (exp, 1) == '\0')
2467 attr->is_numeric = 1;
2470 name_ptr = XSTR (exp, 1);
2471 while ((p = next_comma_elt (&name_ptr)) != NULL)
2473 av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
2474 av->value = attr_rtx (CONST_STRING, p);
2475 av->next = attr->first_value;
2476 attr->first_value = av;
2477 av->first_insn = NULL;
2479 av->has_asm_insn = 0;
2483 if (GET_CODE (XEXP (exp, 2)) == CONST)
2486 if (attr->is_numeric)
2487 fatal ("Constant attributes may not take numeric values");
2488 /* Get rid of the CONST node. It is allowed only at top-level. */
2489 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0);
2492 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
2493 fatal ("`length' attribute must take numeric values");
2495 /* Set up the default value. */
2496 check_attr_value (XEXP (exp, 2), attr);
2497 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
2500 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2501 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2502 number of alternatives as this should be checked elsewhere. */
2505 count_alternatives (exp)
2511 if (GET_CODE (exp) == MATCH_OPERAND)
2512 return n_comma_elts (XSTR (exp, 2));
2514 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2515 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2520 n = count_alternatives (XEXP (exp, i));
2527 if (XVEC (exp, i) != NULL)
2528 for (j = 0; j < XVECLEN (exp, i); j++)
2530 n = count_alternatives (XVECEXP (exp, i, j));
2539 /* Returns non-zero if the given expression contains an EQ_ATTR with the
2540 `alternative' attribute. */
2543 compares_alternatives_p (exp)
2549 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
2552 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2553 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2558 if (compares_alternatives_p (XEXP (exp, i)))
2563 for (j = 0; j < XVECLEN (exp, i); j++)
2564 if (compares_alternatives_p (XVECEXP (exp, i, j)))
2572 /* Returns non-zero is INNER is contained in EXP. */
2575 contained_in_p (inner, exp)
2582 if (rtx_equal_p (inner, exp))
2585 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2586 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2591 if (contained_in_p (inner, XEXP (exp, i)))
2596 for (j = 0; j < XVECLEN (exp, i); j++)
2597 if (contained_in_p (inner, XVECEXP (exp, i, j)))
2605 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
2611 struct insn_def *id;
2613 id = (struct insn_def *) xmalloc (sizeof (struct insn_def));
2618 switch (GET_CODE (exp))
2621 id->insn_code = insn_code_number++;
2622 id->insn_index = insn_index_number++;
2623 id->num_alternatives = count_alternatives (exp);
2624 if (id->num_alternatives == 0)
2625 id->num_alternatives = 1;
2629 case DEFINE_PEEPHOLE:
2630 id->insn_code = insn_code_number++;
2631 id->insn_index = insn_index_number++;
2632 id->num_alternatives = count_alternatives (exp);
2633 if (id->num_alternatives == 0)
2634 id->num_alternatives = 1;
2638 case DEFINE_ASM_ATTRIBUTES:
2640 id->insn_index = -1;
2641 id->num_alternatives = 1;
2643 got_define_asm_attributes = 1;
2648 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
2649 true or annul false is specified, and make a `struct delay_desc'. */
2655 struct delay_desc *delay;
2658 if (XVECLEN (def, 1) % 3 != 0)
2659 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
2661 for (i = 0; i < XVECLEN (def, 1); i += 3)
2663 if (XVECEXP (def, 1, i + 1))
2664 have_annul_true = 1;
2665 if (XVECEXP (def, 1, i + 2))
2666 have_annul_false = 1;
2669 delay = (struct delay_desc *) xmalloc (sizeof (struct delay_desc));
2671 delay->num = ++num_delays;
2672 delay->next = delays;
2676 /* Process a DEFINE_FUNCTION_UNIT.
2678 This gives information about a function unit contained in the CPU.
2679 We fill in a `struct function_unit_op' and a `struct function_unit'
2680 with information used later by `expand_unit'. */
2686 struct function_unit *unit;
2687 struct function_unit_op *op;
2689 /* See if we have already seen this function unit. If so, check that
2690 the multipicity and simultaneity values are the same. If not, make
2691 a structure for this function unit. */
2692 for (unit = units; unit; unit = unit->next)
2693 if (! strcmp (unit->name, XSTR (def, 0)))
2695 if (unit->multiplicity != XINT (def, 1)
2696 || unit->simultaneity != XINT (def, 2))
2697 fatal ("Differing specifications given for `%s' function unit.",
2704 unit = (struct function_unit *) xmalloc (sizeof (struct function_unit));
2705 unit->name = XSTR (def, 0);
2706 unit->multiplicity = XINT (def, 1);
2707 unit->simultaneity = XINT (def, 2);
2708 unit->num = num_units++;
2709 unit->num_opclasses = 0;
2710 unit->condexp = false_rtx;
2716 /* Make a new operation class structure entry and initialize it. */
2717 op = (struct function_unit_op *) xmalloc (sizeof (struct function_unit_op));
2718 op->condexp = XEXP (def, 3);
2719 op->num = unit->num_opclasses++;
2720 op->ready = XINT (def, 4);
2721 op->next = unit->ops;
2724 /* Set our busy expression based on whether or not an optional conflict
2725 vector was specified. */
2728 /* Compute the IOR of all the specified expressions. */
2729 rtx orexp = false_rtx;
2732 for (i = 0; i < XVECLEN (def, 6); i++)
2733 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2);
2735 op->busyexp = attr_rtx (IF_THEN_ELSE, orexp,
2736 make_numeric_value (XINT (def, 5)),
2737 make_numeric_value (0));
2740 op->busyexp = make_numeric_value (XINT (def, 5));
2742 /* Merge our conditional into that of the function unit so we can determine
2743 which insns are used by the function unit. */
2744 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2);
2747 /* Given a piece of RTX, print a C expression to test it's truth value.
2748 We use AND and IOR both for logical and bit-wise operations, so
2749 interpret them as logical unless they are inside a comparison expression.
2750 The second operand of this function will be non-zero in that case. */
2753 write_test_expr (exp, in_comparison)
2757 int comparison_operator = 0;
2759 struct attr_desc *attr;
2761 /* In order not to worry about operator precedence, surround our part of
2762 the expression with parentheses. */
2765 code = GET_CODE (exp);
2768 /* Binary operators. */
2770 case GE: case GT: case GEU: case GTU:
2771 case LE: case LT: case LEU: case LTU:
2772 comparison_operator = 1;
2774 case PLUS: case MINUS: case MULT: case DIV: case MOD:
2775 case AND: case IOR: case XOR:
2776 case LSHIFT: case ASHIFT: case LSHIFTRT: case ASHIFTRT:
2777 write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator);
2793 printf (" >= (unsigned) ");
2796 printf (" > (unsigned) ");
2805 printf (" <= (unsigned) ");
2808 printf (" < (unsigned) ");
2850 write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator);
2854 /* Special-case (not (eq_attrq "alternative" "x")) */
2855 if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2856 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2858 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
2862 /* Otherwise, fall through to normal unary operator. */
2864 /* Unary operators. */
2882 write_test_expr (XEXP (exp, 0), in_comparison);
2885 /* Comparison test of an attribute with a value. Most of these will
2886 have been removed by optimization. Handle "alternative"
2887 specially and give error if EQ_ATTR present inside a comparison. */
2890 fatal ("EQ_ATTR not valid inside comparison");
2892 if (XSTR (exp, 0) == alternative_name)
2894 printf ("which_alternative == %s", XSTR (exp, 1));
2898 attr = find_attr (XSTR (exp, 0), 0);
2899 if (! attr) abort ();
2900 printf ("get_attr_%s (insn) == ", attr->name);
2901 write_attr_valueq (attr, XSTR (exp, 1));
2904 /* See if an operand matches a predicate. */
2906 /* If only a mode is given, just ensure the mode matches the operand.
2907 If neither a mode nor predicate is given, error. */
2908 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
2910 if (GET_MODE (exp) == VOIDmode)
2911 fatal ("Null MATCH_OPERAND specified as test");
2913 printf ("GET_MODE (operands[%d]) == %smode",
2914 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
2917 printf ("%s (operands[%d], %smode)",
2918 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
2921 /* Constant integer. */
2923 printf ("%d", XINT (exp, 0));
2926 /* A random C expression. */
2928 printf ("%s", XSTR (exp, 0));
2931 /* The address of the branch target. */
2933 printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
2936 /* The address of the current insn. It would be more consistent with
2937 other usage to make this the address of the NEXT insn, but this gets
2938 too confusing because of the ambiguity regarding the length of the
2941 printf ("insn_current_address");
2945 fatal ("bad RTX code `%s' in attribute calculation\n",
2946 GET_RTX_NAME (code));
2952 /* Given an attribute value, return the maximum CONST_STRING argument
2953 encountered. It is assumed that they are all numeric. */
2956 max_attr_value (exp)
2959 int current_max = 0;
2963 if (GET_CODE (exp) == CONST_STRING)
2964 return atoi (XSTR (exp, 0));
2966 else if (GET_CODE (exp) == COND)
2968 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2970 n = max_attr_value (XVECEXP (exp, 0, i + 1));
2971 if (n > current_max)
2975 n = max_attr_value (XEXP (exp, 1));
2976 if (n > current_max)
2986 /* Scan an attribute value, possibly a conditional, and record what actions
2987 will be required to do any conditional tests in it.
2990 `must_extract' if we need to extract the insn operands
2991 `must_constrain' if we must compute `which_alternative'
2992 `address_used' if an address expression was used
2996 walk_attr_value (exp)
3006 code = GET_CODE (exp);
3010 if (! RTX_UNCHANGING_P (exp))
3011 /* Since this is an arbitrary expression, it can look at anything.
3012 However, constant expressions do not depend on any particular
3014 must_extract = must_constrain = 1;
3022 if (XSTR (exp, 0) == alternative_name)
3023 must_extract = must_constrain = 1;
3032 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
3037 walk_attr_value (XEXP (exp, i));
3041 if (XVEC (exp, i) != NULL)
3042 for (j = 0; j < XVECLEN (exp, i); j++)
3043 walk_attr_value (XVECEXP (exp, i, j));
3048 /* Write out a function to obtain the attribute for a given INSN. */
3051 write_attr_get (attr)
3052 struct attr_desc *attr;
3054 struct attr_value *av, *common_av;
3056 /* Find the most used attribute value. Handle that as the `default' of the
3057 switch we will generate. */
3058 common_av = find_most_used (attr);
3060 /* Write out start of function, then all values with explicit `case' lines,
3061 then a `default', then the value with the most uses. */
3062 if (attr->is_numeric)
3065 printf ("enum attr_%s\n", attr->name);
3067 /* If the attribute name starts with a star, the remainder is the name of
3068 the subroutine to use, instead of `get_attr_...'. */
3069 if (attr->name[0] == '*')
3070 printf ("%s (insn)\n", &attr->name[1]);
3071 else if (attr->is_const == 0)
3072 printf ("get_attr_%s (insn)\n", attr->name);
3075 printf ("get_attr_%s ()\n", attr->name);
3078 for (av = attr->first_value; av; av = av->next)
3079 if (av->num_insns != 0)
3080 write_attr_set (attr, 2, av->value, "return", ";",
3081 true_rtx, av->first_insn->insn_code,
3082 av->first_insn->insn_index);
3087 printf (" rtx insn;\n");
3089 printf (" switch (recog_memoized (insn))\n");
3092 for (av = attr->first_value; av; av = av->next)
3093 if (av != common_av)
3094 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3096 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3097 printf (" }\n}\n\n");
3100 /* Given an AND tree of known true terms (because we are inside an `if' with
3101 that as the condition or are in an `else' clause) and an expression,
3102 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3103 the bulk of the work. */
3106 eliminate_known_true (known_true, exp, insn_code, insn_index)
3109 int insn_code, insn_index;
3113 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
3115 if (GET_CODE (known_true) == AND)
3117 exp = eliminate_known_true (XEXP (known_true, 0), exp,
3118 insn_code, insn_index);
3119 exp = eliminate_known_true (XEXP (known_true, 1), exp,
3120 insn_code, insn_index);
3125 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
3131 /* Write out a series of tests and assignment statements to perform tests and
3132 sets of an attribute value. We are passed an indentation amount and prefix
3133 and suffix strings to write around each attribute value (e.g., "return"
3137 write_attr_set (attr, indent, value, prefix, suffix, known_true,
3138 insn_code, insn_index)
3139 struct attr_desc *attr;
3145 int insn_code, insn_index;
3147 if (GET_CODE (value) == CONST_STRING)
3149 write_indent (indent);
3150 printf ("%s ", prefix);
3151 write_attr_value (attr, value);
3152 printf ("%s\n", suffix);
3154 else if (GET_CODE (value) == COND)
3156 /* Assume the default value will be the default of the COND unless we
3157 find an always true expression. */
3158 rtx default_val = XEXP (value, 1);
3159 rtx our_known_true = known_true;
3164 for (i = 0; i < XVECLEN (value, 0); i += 2)
3169 testexp = eliminate_known_true (our_known_true,
3170 XVECEXP (value, 0, i),
3171 insn_code, insn_index);
3172 newexp = attr_rtx (NOT, testexp);
3173 newexp = insert_right_side (AND, our_known_true, newexp,
3174 insn_code, insn_index);
3176 /* If the test expression is always true or if the next `known_true'
3177 expression is always false, this is the last case, so break
3178 out and let this value be the `else' case. */
3179 if (testexp == true_rtx || newexp == false_rtx)
3181 default_val = XVECEXP (value, 0, i + 1);
3185 /* Compute the expression to pass to our recursive call as being
3187 inner_true = insert_right_side (AND, our_known_true,
3188 testexp, insn_code, insn_index);
3190 /* If this is always false, skip it. */
3191 if (inner_true == false_rtx)
3194 write_indent (indent);
3195 printf ("%sif ", first_if ? "" : "else ");
3197 write_test_expr (testexp, 0);
3199 write_indent (indent + 2);
3202 write_attr_set (attr, indent + 4,
3203 XVECEXP (value, 0, i + 1), prefix, suffix,
3204 inner_true, insn_code, insn_index);
3205 write_indent (indent + 2);
3207 our_known_true = newexp;
3212 write_indent (indent);
3214 write_indent (indent + 2);
3218 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
3219 prefix, suffix, our_known_true, insn_code, insn_index);
3223 write_indent (indent + 2);
3231 /* Write out the computation for one attribute value. */
3234 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, known_true)
3235 struct attr_desc *attr;
3236 struct attr_value *av;
3237 int write_case_lines;
3238 char *prefix, *suffix;
3242 struct insn_ent *ie;
3244 if (av->num_insns == 0)
3247 if (av->has_asm_insn)
3249 write_indent (indent);
3250 printf ("case -1:\n");
3251 write_indent (indent + 2);
3252 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3253 write_indent (indent + 2);
3254 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3255 write_indent (indent + 2);
3256 printf (" fatal_insn_not_found (insn);\n");
3259 if (write_case_lines)
3261 for (ie = av->first_insn; ie; ie = ie->next)
3262 if (ie->insn_code != -1)
3264 write_indent (indent);
3265 printf ("case %d:\n", ie->insn_code);
3270 write_indent (indent);
3271 printf ("default:\n");
3274 /* See what we have to do to handle output this value. */
3275 must_extract = must_constrain = address_used = 0;
3276 walk_attr_value (av->value);
3280 write_indent (indent + 2);
3281 printf ("insn_extract (insn);\n");
3286 #ifdef REGISTER_CONSTRAINTS
3287 write_indent (indent + 2);
3288 printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
3289 write_indent (indent + 2);
3290 printf (" fatal_insn_not_found (insn);\n");
3294 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
3295 known_true, av->first_insn->insn_code,
3296 av->first_insn->insn_index);
3298 if (strncmp (prefix, "return", 6))
3300 write_indent (indent + 2);
3301 printf ("break;\n");
3306 /* Utilities to write names in various forms. */
3309 write_attr_valueq (attr, s)
3310 struct attr_desc *attr;
3313 if (attr->is_numeric)
3317 write_upcase (attr->name);
3324 write_attr_value (attr, value)
3325 struct attr_desc *attr;
3328 if (GET_CODE (value) != CONST_STRING)
3331 write_attr_valueq (attr, XSTR (value, 0));
3339 if (*str < 'a' || *str > 'z')
3340 printf ("%c", *str++);
3342 printf ("%c", *str++ - 'a' + 'A');
3346 write_indent (indent)
3349 for (; indent > 8; indent -= 8)
3352 for (; indent; indent--)
3356 /* Write a subroutine that is given an insn that requires a delay slot, a
3357 delay slot ordinal, and a candidate insn. It returns non-zero if the
3358 candidate can be placed in the specified delay slot of the insn.
3360 We can write as many as three subroutines. `eligible_for_delay'
3361 handles normal delay slots, `eligible_for_annul_true' indicates that
3362 the specified insn can be annulled if the branch is true, and likewise
3363 for `eligible_for_annul_false'.
3365 KIND is a string distingushing these three cases ("delay", "annul_true",
3366 or "annul_false"). */
3369 write_eligible_delay (kind)
3372 struct delay_desc *delay;
3375 struct attr_desc *attr;
3376 struct attr_value *av, *common_av;
3379 /* Compute the maximum number of delay slots required. We use the delay
3380 ordinal times this number plus one, plus the slot number as an index into
3381 the appropriate predicate to test. */
3383 for (delay = delays, max_slots = 0; delay; delay = delay->next)
3384 if (XVECLEN (delay->def, 1) / 3 > max_slots)
3385 max_slots = XVECLEN (delay->def, 1) / 3;
3387 /* Write function prelude. */
3390 printf ("eligible_for_%s (delay_insn, slot, candidate_insn)\n", kind);
3391 printf (" rtx delay_insn;\n");
3392 printf (" int slot;\n");
3393 printf (" rtx candidate_insn;\n");
3395 printf (" rtx insn;\n");
3397 printf (" if (slot >= %d)\n", max_slots);
3398 printf (" abort ();\n");
3401 /* If more than one delay type, find out which type the delay insn is. */
3405 attr = find_attr ("*delay_type", 0);
3406 if (! attr) abort ();
3407 common_av = find_most_used (attr);
3409 printf (" insn = delay_insn;\n");
3410 printf (" switch (recog_memoized (insn))\n");
3413 sprintf (str, " * %d;\n break;", max_slots);
3414 for (av = attr->first_value; av; av = av->next)
3415 if (av != common_av)
3416 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
3418 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
3421 /* Ensure matched. Otherwise, shouldn't have been called. */
3422 printf (" if (slot < %d)\n", max_slots);
3423 printf (" abort ();\n\n");
3426 /* If just one type of delay slot, write simple switch. */
3427 if (num_delays == 1 && max_slots == 1)
3429 printf (" insn = candidate_insn;\n");
3430 printf (" switch (recog_memoized (insn))\n");
3433 attr = find_attr ("*delay_1_0", 0);
3434 if (! attr) abort ();
3435 common_av = find_most_used (attr);
3437 for (av = attr->first_value; av; av = av->next)
3438 if (av != common_av)
3439 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3441 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3447 /* Write a nested CASE. The first indicates which condition we need to
3448 test, and the inner CASE tests the condition. */
3449 printf (" insn = candidate_insn;\n");
3450 printf (" switch (slot)\n");
3453 for (delay = delays; delay; delay = delay->next)
3454 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
3456 printf (" case %d:\n",
3457 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
3458 printf (" switch (recog_memoized (insn))\n");
3461 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
3462 attr = find_attr (str, 0);
3463 if (! attr) abort ();
3464 common_av = find_most_used (attr);
3466 for (av = attr->first_value; av; av = av->next)
3467 if (av != common_av)
3468 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
3470 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
3474 printf (" default:\n");
3475 printf (" abort ();\n");
3482 /* Write routines to compute conflict cost for function units. Then write a
3483 table describing the available function units. */
3486 write_function_unit_info ()
3488 struct function_unit *unit;
3489 struct attr_desc *case_attr, *attr;
3490 struct attr_value *av, *common_av;
3496 /* Write out conflict routines for function units. Don't bother writing
3497 one if there is only one busy value. */
3499 for (unit = units; unit; unit = unit->next)
3501 /* See if only one case exists and if there is a constant value for
3502 that case. If so, we don't need a function. */
3503 str = (char *) alloca (strlen (unit->name) + 10);
3504 sprintf (str, "*%s_cases", unit->name);
3505 attr = find_attr (str, 0);
3506 if (! attr) abort ();
3507 value = find_single_value (attr);
3508 if (value && GET_CODE (value) == CONST_STRING)
3510 sprintf (str, "*%s_case_%s", unit->name, XSTR (value, 0));
3511 attr = find_attr (str, 0);
3512 if (! attr) abort ();
3513 value = find_single_value (attr);
3514 if (value && GET_CODE (value) == CONST_STRING)
3516 unit->needs_conflict_function = 0;
3517 unit->default_cost = value;
3522 /* The function first computes the case from the candidate insn. */
3523 unit->needs_conflict_function = 1;
3524 unit->default_cost = make_numeric_value (0);
3526 printf ("static int\n");
3527 printf ("%s_unit_conflict_cost (executing_insn, candidate_insn)\n",
3529 printf (" rtx executing_insn;\n");
3530 printf (" rtx candidate_insn;\n");
3532 printf (" rtx insn;\n");
3533 printf (" int casenum;\n\n");
3534 printf (" insn = candidate_insn;\n");
3535 printf (" switch (recog_memoized (insn))\n");
3538 /* Write the `switch' statement to get the case value. */
3539 sprintf (str, "*%s_cases", unit->name);
3540 case_attr = find_attr (str, 0);
3541 if (! case_attr) abort ();
3542 common_av = find_most_used (case_attr);
3544 for (av = case_attr->first_value; av; av = av->next)
3545 if (av != common_av)
3546 write_attr_case (case_attr, av, 1,
3547 "casenum =", ";", 4, unit->condexp);
3549 write_attr_case (case_attr, common_av, 0,
3550 "casenum =", ";", 4, unit->condexp);
3553 /* Now write an outer switch statement on each case. Then write
3554 the tests on the executing function within each. */
3555 printf (" insn = executing_insn;\n");
3556 printf (" switch (casenum)\n");
3559 for (i = 0; i < unit->num_opclasses; i++)
3561 /* Ensure using this case. */
3563 for (av = case_attr->first_value; av; av = av->next)
3565 && contained_in_p (make_numeric_value (i), av->value))
3571 printf (" case %d:\n", i);
3572 sprintf (str, "*%s_case_%d", unit->name, i);
3573 attr = find_attr (str, 0);
3574 if (! attr) abort ();
3576 /* If single value, just write it. */
3577 value = find_single_value (attr);
3579 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2);
3582 common_av = find_most_used (attr);
3583 printf (" switch (recog_memoized (insn))\n");
3586 for (av = attr->first_value; av; av = av->next)
3587 if (av != common_av)
3588 write_attr_case (attr, av, 1,
3589 "return", ";", 8, unit->condexp);
3591 write_attr_case (attr, common_av, 0,
3592 "return", ";", 8, unit->condexp);
3597 printf (" }\n}\n\n");
3600 /* Now that all functions have been written, write the table describing
3601 the function units. The name is included for documenation purposes
3604 printf ("struct function_unit_desc function_units[] = {\n");
3606 for (unit = units; unit; unit = unit->next)
3608 printf (" {\"%s\", %d, %d, %d, %s, %s_unit_ready_cost, ",
3609 unit->name, 1 << unit->num, unit->multiplicity,
3610 unit->simultaneity, XSTR (unit->default_cost, 0), unit->name);
3612 if (unit->needs_conflict_function)
3613 printf ("%s_unit_conflict_cost", unit->name);
3623 /* This page contains miscellaneous utility routines. */
3625 /* Given a string, return the number of comma-separated elements in it.
3626 Return 0 for the null string. */
3637 for (n = 1; *s; s++)
3644 /* Given a pointer to a (char *), return a malloc'ed string containing the
3645 next comma-separated element. Advance the pointer to after the string
3646 scanned, or the end-of-string. Return NULL if at end of string. */
3649 next_comma_elt (pstr)
3658 /* Find end of string to compute length. */
3659 for (p = *pstr; *p != ',' && *p != '\0'; p++)
3662 out_str = attr_string (*pstr, p - *pstr);
3671 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
3672 is non-zero, build a new attribute, if one does not exist. */
3674 static struct attr_desc *
3675 find_attr (name, create)
3679 struct attr_desc *attr;
3682 /* Before we resort to using `strcmp', see if the string address matches
3683 anywhere. In most cases, it should have been canonicalized to do so. */
3684 if (name == alternative_name)
3687 for (attr = attrs; attr; attr = attr->next)
3688 if (name == attr->name)
3691 /* Otherwise, do it the slow way. */
3692 for (attr = attrs; attr; attr = attr->next)
3693 if (! strcmp (name, attr->name))
3699 new_name = (char *) xmalloc (strlen (name) + 1);
3700 strcpy (new_name, name);
3702 attr = (struct attr_desc *) xmalloc (sizeof (struct attr_desc));
3703 attr->name = new_name;
3704 attr->first_value = attr->default_val = NULL;
3705 attr->is_numeric = attr->is_const = attr->is_special = 0;
3712 /* Create internal attribute with the given default value. */
3715 make_internal_attr (name, value, special)
3720 struct attr_desc *attr;
3722 attr = find_attr (name, 1);
3723 if (attr->default_val)
3726 attr->is_numeric = 1;
3728 attr->is_special = special;
3729 attr->default_val = get_attr_value (value, attr, -2);
3732 /* Find the most used value of an attribute. */
3734 static struct attr_value *
3735 find_most_used (attr)
3736 struct attr_desc *attr;
3738 struct attr_value *av;
3739 struct attr_value *most_used;
3745 for (av = attr->first_value; av; av = av->next)
3746 if (av->num_insns > nuses)
3747 nuses = av->num_insns, most_used = av;
3752 /* If an attribute only has a single value used, return it. Otherwise
3756 find_single_value (attr)
3757 struct attr_desc *attr;
3759 struct attr_value *av;
3762 unique_value = NULL;
3763 for (av = attr->first_value; av; av = av->next)
3769 unique_value = av->value;
3772 return unique_value;
3775 /* Return (attr_value "n") */
3778 make_numeric_value (n)
3781 static rtx int_values[20];
3788 if (n < 20 && int_values[n])
3789 return int_values[n];
3791 p = attr_printf ((n < 1000 ? 4 : HOST_BITS_PER_INT * 3 / 10 + 3), "%d", n);
3792 exp = attr_rtx (CONST_STRING, p);
3795 int_values[n] = exp;
3801 xrealloc (ptr, size)
3805 char *result = (char *) realloc (ptr, size);
3807 fatal ("virtual memory exhausted");
3815 register char *val = (char *) malloc (size);
3818 fatal ("virtual memory exhausted");
3826 fprintf (stderr, "genattrtab: ");
3827 fprintf (stderr, s, a1, a2);
3828 fprintf (stderr, "\n");
3829 exit (FATAL_EXIT_CODE);
3832 /* More 'friendly' abort that prints the line and file.
3833 config.h can #define abort fancy_abort if you like that sort of thing. */
3838 fatal ("Internal gcc abort.");
3849 struct attr_desc *attr;
3850 struct attr_value *av;
3851 struct insn_def *id;
3854 obstack_init (rtl_obstack);
3857 fatal ("No input file name.");
3859 infile = fopen (argv[1], "r");
3863 exit (FATAL_EXIT_CODE);
3868 /* Set up true and false rtx's */
3869 true_rtx = attr_rtx (CONST_INT, 1);
3870 false_rtx = attr_rtx (CONST_INT, 0);
3871 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
3873 printf ("/* Generated automatically by the program `genattrtab'\n\
3874 from the machine description file `md'. */\n\n");
3876 /* Read the machine description. */
3880 c = read_skip_spaces (infile);
3885 desc = read_rtx (infile);
3886 if (GET_CODE (desc) == DEFINE_INSN
3887 || GET_CODE (desc) == DEFINE_PEEPHOLE
3888 || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
3891 else if (GET_CODE (desc) == DEFINE_EXPAND)
3892 insn_code_number++, insn_index_number++;
3894 else if (GET_CODE (desc) == DEFINE_SPLIT)
3895 insn_code_number++, insn_index_number++;
3897 else if (GET_CODE (desc) == DEFINE_ATTR)
3900 insn_index_number++;
3903 else if (GET_CODE (desc) == DEFINE_DELAY)
3906 insn_index_number++;
3909 else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
3912 insn_index_number++;
3916 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
3917 if (! got_define_asm_attributes)
3919 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
3920 XVEC (tem, 0) = rtvec_alloc (0);
3924 /* Expand DEFINE_DELAY information into new attribute. */
3928 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
3932 printf ("#include \"config.h\"\n");
3933 printf ("#include \"rtl.h\"\n");
3934 printf ("#include \"insn-config.h\"\n");
3935 printf ("#include \"recog.h\"\n");
3936 printf ("#include \"regs.h\"\n");
3937 printf ("#include \"real.h\"\n");
3938 printf ("#include \"output.h\"\n");
3939 printf ("#include \"insn-attr.h\"\n");
3941 printf ("#define operands recog_operand\n\n");
3943 /* Make `insn_alternatives'. */
3944 insn_alternatives = (int *) xmalloc (insn_code_number * sizeof (int));
3945 for (id = defs; id; id = id->next)
3946 if (id->insn_code >= 0)
3947 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
3949 /* Prepare to write out attribute subroutines by checking everything stored
3950 away and building the attribute cases. */
3953 for (attr = attrs; attr; attr = attr->next)
3955 check_attr_value (attr->default_val->value, attr);
3959 /* Construct extra attributes for `length'. */
3960 make_length_attrs ();
3962 /* Perform any possible optimizations to speed up compilation. */
3965 /* Now write out all the `gen_attr_...' routines. Do these before the
3966 special routines (specifically before write_function_unit_info), so
3967 that they get defined before they are used. */
3969 for (attr = attrs; attr; attr = attr->next)
3971 if (! attr->is_special)
3972 write_attr_get (attr);
3975 /* Write out delay eligibility information, if DEFINE_DELAY present.
3976 (The function to compute the number of delay slots will be written
3980 write_eligible_delay ("delay");
3981 if (have_annul_true)
3982 write_eligible_delay ("annul_true");
3983 if (have_annul_false)
3984 write_eligible_delay ("annul_false");
3987 /* Write out information about function units. */
3989 write_function_unit_info ();
3992 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);