*** empty log message ***
[official-gcc.git] / gcc / genattrtab.c
blob1fbdc5db53a7b86ec848a3644b9b33b25bfb0ad1
1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1989, 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)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 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 call `get_attr_...', one for each
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
32 expression).
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
45 `get_attr_length'.
47 Internal attributes are defined to handle DEFINE_DELAY and
48 DEFINE_FUNCTION_UNIT. Special routines are output for these cases.
50 This program works by keeping a list of possible values for each attribute.
51 These include the basic attribute choices, default values for attribute, and
52 all derived quantities.
54 As the description file is read, the definition for each insn is saved in a
55 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
56 is created for each insn and chained to the corresponding attribute value,
57 either that specified, or the default.
59 An optimization phase is then run. This simplifies expressions for each
60 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
61 indicates when the attribute has the specified value for the insn. This
62 avoids recursive calls during compilation.
64 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
65 definitions is to create arbitrarily complex expressions and have the
66 optimization simplify them.
68 Once optimization is complete, any required routines and definitions
69 will be written. */
71 #include <stdio.h>
72 #include "config.h"
73 #include "rtl.h"
74 #include "obstack.h"
75 #include "insn-config.h" /* For REGISTER_CONSTRAINTS */
77 static struct obstack obstack;
78 struct obstack *rtl_obstack = &obstack;
80 #define obstack_chunk_alloc xmalloc
81 #define obstack_chunk_free free
83 extern void free ();
85 static void fatal ();
86 void fancy_abort ();
88 /* Define structures used to record attributes and values. */
90 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
91 encountered, we store all the relevant information into a
92 `struct insn_def'. This is done to allow attribute definitions to occur
93 anywhere in the file. */
95 struct insn_def
97 int insn_code; /* Instruction number. */
98 int insn_index; /* Expression numer in file, for errors. */
99 struct insn_def *next; /* Next insn in chain. */
100 rtx def; /* The DEFINE_... */
101 int num_alternatives; /* Number of alternatives. */
102 int vec_idx; /* Index of attribute vector in `def'. */
105 /* Once everything has been read in, we store in each attribute value a list
106 of insn codes that have that value. Here is the structure used for the
107 list. */
109 struct insn_ent
111 int insn_code; /* Instruction number. */
112 int insn_index; /* Index of definition in file */
113 struct insn_ent *next; /* Next in chain. */
116 /* Each value of an attribute (either constant or computed) is assigned a
117 structure which is used as the listhead of the insns that have that
118 value. */
120 struct attr_value
122 rtx value; /* Value of attribute. */
123 struct attr_value *next; /* Next attribute value in chain. */
124 struct insn_ent *first_insn; /* First insn with this value. */
125 int num_insns; /* Number of insns with this value. */
126 int has_asm_insn; /* True if this value used for `asm' insns */
129 /* Structure for each attribute. */
131 struct attr_desc
133 char *name; /* Name of attribute. */
134 struct attr_desc *next; /* Next attribute. */
135 int is_numeric; /* Values of this attribute are numeric. */
136 int is_special; /* Don't call `write_attr_set'. */
137 struct attr_value *first_value; /* First value of this attribute. */
138 struct attr_value *default_val; /* Default value for this attribute. */
141 /* Structure for each DEFINE_DELAY. */
143 struct delay_desc
145 rtx def; /* DEFINE_DELAY expression. */
146 struct delay_desc *next; /* Next DEFINE_DELAY. */
147 int num; /* Number of DEFINE_DELAY, starting at 1. */
150 /* Record information about each DEFINE_FUNCTION_UNIT. */
152 struct function_unit_op
154 rtx condexp; /* Expression TRUE for applicable insn. */
155 struct function_unit_op *next; /* Next operation for this function unit. */
156 int num; /* Ordinal for this operation type in unit. */
157 int ready; /* Cost until data is ready. */
158 rtx busyexp; /* Expression computing conflict cost. */
161 /* Record information about each function unit mentioned in a
162 DEFINE_FUNCTION_UNIT. */
164 struct function_unit
166 char *name; /* Function unit name. */
167 struct function_unit *next; /* Next function unit. */
168 int num; /* Ordinal of this unit type. */
169 int multiplicity; /* Number of units of this type. */
170 int simultaneity; /* Maximum number of simultaneous insns
171 on this function unit or 0 if unlimited. */
172 rtx condexp; /* Expression TRUE for insn needing unit. */
173 rtx costexp; /* Worst-case cost as function of insn. */
174 int num_opclasses; /* Number of different operation types. */
175 struct function_unit_op *ops; /* Pointer to first operation type. */
176 int needs_conflict_function; /* Nonzero if a conflict function required. */
177 rtx default_cost; /* Conflict cost, if constant. */
180 /* Listheads of above structures. */
182 static struct attr_desc *attrs;
183 static struct insn_def *defs;
184 static struct delay_desc *delays;
185 static struct function_unit *units;
187 /* Other variables. */
189 static int insn_code_number;
190 static int insn_index_number;
191 static int got_define_asm_attributes;
192 static int must_extract;
193 static int must_constrain;
194 static int address_used;
195 static int num_delays;
196 static int have_annul_true, have_annul_false;
197 static int num_units;
199 /* Used as operand to `operate_exp': */
201 enum operator {PLUS_OP, MINUS_OP, OR_OP, MAX_OP};
203 /* Stores, for each insn code, a bitmap that has bits on for each possible
204 alternative. */
206 static int *insn_alternatives;
208 /* Used to simplify expressions. */
210 static rtx true_rtx, false_rtx;
212 /* Used to reduce calls to `strcmp' */
214 static char *alternative_name = "alternative";
216 /* Simplify an expression. Only call the routine if there is something to
217 simplify. */
218 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
219 (RTX_UNCHANGING_P (EXP) ? (EXP) \
220 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
222 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
223 They won't actually be used. */
225 rtx frame_pointer_rtx, stack_pointer_rtx, arg_pointer_rtx;
227 static rtx check_attr_test ();
228 static void check_attr_value ();
229 static rtx convert_set_attr_alternative ();
230 static rtx convert_set_attr ();
231 static void check_defs ();
232 static rtx make_canonical ();
233 static struct attr_value *get_attr_value ();
234 static void expand_delays ();
235 static rtx operate_exp ();
236 static void expand_units ();
237 static void fill_attr ();
238 static rtx substitute_address ();
239 static void make_length_attrs ();
240 static rtx identity_fn ();
241 static rtx zero_fn ();
242 static rtx one_fn ();
243 static rtx max_fn ();
244 static rtx simplify_cond ();
245 static void remove_insn_ent ();
246 static void insert_insn_ent ();
247 static rtx insert_right_side ();
248 static rtx make_alternative_compare ();
249 static int compute_alternative_mask ();
250 static rtx evaluate_eq_attr ();
251 static rtx simplify_and_tree ();
252 static rtx simplify_or_tree ();
253 static rtx simplify_test_exp ();
254 static void optimize_attrs ();
255 static void gen_attr ();
256 static int count_alternatives ();
257 static int compares_alternatives_p ();
258 static int contained_in_p ();
259 static void gen_insn ();
260 static void gen_delay ();
261 static void gen_unit ();
262 static void write_test_expr ();
263 static int max_attr_value ();
264 static void walk_attr_value ();
265 static void write_attr_get ();
266 static rtx eliminate_known_true ();
267 static void write_attr_set ();
268 static void write_attr_case ();
269 static void write_attr_value ();
270 static void write_attr_valueq ();
271 static void write_upcase ();
272 static void write_indent ();
273 static void write_eligible_delay ();
274 static void write_function_unit_info ();
275 static int n_comma_elts ();
276 static char *next_comma_elt ();
277 static struct attr_desc *find_attr ();
278 static void make_internal_attr ();
279 static struct attr_value *find_most_used ();
280 static rtx find_single_value ();
281 static rtx make_numeric_value ();
282 char *xrealloc ();
283 char *xmalloc ();
284 static void fatal ();
286 /* Given a test expression for an attribute, ensure it is validly formed.
287 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
288 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
289 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
291 Update the string address in EQ_ATTR expression to be the same used
292 in the attribute (or `alternative_name') to speed up subsequent
293 `find_attr' calls and eliminate most `strcmp' calls.
295 Return the new expression, if any. */
297 static rtx
298 check_attr_test (exp)
299 rtx exp;
301 struct attr_desc *attr;
302 struct attr_value *av;
303 char *name_ptr, *p;
304 rtx orexp, newexp;
306 switch (GET_CODE (exp))
308 case EQ_ATTR:
309 /* Handle negation test. */
310 if (XSTR (exp, 1)[0] == '!')
312 XSTR(exp, 1) = &XSTR(exp, 1)[1];
313 newexp = rtx_alloc (NOT);
314 XEXP (newexp, 0) = exp;
316 return check_attr_test (newexp);
319 else if (n_comma_elts (XSTR (exp, 1)) == 1)
321 attr = find_attr (XEXP (exp, 0), 0);
322 if (attr == NULL)
324 if (! strcmp (XSTR (exp, 0), "alternative"))
326 XSTR (exp, 0) = alternative_name;
327 /* This can't be simplified any further. */
328 RTX_UNCHANGING_P (exp) = 1;
329 return exp;
331 else
332 fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp, 0));
335 XSTR (exp, 0) = attr->name;
337 if (attr->is_numeric)
339 for (p = XSTR (exp, 1); *p; p++)
340 if (*p < '0' || *p > '9')
341 fatal ("Attribute `%s' takes only numeric values",
342 XEXP (exp, 0));
344 else
346 for (av = attr->first_value; av; av = av->next)
347 if (GET_CODE (av->value) == CONST_STRING
348 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
349 break;
351 if (av == NULL)
352 fatal ("Unknown value `%s' for `%s' attribute",
353 XEXP (exp, 1), XEXP (exp, 0));
356 else
358 /* Make an IOR tree of the possible values. */
359 orexp = false_rtx;
360 name_ptr = XSTR (exp, 1);
361 while ((p = next_comma_elt (&name_ptr)) != NULL)
363 newexp = rtx_alloc (EQ_ATTR);
364 XSTR (newexp, 0) = XSTR (exp, 0);
365 XSTR (newexp, 1) = p;
366 orexp = insert_right_side (IOR, orexp, newexp, -2);
369 return check_attr_test (orexp);
371 break;
373 case CONST_INT:
374 /* Either TRUE or FALSE. */
375 if (XINT (exp, 0))
376 return true_rtx;
377 else
378 return false_rtx;
380 case IOR:
381 case AND:
382 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
383 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1));
384 break;
386 case NOT:
387 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
388 break;
390 case MATCH_OPERAND:
391 case LE: case LT: case GT: case GE:
392 case LEU: case LTU: case GTU: case GEU:
393 case NE: case EQ:
394 /* These cases can't be simplified. */
395 RTX_UNCHANGING_P (exp) = 1;
396 break;
398 default:
399 fatal ("RTL operator \"%s\" not valid in attribute test",
400 GET_RTX_NAME (GET_CODE (exp)));
403 return exp;
406 /* Given an expression, ensure that it is validly formed and that all named
407 attribute values are valid for the given attribute. Issue a fatal error
408 if not. If no attribute is specified, assume a numeric attribute. */
410 static void
411 check_attr_value (exp, attr)
412 rtx exp;
413 struct attr_desc *attr;
415 struct attr_value *av;
416 char *p;
417 int i;
419 switch (GET_CODE (exp))
421 case CONST_INT:
422 if (attr && ! attr->is_numeric)
423 fatal ("CONST_INT not valid for non-numeric `%s' attribute",
424 attr->name);
426 if (INTVAL (exp) < 0)
427 fatal ("Negative numeric value specified for `%s' attribute",
428 attr->name);
430 break;
432 case CONST_STRING:
433 if (! strcmp (XSTR (exp, 0), "*"))
434 break;
436 if (attr == 0 || attr->is_numeric)
438 for (p = XSTR (exp, 0); *p; p++)
439 if (*p > '9' || *p < '0')
440 fatal ("Non-numeric value for numeric `%s' attribute",
441 attr ? "internal" : attr->name);
442 break;
445 for (av = attr->first_value; av; av = av->next)
446 if (GET_CODE (av->value) == CONST_STRING
447 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
448 break;
450 if (av == NULL)
451 fatal ("Unknown value `%s' for `%s' attribute",
452 XSTR (exp, 0), attr ? "internal" : attr->name);
454 return;
456 case IF_THEN_ELSE:
457 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
458 check_attr_value (XEXP (exp, 1), attr);
459 check_attr_value (XEXP (exp, 2), attr);
460 return;
462 case COND:
463 if (XVECLEN (exp, 0) % 2 != 0)
464 fatal ("First operand of COND must have even length");
466 for (i = 0; i < XVECLEN (exp, 0); i += 2)
468 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i));
469 check_attr_value (XVECEXP (exp, 0, i + 1), attr);
472 check_attr_value (XEXP (exp, 1), attr);
473 return;
475 default:
476 fatal ("Illegal operation `%s' for attribute value",
477 GET_RTX_NAME (GET_CODE (exp)));
481 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
482 It becomes a COND with each test being (eq_attr "alternative "n") */
484 static rtx
485 convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
486 rtx exp;
487 int num_alt;
488 int insn_code, insn_index;
490 rtx newexp;
491 rtx condexp;
492 int i;
494 if (XVECLEN (exp, 1) != num_alt)
495 fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
496 insn_index);
498 /* Make a COND with all tests but the last. Select the last value via the
499 default. */
500 condexp = rtx_alloc (COND);
501 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
503 for (i = 0; i < num_alt - 1; i++)
505 XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
506 XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
507 XSTR (XVECEXP (condexp, 0, 2 * i), 1) = (char *) xmalloc (3);
508 sprintf (XSTR (XVECEXP (condexp, 0, 2 * i), 1), "%d", i);
509 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
512 XEXP (condexp, 1) = XVECEXP (exp, 1, i);
514 newexp = rtx_alloc (SET);
515 XEXP (newexp, 0) = rtx_alloc (ATTR);
516 XSTR (XEXP (newexp, 0), 0) = XSTR (exp, 0);
517 XEXP (newexp, 1) = condexp;
519 return newexp;
522 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
523 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
525 static rtx
526 convert_set_attr (exp, num_alt, insn_code, insn_index)
527 rtx exp;
528 int num_alt;
529 int insn_code, insn_index;
531 rtx newexp;
532 char *name_ptr;
533 char *p;
534 int n;
536 /* See how many alternative specified. */
537 n = n_comma_elts (XSTR (exp, 1));
538 if (n == 1)
540 newexp = rtx_alloc (SET);
541 XEXP (newexp, 0) = rtx_alloc (ATTR);
542 XSTR (XEXP (newexp, 0), 0) = XSTR (exp, 0);
543 XEXP (newexp, 1) = rtx_alloc (CONST_STRING);
544 XSTR (XEXP (newexp, 1), 0) = XSTR (exp, 1);
546 return newexp;
549 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
550 XSTR (newexp, 0) = XSTR (exp, 0);
551 XVEC (newexp, 1) = rtvec_alloc (n);
553 /* Process each comma-separated name. */
554 name_ptr = XSTR (exp, 1);
555 n = 0;
556 while ((p = next_comma_elt (&name_ptr)) != NULL)
558 XVECEXP (newexp, 1, n) = rtx_alloc (CONST_STRING);
559 XSTR (XVECEXP (newexp, 1, n++), 0) = p;
562 return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
565 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
566 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
567 expressions. */
569 static void
570 check_defs ()
572 struct insn_def *id;
573 struct attr_desc *attr;
574 int i;
575 rtx value;
577 for (id = defs; id; id = id->next)
579 if (XVEC (id->def, id->vec_idx) == NULL)
580 continue;
582 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
584 value = XVECEXP (id->def, id->vec_idx, i);
585 switch (GET_CODE (value))
587 case SET:
588 if (GET_CODE (XEXP (value, 0)) != ATTR)
589 fatal ("Bad attribute set in pattern %d", id->insn_index);
590 break;
592 case SET_ATTR_ALTERNATIVE:
593 value = convert_set_attr_alternative (value,
594 id->num_alternatives,
595 id->insn_code,
596 id->insn_index);
597 break;
599 case SET_ATTR:
600 value = convert_set_attr (value, id->num_alternatives,
601 id->insn_code, id->insn_index);
602 break;
604 default:
605 fatal ("Invalid attribute code `%s' for pattern %d",
606 GET_RTX_NAME (GET_CODE (value)), id->insn_index);
609 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
610 fatal ("Unknown attribute `%s' for pattern number %d",
611 XSTR (XEXP (value, 0), 0), id->insn_index);
613 XVECEXP (id->def, id->vec_idx, i) = value;
614 check_attr_value (XEXP (value, 1), attr);
619 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
620 expressions by converting them into a COND. This removes cases from this
621 program. Also, replace an attribute value of "*" with the default attribute
622 value. */
624 static rtx
625 make_canonical (attr, exp)
626 struct attr_desc *attr;
627 rtx exp;
629 int i;
630 rtx newexp;
632 switch (GET_CODE (exp))
634 case CONST_INT:
635 exp = make_numeric_value (INTVAL (exp));
636 break;
638 case CONST_STRING:
639 if (! strcmp (XSTR (exp, 0), "*"))
641 if (attr == 0 || attr->default_val == 0)
642 fatal ("(attr_value \"*\") used in invalid context.");
643 exp = attr->default_val->value;
646 break;
648 case IF_THEN_ELSE:
649 newexp = rtx_alloc (COND);
650 XVEC (newexp, 0) = rtvec_alloc (2);
651 XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
652 XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
654 XEXP (newexp, 1) = XEXP (exp, 2);
656 exp = newexp;
657 /* Fall through to COND case since this is now a COND. */
659 case COND:
660 /* First, check for degenerate COND. */
661 if (XVECLEN (exp, 0) == 0)
662 return make_canonical (attr, XEXP (exp, 1));
664 for (i = 0; i < XVECLEN (exp, 0); i += 2)
665 XVECEXP (exp, 0, i + 1)
666 = make_canonical (attr, XVECEXP (exp, 0, i + 1));
668 XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
669 break;
672 return exp;
675 /* Given a value and an attribute description, return a `struct attr_value *'
676 that represents that value. This is either an existing structure, if the
677 value has been previously encountered, or a newly-created structure.
679 `insn_code' is the code of an insn whose attribute has the specified
680 value (-2 if not processing an insn). We ensure that all insns for
681 a given value have the same number of alternatives if the value checks
682 alternatives. */
684 static struct attr_value *
685 get_attr_value (value, attr, insn_code)
686 rtx value;
687 struct attr_desc *attr;
688 int insn_code;
690 struct attr_value *av;
691 int num_alt = 0;
693 value = make_canonical (attr, value);
694 if (compares_alternatives_p (value))
696 if (insn_code < 0 || insn_alternatives == NULL)
697 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
698 else
699 num_alt = insn_alternatives[insn_code];
702 for (av = attr->first_value; av; av = av->next)
703 if (rtx_equal_p (value, av->value)
704 && (num_alt == 0 || av->first_insn == NULL
705 || insn_alternatives[av->first_insn->insn_code]))
706 return av;
708 av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
709 av->value = value;
710 av->next = attr->first_value;
711 attr->first_value = av;
712 av->first_insn = NULL;
713 av->num_insns = 0;
714 av->has_asm_insn = 0;
716 return av;
719 /* After all DEFINE_DELAYs have been read in, create internal attributes
720 to generate the required routines.
722 First, we compute the number of delay slots for each insn (as a COND of
723 each of the test expressions in DEFINE_DELAYs). Then, if more than one
724 delay type is specified, we compute a similar function giving the
725 DEFINE_DELAY ordinal for each insn.
727 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
728 tells whether a given insn can be in that delay slot.
730 Normal attrbute filling and optimization expands these to contain the
731 information needed to handle delay slots. */
733 static void
734 expand_delays ()
736 struct delay_desc *delay;
737 rtx condexp;
738 rtx newexp;
739 int i;
740 char *p;
742 /* First, generate data for `num_delay_slots' function. */
744 condexp = rtx_alloc (COND);
745 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
746 XEXP (condexp, 1) = make_numeric_value (0);
748 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
750 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
751 XVECEXP (condexp, 0, i + 1)
752 = make_numeric_value (XVECLEN (delay->def, 1) / 3);
755 make_internal_attr ("*num_delay_slots", condexp, 0);
757 /* If more than one delay type, do the same for computing the delay type. */
758 if (num_delays > 1)
760 condexp = rtx_alloc (COND);
761 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
762 XEXP (condexp, 1) = make_numeric_value (0);
764 for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
766 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
767 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
770 make_internal_attr ("*delay_type", condexp, 1);
773 /* For each delay possibility and delay slot, compute an eligability
774 attribute for non-anulled insns and for each type of annulled (annul
775 if true and annul if false). */
776 for (delay = delays; delay; delay = delay->next)
778 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
780 newexp = rtx_alloc (IF_THEN_ELSE);
781 condexp = XVECEXP (delay->def, 1, i);
782 if (condexp == 0) condexp = false_rtx;
783 XEXP (newexp, 0) = condexp;
784 XEXP (newexp, 1) = make_numeric_value (1);
785 XEXP (newexp, 2) = make_numeric_value (0);
787 p = (char *) xmalloc (13);
788 sprintf (p, "*delay_%d_%d", delay->num, i / 3);
789 make_internal_attr (p, newexp, 1);
791 if (have_annul_true)
793 newexp = rtx_alloc (IF_THEN_ELSE);
794 condexp = XVECEXP (delay->def, 1, i + 1);
795 if (condexp == 0) condexp = false_rtx;
796 XEXP (newexp, 0) = condexp;
797 XEXP (newexp, 1) = make_numeric_value (1);
798 XEXP (newexp, 2) = make_numeric_value (0);
799 p = (char *) xmalloc (18);
800 sprintf (p, "*annul_true_%d_%d", delay->num, i / 3);
801 make_internal_attr (p, newexp, 1);
804 if (have_annul_false)
806 newexp = rtx_alloc (IF_THEN_ELSE);
807 condexp = XVECEXP (delay->def, 1, i + 2);
808 if (condexp == 0) condexp = false_rtx;
809 XEXP (newexp, 0) = condexp;
810 XEXP (newexp, 1) = make_numeric_value (1);
811 XEXP (newexp, 2) = make_numeric_value (0);
812 p = (char *) xmalloc (18);
813 sprintf (p, "*annul_false_%d_%d", delay->num, i / 3);
814 make_internal_attr (p, newexp, 1);
820 /* This function is given a left and right side expression and an operator.
821 Each side is a conditional expression, each alternative of which has a
822 numerical value. The function returns another conditional expression
823 which, for every possible set of condition values, returns a value that is
824 the operator applied to the values of the two sides.
826 Since this is called early, it must also support IF_THEN_ELSE. */
828 static rtx
829 operate_exp (op, left, right)
830 enum operator op;
831 rtx left, right;
833 int left_value, right_value;
834 rtx newexp;
835 int i;
837 /* If left is a string, apply operator to it and the right side. */
838 if (GET_CODE (left) == CONST_STRING)
840 /* If right is also a string, just perform the operation. */
841 if (GET_CODE (right) == CONST_STRING)
843 left_value = atoi (XSTR (left, 0));
844 right_value = atoi (XSTR (right, 0));
845 switch (op)
847 case PLUS_OP:
848 i = left_value + right_value;
849 break;
851 case MINUS_OP:
852 i = left_value - right_value;
853 break;
855 case OR_OP:
856 i = left_value | right_value;
857 break;
859 case MAX_OP:
860 if (left_value > right_value)
861 i = left_value;
862 else
863 i = right_value;
864 break;
866 default:
867 abort ();
870 return make_numeric_value (i);
872 else if (GET_CODE (right) == IF_THEN_ELSE)
874 /* Apply recursively to all values within. */
875 newexp = rtx_alloc (IF_THEN_ELSE);
876 XEXP (newexp, 0) = XEXP (right, 0);
877 XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
878 XEXP (newexp, 2) = operate_exp (op, left, XEXP (right, 2));
880 return newexp;
882 else if (GET_CODE (right) == COND)
884 newexp = rtx_alloc (COND);
885 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
886 for (i = 0; i < XVECLEN (right, 0); i += 2)
888 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
889 XVECEXP (newexp, 0, i + 1)
890 = operate_exp (op, left, XVECEXP (right, 0, i + 1));
893 XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
895 return newexp;
897 else
898 fatal ("Badly formed attribute value");
901 /* Otherwise, do recursion the other way. */
902 else if (GET_CODE (left) == IF_THEN_ELSE)
904 newexp = rtx_alloc (IF_THEN_ELSE);
905 XEXP (newexp, 0) = XEXP (left, 0);
906 XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
907 XEXP (newexp, 2) = operate_exp (op, XEXP (left, 2), right);
909 return newexp;
912 else if (GET_CODE (left) == COND)
914 newexp = rtx_alloc (COND);
915 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
916 for (i = 0; i < XVECLEN (left, 0); i += 2)
918 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
919 XVECEXP (newexp, 0, i + 1)
920 = operate_exp (op, XVECEXP (left, 0, i + 1), right);
923 XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
925 return newexp;
928 else
929 fatal ("Badly formed attribute value.");
930 /* NOTREACHED */
931 return NULL;
934 /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
935 construct a number of attributes.
937 The first produces a function `function_units_used' which is given an
938 insn and produces a mask showing which function units are required for
939 the execution of that insn.
941 The second produces a function `result_ready_cost' which is used to
942 determine the time that the result of an insn will be ready and hence
943 a worst-case schedule.
945 Both of these produce quite complex expressions which are then set as the
946 default value of internal attributes. Normal attribute simplification
947 should produce reasonable expressions.
949 For each unit, a `<name>_unit_ready_cost' function will take an
950 insn and give the delay until that unit will be ready with the result
951 and a `<name>_unit_busy_delay' function is given an insn already
952 executing on the unit and a candidate to execute and will give the
953 cost from the time the executing insn started until the candidate
954 can start (ignore limitations on the number of simultaneous insns). */
956 static void
957 expand_units ()
959 struct function_unit *unit;
960 struct function_unit_op *op;
961 rtx unitsmask;
962 rtx readycost;
963 rtx newexp;
964 char *str;
966 /* Initially, cost and masks are zero. */
967 unitsmask = readycost = make_numeric_value (0);
969 /* Set up a conditional for costs and unit mask. */
970 newexp = rtx_alloc (IF_THEN_ELSE);
971 XEXP (newexp, 2) = make_numeric_value (0);
973 /* For each unit, insert its contribution to the above three values. */
974 for (unit = units; unit; unit = unit->next)
976 /* An expression that computes the ready cost for this unit. */
977 rtx readyexp = rtx_alloc (COND);
978 /* An expression that maps insns to operation number for conflicts. */
979 rtx caseexp = rtx_alloc (COND);
981 XVEC (readyexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
982 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
984 for (op = unit->ops; op; op = op->next)
986 str = (char *) xmalloc (strlen (unit->name) + 11);
988 /* Validate the expressions we were given for the conditions
989 and busy cost. Then make an attribute for use in the conflict
990 function. */
991 op->condexp = check_attr_test (op->condexp);
992 check_attr_value (op->busyexp, 0);
993 sprintf (str, "*%s_case_%d", unit->name, op->num);
994 make_internal_attr (str, make_canonical (0, op->busyexp));
996 /* Make our adjustment to the two COND's being computed. If we are
997 the last operation class, place our values into the default of
998 the COND. */
999 if (op->num == unit->num_opclasses - 1)
1001 XEXP (readyexp, 1) = make_numeric_value (op->ready);
1002 XEXP (caseexp, 1) = make_numeric_value (op->num);
1004 else
1006 XVECEXP (readyexp, 0, op->num * 2) = op->condexp;
1007 XVECEXP (readyexp, 0, op->num * 2 + 1)
1008 = make_numeric_value (op->ready);
1009 XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
1010 XVECEXP (caseexp, 0, op->num * 2 + 1)
1011 = make_numeric_value (op->num);
1015 /* Make an attribute for the case number and ready delay. */
1016 str = (char *) xmalloc (strlen (unit->name) + 8);
1017 sprintf (str, "*%s_cases", unit->name);
1018 make_internal_attr (str, caseexp, 1);
1020 str = (char *) xmalloc (strlen (unit->name) + 20);
1021 sprintf (str, "*%s_unit_ready_cost", unit->name);
1022 make_internal_attr (str, readyexp, 0);
1024 /* Merge this function unit into the ready cost and unit mask
1025 attributes. */
1026 XEXP (newexp, 0) = check_attr_test (unit->condexp);
1027 XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
1028 unitsmask = operate_exp (OR_OP, unitsmask, newexp);
1030 XEXP (newexp, 1) = readyexp;
1031 readycost = operate_exp (MAX_OP, readycost, newexp);
1034 make_internal_attr ("*function_units_used", unitsmask, 0);
1035 make_internal_attr ("*result_ready_cost", readycost, 0);
1038 /* Once all attributes and insns have been read and checked, we construct for
1039 each attribute value a list of all the insns that have that value for
1040 the attribute. */
1042 static void
1043 fill_attr (attr)
1044 struct attr_desc *attr;
1046 struct attr_value *av;
1047 struct insn_ent *ie;
1048 struct insn_def *id;
1049 int i;
1050 rtx value;
1052 for (id = defs; id; id = id->next)
1054 /* If no value is specified for this insn for this attribute, use the
1055 default. */
1056 value = NULL;
1057 if (XVEC (id->def, id->vec_idx))
1058 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
1059 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0),
1060 attr->name))
1061 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
1063 if (value == NULL)
1064 av = attr->default_val;
1065 else
1066 av = get_attr_value (value, attr, id->insn_code);
1068 ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1069 ie->insn_code = id->insn_code;
1070 ie->insn_index = id->insn_code;
1071 insert_insn_ent (av, ie);
1075 /* Given an expression EXP, see if it is a COND that has a test that checks
1076 relative positions of insns (uses MATCH_DUP or PC). If so, replace it
1077 with what is obtained by passing the expression to ADDRESS_FN. If not
1078 but it is a COND, call this routine recursively on each value (including
1079 the default value). Otherwise, return the value returned by NO_ADDRESS_FN
1080 applied to EXP. */
1082 static rtx
1083 substitute_address (exp, no_address_fn, address_fn)
1084 rtx exp;
1085 rtx (*no_address_fn) ();
1086 rtx (*address_fn) ();
1088 int i;
1089 rtx newexp;
1091 if (GET_CODE (exp) != COND)
1092 return (*no_address_fn) (exp);
1094 /* See if any tests use addresses. */
1095 address_used = 0;
1096 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1097 walk_attr_value (XVECEXP (exp, 0, i));
1099 if (address_used)
1100 return (*address_fn) (exp);
1102 /* Make a new copy of this COND, replacing each element. */
1103 newexp = rtx_alloc (COND);
1104 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1105 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1107 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
1108 XVECEXP (newexp, 0, i + 1) = substitute_address (XVECEXP (exp, 0, i + 1),
1109 no_address_fn,
1110 address_fn);
1113 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
1114 no_address_fn, address_fn);
1116 return newexp;
1119 /* Make new attributes from the `length' attribute. The following are made,
1120 each corresponding to a function called from `shorten_branches' or
1121 `get_attr_length':
1123 *insn_default_length This is the length of the insn to be returned
1124 by `get_attr_length' before `shorten_branches'
1125 has been called. In each case where the length
1126 depends on relative addresses, the largest
1127 possible is used. This routine is also used
1128 to compute the initial size of the insn.
1130 *insn_variable_length_p This returns 1 if the insn's length depends
1131 on relative addresses, zero otherwise.
1133 *insn_current_length This is only called when it is known that the
1134 insn has a variable length and returns the
1135 current length, based on relative addresses.
1138 static void
1139 make_length_attrs ()
1141 static char *new_names[] = {"*insn_default_length",
1142 "*insn_variable_length_p",
1143 "*insn_current_length"};
1144 static rtx (*no_address_fn[]) () = {identity_fn, zero_fn, zero_fn};
1145 static rtx (*address_fn[]) () = {max_fn, one_fn, identity_fn};
1146 int i;
1147 struct attr_desc *length_attr, *new_attr;
1148 struct attr_value *av, *new_av;
1149 struct insn_ent *ie, *new_ie;
1151 /* See if length attribute is defined. If so, it must be numeric. Make
1152 it special so we don't output anything for it. */
1153 length_attr = find_attr ("length", 0);
1154 if (length_attr == 0)
1155 return;
1157 if (! length_attr->is_numeric)
1158 fatal ("length attribute must be numeric.");
1160 length_attr->is_special = 1;
1162 /* Make each new attribute, in turn. */
1163 for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
1165 make_internal_attr (new_names[i],
1166 substitute_address (length_attr->default_val->value,
1167 no_address_fn[i], address_fn[i]),
1169 new_attr = find_attr (new_names[i], 0);
1170 for (av = length_attr->first_value; av; av = av->next)
1171 for (ie = av->first_insn; ie; ie = ie->next)
1173 new_av = get_attr_value (substitute_address (av->value,
1174 no_address_fn[i],
1175 address_fn[i]),
1176 new_attr, ie->insn_code);
1177 new_ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
1178 new_ie->insn_code = ie->insn_code;
1179 new_ie->insn_index = ie->insn_index;
1180 insert_insn_ent (new_av, new_ie);
1185 /* Utility functions called from above routine. */
1187 static rtx
1188 identity_fn (exp)
1189 rtx exp;
1191 return exp;
1194 static rtx
1195 zero_fn (exp)
1196 rtx exp;
1198 return make_numeric_value (0);
1201 static rtx
1202 one_fn (exp)
1203 rtx exp;
1205 return make_numeric_value (1);
1208 static rtx
1209 max_fn (exp)
1210 rtx exp;
1212 return make_numeric_value (max_attr_value (exp));
1215 /* Take a COND expression and see if any of the conditions in it can be
1216 simplified. If any are known true or known false for the particular insn
1217 code, the COND can be further simplified.
1219 Also call ourselves on any COND operations that are values of this COND.
1221 We only do the first replacement found directly and call ourselves
1222 recursively for subsequent replacements. */
1224 static rtx
1225 simplify_cond (exp, insn_code, insn_index)
1226 rtx exp;
1227 int insn_code, insn_index;
1229 int i, j;
1230 rtx newtest;
1231 rtx value;
1232 rtx newexp = exp;
1234 for (i = 0; i < XVECLEN (exp, 0); i += 2)
1236 newtest = SIMPLIFY_TEST_EXP (XVECEXP (exp, 0, i), insn_code, insn_index);
1237 if (newtest == true_rtx)
1239 /* Make a new COND with any previous conditions and the value for
1240 this pair as the default value. */
1241 newexp = rtx_alloc (COND);
1242 XVEC (newexp, 0) = rtvec_alloc (i);
1243 for (j = 0; j < i; j++)
1244 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1246 XEXP (newexp, 1) = XVECEXP (exp, 0, i + 1);
1247 break;
1250 else if (newtest == false_rtx)
1252 /* Build a new COND without this test. */
1253 newexp = rtx_alloc (COND);
1254 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1255 for (j = 0; j < i; j++)
1256 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1258 for (j = i; j < XVECLEN (newexp, 0); j++)
1259 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
1261 XEXP (newexp, 1) = XEXP (exp, 1);
1262 break;
1265 else if (newtest != XVECEXP (exp, 0, i))
1267 newexp = rtx_alloc (COND);
1268 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1269 for (j = 0; j < XVECLEN (exp, 0); j++)
1270 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1271 XEXP (newexp, 1) = XEXP (exp, 1);
1273 XVECEXP (newexp, 0, i) = newtest;
1274 break;
1277 /* See if this value may need simplification. */
1278 if (GET_CODE (XVECEXP (exp, 0, i + 1)) == COND)
1280 value = simplify_cond (XVECEXP (exp, 0, i + 1),
1281 insn_code, insn_index);
1282 if (value != XVECEXP (exp, 0, i + 1))
1284 newexp = rtx_alloc (COND);
1285 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1286 for (j = 0; j < XVECLEN (exp, 0); j++)
1287 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1288 XEXP (newexp, 1) = XEXP (exp, 1);
1290 XVECEXP (newexp, 0, i + 1) = value;
1291 break;
1295 /* If this is the last condition in a COND and our value is the same
1296 as the default value, our test isn't needed. */
1297 if (i == XVECLEN (exp, 0) - 2
1298 && rtx_equal_p (XVECEXP (exp, 0, i + 1), XEXP (exp, 1)))
1300 newexp = rtx_alloc (COND);
1301 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1302 for (j = 0; j < i; j++)
1303 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1304 XEXP (newexp, 1) = XEXP (exp, 1);
1305 break;
1308 /* If this value and the value for the next test are the same, merge the
1309 tests. */
1310 else if (i != XVECLEN (exp, 0) - 2
1311 && rtx_equal_p (XVECEXP (exp, 0, i + 1),
1312 XVECEXP (exp, 0, i + 3)))
1314 newexp = rtx_alloc (COND);
1315 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
1316 for (j = 0; j < i; j++)
1317 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1319 XVECEXP (newexp, 0, j)
1320 = insert_right_side (IOR, XVECEXP (exp, 0, i),
1321 XVECEXP (exp, 0, i + 2),
1322 insn_code, insn_index);
1323 XVECEXP (newexp, 0, j + 1) = XVECEXP (exp, 0, i + 1);
1325 for (j = i + 2; j < XVECLEN (newexp, 0); j++)
1326 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
1328 XEXP (newexp, 1) = XEXP (exp, 1);
1329 break;
1333 /* See if default value needs simplification. */
1334 if (GET_CODE (XEXP (exp, 1)) == COND)
1336 value = simplify_cond (XEXP (exp, 1), insn_code, insn_index);
1337 if (value != XEXP (exp, 1))
1339 newexp = rtx_alloc (COND);
1340 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
1341 for (j = 0; j < XVECLEN (exp, 0); j++)
1342 XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
1343 XEXP (newexp, 1) = value;
1347 if (exp == newexp)
1348 return exp;
1349 else if (XVECLEN (newexp, 0) == 1)
1350 return XVECEXP (newexp, 0, 0);
1351 else
1352 return simplify_cond (newexp, insn_code, insn_index);
1355 /* Remove an insn entry from an attribute value. */
1357 static void
1358 remove_insn_ent (av, ie)
1359 struct attr_value *av;
1360 struct insn_ent *ie;
1362 struct insn_ent *previe;
1364 if (av->first_insn == ie)
1365 av->first_insn = ie->next;
1366 else
1368 for (previe = av->first_insn; previe->next != ie; previe = previe->next)
1370 previe->next = ie->next;
1373 av->num_insns--;
1374 if (ie->insn_code == -1)
1375 av->has_asm_insn = 0;
1378 /* Insert an insn entry in an attribute value list. */
1380 static void
1381 insert_insn_ent (av, ie)
1382 struct attr_value *av;
1383 struct insn_ent *ie;
1385 ie->next = av->first_insn;
1386 av->first_insn = ie;
1387 av->num_insns++;
1388 if (ie->insn_code == -1)
1389 av->has_asm_insn = 1;
1392 /* This is a utility routine to take an expression that is a tree of either
1393 AND or IOR expressions and insert a new term. The new term will be
1394 inserted at the right side of the first node whose code does not match
1395 the root. A new node will be created with the root's code. Its left
1396 side will be the old right side and its right side will be the new
1397 term.
1399 If the `term' is itself a tree, all its leaves will be inserted. */
1401 static rtx
1402 insert_right_side (code, exp, term, insn_code, insn_index)
1403 RTX_CODE code;
1404 rtx exp;
1405 rtx term;
1406 int insn_code, insn_index;
1408 rtx newexp;
1410 if (GET_CODE (term) == code)
1412 exp = insert_right_side (code, exp, XEXP (term, 0),
1413 insn_code, insn_index);
1414 exp = insert_right_side (code, exp, XEXP (term, 1),
1415 insn_code, insn_index);
1417 return exp;
1420 if (GET_CODE (exp) == code)
1422 /* Make a copy of this expression and call recursively. */
1423 newexp = rtx_alloc (code);
1424 XEXP (newexp, 0) = XEXP (exp, 0);
1425 XEXP (newexp, 1) = insert_right_side (code, XEXP (exp, 1),
1426 term, insn_code, insn_index);
1428 else
1430 /* Insert the new term. */
1431 newexp = rtx_alloc (code);
1432 XEXP (newexp, 0) = exp;
1433 XEXP (newexp, 1) = term;
1436 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1439 /* If we have an expression which AND's a bunch of
1440 (not (eq_attrq "alternative" "n"))
1441 terms, we may have covered all or all but one of the possible alternatives.
1442 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1444 This routine is passed an expression and either AND or IOR. It returns a
1445 bitmask indicating which alternatives are present. */
1447 static int
1448 compute_alternative_mask (exp, code)
1449 rtx exp;
1450 RTX_CODE code;
1452 if (GET_CODE (exp) == code)
1453 return compute_alternative_mask (XEXP (exp, 0), code)
1454 | compute_alternative_mask (XEXP (exp, 1), code);
1456 else if (code == AND && GET_CODE (exp) == NOT
1457 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1458 && XSTR (XEXP (exp, 0), 0) == alternative_name)
1459 return 1 << atoi (XSTR (XEXP (exp, 0), 1));
1461 else if (code == IOR && GET_CODE (exp) == EQ_ATTR
1462 && XSTR (exp, 0) == alternative_name)
1463 return 1 << atoi (XSTR (exp, 1));
1465 else
1466 return 0;
1469 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1470 attribute with the value represented by that bit. */
1472 static rtx
1473 make_alternative_compare (mask)
1474 int mask;
1476 rtx newexp;
1477 int i;
1478 char *alternative;
1480 /* Find the bit. */
1481 for (i = 0; (mask & (1 << i)) == 0; i++)
1484 alternative = (char *) xmalloc (3);
1485 sprintf (alternative, "%d", i);
1487 newexp = rtx_alloc (EQ_ATTR);
1488 XSTR (newexp, 0) = alternative_name;
1489 XSTR (newexp, 1) = alternative;
1490 RTX_UNCHANGING_P (newexp) = 1;
1492 return newexp;
1495 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1496 of "attr" for this insn code. From that value, we can compute a test
1497 showing when the EQ_ATTR will be true. This routine performs that
1498 computation. If a test condition involves an address, we leave the EQ_ATTR
1499 intact because addresses are only valid for the `length' attribute. */
1501 static rtx
1502 evaluate_eq_attr (exp, value, insn_code, insn_index)
1503 rtx exp;
1504 rtx value;
1505 int insn_code, insn_index;
1507 rtx orexp, andexp;
1508 rtx right;
1509 rtx newexp;
1510 int i;
1512 if (GET_CODE (value) == CONST_STRING)
1514 if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
1515 newexp = true_rtx;
1516 else
1517 newexp = false_rtx;
1519 else if (GET_CODE (value) == COND)
1521 /* We construct an IOR of all the cases for which the requested attribute
1522 value is present. Since we start with FALSE, if it is not present,
1523 FALSE will be returned.
1525 Each case is the AND of the NOT's of the previous conditions with the
1526 current condition; in the default case the current condition is TRUE.
1528 For each possible COND value, call ourselves recursively.
1530 The extra TRUE and FALSE expressions will be eliminated by another
1531 call to the simplification routine. */
1533 orexp = false_rtx;
1534 andexp = true_rtx;
1536 for (i = 0; i < XVECLEN (value, 0); i += 2)
1538 right = insert_right_side (AND, andexp,
1539 XVECEXP (value, 0, i),
1540 insn_code, insn_index);
1541 right = insert_right_side (AND, right,
1542 evaluate_eq_attr (exp, XVECEXP (value, 0, i + 1),
1543 insn_code, insn_index),
1544 insn_code, insn_index);
1545 orexp = insert_right_side (IOR, orexp, right,
1546 insn_code, insn_index);
1548 /* Add this condition into the AND expression. */
1549 newexp = rtx_alloc (NOT);
1550 XEXP (newexp, 0) = XVECEXP (value, 0, i);
1551 andexp = insert_right_side (AND, andexp, newexp,
1552 insn_code, insn_index);
1555 /* Handle the default case. */
1556 right = insert_right_side (AND, andexp,
1557 evaluate_eq_attr (exp, XEXP (value, 1),
1558 insn_code, insn_index),
1559 insn_code, insn_index);
1560 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
1562 else
1563 abort ();
1565 /* If uses an address, must return original expression. */
1567 address_used = 0;
1568 walk_attr_value (newexp);
1570 if (address_used)
1571 return exp;
1572 else
1573 return newexp;
1576 /* This routine is called when an AND of a term with a tree of AND's is
1577 encountered. If the term or its complement is present in the tree, it
1578 can be replaced with TRUE or FALSE, respectively.
1580 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
1581 be true and hence are complementary.
1583 There is one special case: If we see
1584 (and (not (eq_attr "att" "v1"))
1585 (eq_attr "att" "v2"))
1586 this can be replaced by (eq_attr "att" "v2"). To do this we need to
1587 replace the term, not anything in the AND tree. So we pass a pointer to
1588 the term. */
1590 static rtx
1591 simplify_and_tree (exp, pterm, insn_code, insn_index)
1592 rtx exp;
1593 rtx *pterm;
1594 int insn_code, insn_index;
1596 rtx left, right;
1597 rtx newexp;
1598 rtx temp;
1599 int left_eliminates_term, right_eliminates_term;
1601 if (GET_CODE (exp) == AND)
1603 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
1604 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
1605 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1607 newexp = rtx_alloc (GET_CODE (exp));
1608 XEXP (newexp, 0) = left;
1609 XEXP (newexp, 1) = right;
1611 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1615 else if (GET_CODE (exp) == IOR)
1617 /* For the IOR case, we do the same as above, except that we can
1618 only eliminate `term' if both sides of the IOR would do so. */
1619 temp = *pterm;
1620 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
1621 left_eliminates_term = (temp == true_rtx);
1623 temp = *pterm;
1624 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
1625 right_eliminates_term = (temp == true_rtx);
1627 if (left_eliminates_term && right_eliminates_term)
1628 *pterm = true_rtx;
1630 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1632 newexp = rtx_alloc (GET_CODE (exp));
1633 XEXP (newexp, 0) = left;
1634 XEXP (newexp, 1) = right;
1636 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1640 /* Check for simplifications. Do some extra checking here since this
1641 routine is called so many times. */
1643 if (exp == *pterm)
1644 return true_rtx;
1646 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
1647 return false_rtx;
1649 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
1650 return false_rtx;
1652 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
1654 if (XSTR (exp, 0) != XSTR (*pterm, 0))
1655 return exp;
1657 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
1658 return true_rtx;
1659 else
1660 return false_rtx;
1663 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
1664 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
1666 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
1667 return exp;
1669 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
1670 return false_rtx;
1671 else
1672 return true_rtx;
1675 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
1676 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
1678 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
1679 return exp;
1681 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
1682 return false_rtx;
1683 else
1684 *pterm = true_rtx;
1687 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
1689 if (rtx_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
1690 return true_rtx;
1693 else if (GET_CODE (exp) == NOT)
1695 if (rtx_equal_p (XEXP (exp, 0), *pterm))
1696 return false_rtx;
1699 else if (GET_CODE (*pterm) == NOT)
1701 if (rtx_equal_p (XEXP (*pterm, 0), exp))
1702 return false_rtx;
1705 else if (rtx_equal_p (exp, *pterm))
1706 return true_rtx;
1708 return exp;
1711 /* Similiar to `simplify_and_tree', but for IOR trees. */
1713 static rtx
1714 simplify_or_tree (exp, pterm, insn_code, insn_index)
1715 rtx exp;
1716 rtx *pterm;
1717 int insn_code, insn_index;
1719 rtx left, right;
1720 rtx newexp;
1721 rtx temp;
1722 int left_eliminates_term, right_eliminates_term;
1724 if (GET_CODE (exp) == IOR)
1726 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index);
1727 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
1728 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1730 newexp = rtx_alloc (GET_CODE (exp));
1731 XEXP (newexp, 0) = left;
1732 XEXP (newexp, 1) = right;
1734 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1738 else if (GET_CODE (exp) == AND)
1740 /* For the AND case, we do the same as above, except that we can
1741 only eliminate `term' if both sides of the AND would do so. */
1742 temp = *pterm;
1743 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index);
1744 left_eliminates_term = (temp == false_rtx);
1746 temp = *pterm;
1747 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
1748 right_eliminates_term = (temp == false_rtx);
1750 if (left_eliminates_term && right_eliminates_term)
1751 *pterm = false_rtx;
1753 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1755 newexp = rtx_alloc (GET_CODE (exp));
1756 XEXP (newexp, 0) = left;
1757 XEXP (newexp, 1) = right;
1759 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1763 if (rtx_equal_p (exp, *pterm))
1764 return false_rtx;
1766 else if (GET_CODE (exp) == NOT && rtx_equal_p (XEXP (exp, 0), *pterm))
1767 return true_rtx;
1769 else if (GET_CODE (*pterm) == NOT && rtx_equal_p (XEXP (*pterm, 0), exp))
1770 return true_rtx;
1772 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
1773 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
1774 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
1775 *pterm = false_rtx;
1777 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
1778 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
1779 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
1780 return false_rtx;
1782 return exp;
1785 /* Given an expression, see if it can be simplified for a particular insn
1786 code based on the values of other attributes being tested. This can
1787 eliminate nested get_attr_... calls.
1789 Note that if an endless recursion is specified in the patterns, the
1790 optimization will loop. However, it will do so in precisely the cases where
1791 an infinite recursion loop could occur during compilation. It's better that
1792 it occurs here! */
1794 static rtx
1795 simplify_test_exp (exp, insn_code, insn_index)
1796 rtx exp;
1797 int insn_code, insn_index;
1799 rtx left, right;
1800 struct attr_desc *attr;
1801 struct attr_value *av;
1802 struct insn_ent *ie;
1803 int i;
1804 rtx newexp = exp;
1806 switch (GET_CODE (exp))
1808 case AND:
1809 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
1810 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
1812 /* If either side is an IOR and we have (eq_attr "alternative" ..")
1813 present on both sides, apply the distributive law since this will
1814 yield simplications. */
1815 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
1816 && compute_alternative_mask (left, IOR)
1817 && compute_alternative_mask (right, IOR))
1819 if (GET_CODE (left) == IOR)
1821 rtx tem = left;
1822 left = right;
1823 right = tem;
1826 newexp = rtx_alloc (IOR);
1827 XEXP (newexp, 0) = rtx_alloc (AND);
1828 XEXP (newexp, 1) = rtx_alloc (AND);
1829 XEXP (XEXP (newexp, 0), 0) = XEXP (XEXP (newexp, 1), 0) = left;
1830 XEXP (XEXP (newexp, 0), 1) = XEXP (right, 0);
1831 XEXP (XEXP (newexp, 1), 1) = XEXP (right, 1);
1833 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1836 /* Try with the term on both sides. */
1837 right = simplify_and_tree (right, &left, insn_code, insn_index);
1838 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
1839 left = simplify_and_tree (left, &right, insn_code, insn_index);
1841 if (left == false_rtx || right == false_rtx)
1842 return false_rtx;
1843 else if (left == true_rtx)
1844 return right;
1845 else if (right == true_rtx)
1846 return left;
1848 /* See if all or all but one of the insn's alternatives are specified
1849 in this tree. Optimize if so. */
1851 else if (insn_code >= 0
1852 && (GET_CODE (left) == AND
1853 || (GET_CODE (left) == NOT
1854 && GET_CODE (XEXP (left, 0)) == EQ_ATTR
1855 && XSTR (XEXP (left, 0), 0) == alternative_name)
1856 || GET_CODE (right) == AND
1857 || (GET_CODE (right) == NOT
1858 && GET_CODE (XEXP (right, 0)) == EQ_ATTR
1859 && XSTR (XEXP (right, 0), 0) == alternative_name)))
1861 i = compute_alternative_mask (exp, AND);
1862 if (i & ~insn_alternatives[insn_code])
1863 fatal ("Illegal alternative specified for pattern number %d",
1864 insn_index);
1866 /* If all alternatives are excluded, this is false. */
1867 i ^= insn_alternatives[insn_code];
1868 if (i == 0)
1869 return false_rtx;
1870 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
1872 /* If just one excluded, AND a comparison with that one to the
1873 front of the tree. The others will be eliminated by
1874 optimization. We do not want to do this if the insn has one
1875 alternative and we have tested none of them! */
1876 left = make_alternative_compare (i);
1877 right = simplify_and_tree (exp, &left, insn_code, insn_index);
1878 newexp = rtx_alloc (AND);
1879 XEXP (newexp, 0) = left;
1880 XEXP (newexp, 1) = right;
1882 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1886 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1888 newexp = rtx_alloc (AND);
1889 XEXP (newexp, 0) = left;
1890 XEXP (newexp, 1) = right;
1891 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1893 break;
1895 case IOR:
1896 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
1897 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
1899 right = simplify_or_tree (right, &left, insn_code, insn_index);
1900 if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
1901 left = simplify_or_tree (left, &right, insn_code, insn_index);
1903 if (right == true_rtx || left == true_rtx)
1904 return true_rtx;
1905 else if (left == false_rtx)
1906 return right;
1907 else if (right == false_rtx)
1908 return left;
1910 /* Test for simple cases where the distributive law is useful. I.e.,
1911 convert (ior (and (x) (y))
1912 (and (x) (z)))
1913 to (and (x)
1914 (ior (y) (z)))
1917 else if (GET_CODE (left) == AND && GET_CODE (right) == AND
1918 && rtx_equal_p (XEXP (left, 0), XEXP (right, 0)))
1920 newexp = rtx_alloc (IOR);
1921 XEXP (newexp, 0) = XEXP (left, 1);
1922 XEXP (newexp, 1) = XEXP (right, 1);
1924 left = XEXP (left, 0);
1925 right = newexp;
1926 newexp = rtx_alloc (AND);
1927 XEXP (newexp, 0) = left;
1928 XEXP (newexp, 1) = right;
1929 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1932 /* See if all or all but one of the insn's alternatives are specified
1933 in this tree. Optimize if so. */
1935 else if (insn_code >= 0
1936 && (GET_CODE (left) == IOR
1937 || (GET_CODE (left) == EQ_ATTR
1938 && XSTR (left, 0) == alternative_name)
1939 || GET_CODE (right) == IOR
1940 || (GET_CODE (right) == EQ_ATTR
1941 && XSTR (right, 0) == alternative_name)))
1943 i = compute_alternative_mask (exp, IOR);
1944 if (i & ~insn_alternatives[insn_code])
1945 fatal ("Illegal alternative specified for pattern number %d",
1946 insn_index);
1948 /* If all alternatives are included, this is true. */
1949 i ^= insn_alternatives[insn_code];
1950 if (i == 0)
1951 return true_rtx;
1952 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
1954 /* If just one excluded, IOR a comparison with that one to the
1955 front of the tree. The others will be eliminated by
1956 optimization. We do not want to do this if the insn has one
1957 alternative and we have tested none of them! */
1958 left = make_alternative_compare (i);
1959 right = simplify_and_tree (exp, &left, insn_code, insn_index);
1960 newexp = rtx_alloc (IOR);
1961 XEXP (newexp, 0) = rtx_alloc (NOT);
1962 XEXP (XEXP (newexp, 0), 0) = left;
1963 XEXP (newexp, 1) = right;
1965 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1969 if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
1971 newexp = rtx_alloc (IOR);
1972 XEXP (newexp, 0) = left;
1973 XEXP (newexp, 1) = right;
1974 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1976 break;
1978 case NOT:
1979 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
1980 if (GET_CODE (left) == NOT)
1981 return XEXP (left, 0);
1983 if (left == false_rtx)
1984 return true_rtx;
1985 else if (left == true_rtx)
1986 return false_rtx;
1988 /* Try to apply De`Morgan's laws. */
1989 else if (GET_CODE (left) == IOR)
1991 newexp = rtx_alloc (AND);
1992 XEXP (newexp, 0) = rtx_alloc (NOT);
1993 XEXP (XEXP (newexp, 0), 0) = XEXP (left, 0);
1994 XEXP (newexp, 1) = rtx_alloc (NOT);
1995 XEXP (XEXP (newexp, 1), 0) = XEXP (left, 1);
1997 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
1999 else if (GET_CODE (left) == AND)
2001 newexp = rtx_alloc (IOR);
2002 XEXP (newexp, 0) = rtx_alloc (NOT);
2003 XEXP (XEXP (newexp, 0), 0) = XEXP (left, 0);
2004 XEXP (newexp, 1) = rtx_alloc (NOT);
2005 XEXP (XEXP (newexp, 1), 0) = XEXP (left, 1);
2007 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
2009 else if (left != XEXP (exp, 0))
2011 newexp = rtx_alloc (NOT);
2012 XEXP (newexp, 0) = left;
2014 break;
2016 case EQ_ATTR:
2017 /* Look at the value for this insn code in the specified attribute.
2018 We normally can replace this comparison with the condition that
2019 would give this insn the values being tested for. */
2020 if (XSTR (exp, 0) != alternative_name
2021 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
2022 for (av = attr->first_value; av; av = av->next)
2023 for (ie = av->first_insn; ie; ie = ie->next)
2024 if (ie->insn_code == insn_code)
2025 return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
2028 /* We have already simplified this expression. Simplifying it again
2029 won't buy anything unless we weren't given a valid insn code
2030 to process (i.e., we are canonicalizing something.). */
2031 if (insn_code != -2)
2032 RTX_UNCHANGING_P (newexp) = 1;
2034 return newexp;
2037 /* Optimize the attribute lists by seeing if we can determine conditional
2038 values from the known values of other attributes. This will save subroutine
2039 calls during the compilation. */
2041 static void
2042 optimize_attrs ()
2044 struct attr_desc *attr;
2045 struct attr_value *av;
2046 struct insn_ent *ie, *nextie;
2047 rtx newexp;
2048 int something_changed = 1;
2050 /* Loop until nothing changes for one iteration. */
2051 while (something_changed)
2053 something_changed = 0;
2054 for (attr = attrs; attr; attr = attr->next)
2055 for (av = attr->first_value; av; av = av->next)
2056 for (ie = av->first_insn; ie; ie = nextie)
2058 nextie = ie->next;
2059 if (GET_CODE (av->value) != COND)
2060 continue;
2062 newexp = simplify_cond (av->value, ie->insn_code,
2063 ie->insn_index);
2064 if (newexp != av->value)
2066 remove_insn_ent (av, ie);
2067 insert_insn_ent (get_attr_value (newexp, attr,
2068 ie->insn_code), ie);
2069 something_changed = 1;
2075 /* Create table entries for DEFINE_ATTR. */
2077 static void
2078 gen_attr (exp)
2079 rtx exp;
2081 struct attr_desc *attr;
2082 struct attr_value *av;
2083 char *name_ptr;
2084 char *p;
2086 /* Make a new attribute structure. Check for duplicate by looking at
2087 attr->default_val, since it is initialized by this routine. */
2088 attr = find_attr (XSTR (exp, 0), 1);
2089 if (attr->default_val)
2090 fatal ("Duplicate definition for `%s' attribute", attr->name);
2092 if (*XSTR (exp, 1) == '\0')
2093 attr->is_numeric = 1;
2094 else
2096 name_ptr = XSTR (exp, 1);
2097 while ((p = next_comma_elt (&name_ptr)) != NULL)
2099 av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
2100 av->value = rtx_alloc (CONST_STRING);
2101 XSTR (av->value, 0) = p;
2102 av->next = attr->first_value;
2103 attr->first_value = av;
2104 av->first_insn = NULL;
2105 av->num_insns = 0;
2106 av->has_asm_insn = 0;
2110 if (! strcmp (attr->name, "length") && ! attr->is_numeric)
2111 fatal ("`length' attribute must take numeric values");
2113 /* Set up the default value. */
2114 check_attr_value (XEXP (exp, 2), attr);
2115 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
2118 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2119 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2120 number of alternatives as this should be checked elsewhere. */
2122 static int
2123 count_alternatives (exp)
2124 rtx exp;
2126 int i, j, n;
2127 char *fmt;
2129 if (GET_CODE (exp) == MATCH_OPERAND)
2130 return n_comma_elts (XSTR (exp, 2));
2132 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2133 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2134 switch (*fmt++)
2136 case 'e':
2137 case 'u':
2138 n = count_alternatives (XEXP (exp, i));
2139 if (n)
2140 return n;
2141 break;
2143 case 'E':
2144 case 'V':
2145 if (XVEC (exp, i) != NULL)
2146 for (j = 0; j < XVECLEN (exp, i); j++)
2148 n = count_alternatives (XVECEXP (exp, i, j));
2149 if (n)
2150 return n;
2154 return 0;
2157 /* Returns non-zero if the given expression contains an EQ_ATTR with the
2158 `alternative' attribute. */
2160 static int
2161 compares_alternatives_p (exp)
2162 rtx exp;
2164 int i, j;
2165 char *fmt;
2167 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
2168 return 1;
2170 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2171 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2172 switch (*fmt++)
2174 case 'e':
2175 case 'u':
2176 if (compares_alternatives_p (XEXP (exp, i)))
2177 return 1;
2178 break;
2180 case 'E':
2181 for (j = 0; j < XVECLEN (exp, i); j++)
2182 if (compares_alternatives_p (XVECEXP (exp, i, j)))
2183 return 1;
2184 break;
2187 return 0;
2190 /* Returns non-zero is INNER is contained in EXP. */
2192 static int
2193 contained_in_p (inner, exp)
2194 rtx inner;
2195 rtx exp;
2197 int i, j;
2198 char *fmt;
2200 if (rtx_equal_p (inner, exp))
2201 return 1;
2203 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
2204 i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
2205 switch (*fmt++)
2207 case 'e':
2208 case 'u':
2209 if (contained_in_p (inner, XEXP (exp, i)))
2210 return 1;
2211 break;
2213 case 'E':
2214 for (j = 0; j < XVECLEN (exp, i); j++)
2215 if (contained_in_p (inner, XVECEXP (exp, i, j)))
2216 return 1;
2217 break;
2220 return 0;
2223 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
2225 static void
2226 gen_insn (exp)
2227 rtx exp;
2229 struct insn_def *id;
2231 id = (struct insn_def *) xmalloc (sizeof (struct insn_def));
2232 id->next = defs;
2233 defs = id;
2234 id->def = exp;
2236 switch (GET_CODE (exp))
2238 case DEFINE_INSN:
2239 id->insn_code = insn_code_number++;
2240 id->insn_index = insn_index_number++;
2241 id->num_alternatives = count_alternatives (exp);
2242 if (id->num_alternatives == 0)
2243 id->num_alternatives = 1;
2244 id->vec_idx = 4;
2245 break;
2247 case DEFINE_PEEPHOLE:
2248 id->insn_code = insn_code_number++;
2249 id->insn_index = insn_index_number++;
2250 id->num_alternatives = count_alternatives (exp);
2251 if (id->num_alternatives == 0)
2252 id->num_alternatives = 1;
2253 id->vec_idx = 3;
2254 break;
2256 case DEFINE_ASM_ATTRIBUTES:
2257 id->insn_code = -1;
2258 id->insn_index = -1;
2259 id->num_alternatives = 1;
2260 id->vec_idx = 0;
2261 got_define_asm_attributes = 1;
2262 break;
2266 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
2267 true or annul false is specified, and make a `struct delay_desc'. */
2269 static void
2270 gen_delay (def)
2271 rtx def;
2273 struct delay_desc *delay;
2274 int i;
2276 if (XVECLEN (def, 1) % 3 != 0)
2277 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
2279 for (i = 0; i < XVECLEN (def, 1); i += 3)
2281 if (XVECEXP (def, 1, i + 1))
2282 have_annul_true = 1;
2283 if (XVECEXP (def, 1, i + 2))
2284 have_annul_false = 1;
2287 delay = (struct delay_desc *) xmalloc (sizeof (struct delay_desc));
2288 delay->def = def;
2289 delay->num = ++num_delays;
2290 delay->next = delays;
2291 delays = delay;
2294 /* Process a DEFINE_FUNCTION_UNIT.
2296 This gives information about a function unit contained in the CPU.
2297 We fill in a `struct function_unit_op' and a `struct function_unit'
2298 with information used later by `expand_unit'. */
2300 static void
2301 gen_unit (def)
2302 rtx def;
2304 struct function_unit *unit;
2305 struct function_unit_op *op;
2307 /* See if we have already seen this function unit. If so, check that
2308 the multipicity and simultaneity values are the same. If not, make
2309 a structure for this function unit. */
2310 for (unit = units; unit; unit = unit->next)
2311 if (! strcmp (unit->name, XSTR (def, 0)))
2313 if (unit->multiplicity != XINT (def, 1)
2314 || unit->simultaneity != XINT (def, 2))
2315 fatal ("Differing specifications given for `%s' function unit.",
2316 unit->name);
2317 break;
2320 if (unit == 0)
2322 unit = (struct function_unit *) xmalloc (sizeof (struct function_unit));
2323 unit->name = XSTR (def, 0);
2324 unit->multiplicity = XINT (def, 1);
2325 unit->simultaneity = XINT (def, 2);
2326 unit->num = num_units++;
2327 unit->num_opclasses = 0;
2328 unit->condexp = false_rtx;
2329 unit->ops = 0;
2330 unit->next = units;
2331 units = unit;
2334 /* Make a new operation class structure entry and initialize it. */
2335 op = (struct function_unit_op *) xmalloc (sizeof (struct function_unit_op));
2336 op->condexp = XEXP (def, 3);
2337 op->num = unit->num_opclasses++;
2338 op->ready = XINT (def, 4);
2339 op->next = unit->ops;
2340 unit->ops = op;
2342 /* Set our busy expression based on whether or not an optional conflict
2343 vector was specified. */
2344 if (XVEC (def, 6))
2346 /* Compute the IOR of all the specified expressions. */
2347 rtx orexp = false_rtx;
2348 int i;
2350 for (i = 0; i < XVECLEN (def, 6); i++)
2351 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2);
2353 op->busyexp = rtx_alloc (IF_THEN_ELSE);
2354 XEXP (op->busyexp, 0) = orexp;
2355 XEXP (op->busyexp, 1) = make_numeric_value (XINT (def, 5));
2356 XEXP (op->busyexp, 2) = make_numeric_value (0);
2358 else
2359 op->busyexp = make_numeric_value (XINT (def, 5));
2361 /* Merge our conditional into that of the function unit so we can determine
2362 which insns are used by the function unit. */
2363 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2);
2366 /* Given a piece of RTX, print a C expression to test it's truth value.
2367 We use AND and IOR both for logical and bit-wise operations, so
2368 interpret them as logical unless they are inside a comparison expression.
2369 The second operand of this function will be non-zero in that case. */
2371 static void
2372 write_test_expr (exp, in_comparison)
2373 rtx exp;
2374 int in_comparison;
2376 int comparison_operator = 0;
2377 RTX_CODE code;
2378 struct attr_desc *attr;
2380 /* In order not to worry about operator precedence, surround our part of
2381 the expression with parentheses. */
2383 printf ("(");
2384 code = GET_CODE (exp);
2385 switch (code)
2387 /* Binary operators. */
2388 case EQ: case NE:
2389 case GE: case GT: case GEU: case GTU:
2390 case LE: case LT: case LEU: case LTU:
2391 comparison_operator = 1;
2393 case PLUS: case MINUS: case MULT: case DIV: case MOD:
2394 case AND: case IOR: case XOR:
2395 case LSHIFT: case ASHIFT: case LSHIFTRT: case ASHIFTRT:
2396 write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator);
2397 switch (code)
2399 case EQ:
2400 printf (" == ");
2401 break;
2402 case NE:
2403 printf (" != ");
2404 break;
2405 case GE:
2406 printf (" >= ");
2407 break;
2408 case GT:
2409 printf (" > ");
2410 break;
2411 case GEU:
2412 printf (" >= (unsigned) ");
2413 break;
2414 case GTU:
2415 printf (" > (unsigned) ");
2416 break;
2417 case LE:
2418 printf (" <= ");
2419 break;
2420 case LT:
2421 printf (" < ");
2422 break;
2423 case LEU:
2424 printf (" <= (unsigned) ");
2425 break;
2426 case LTU:
2427 printf (" < (unsigned) ");
2428 break;
2429 case PLUS:
2430 printf (" + ");
2431 break;
2432 case MINUS:
2433 printf (" - ");
2434 break;
2435 case MULT:
2436 printf (" * ");
2437 break;
2438 case DIV:
2439 printf (" / ");
2440 break;
2441 case MOD:
2442 printf (" % ");
2443 break;
2444 case AND:
2445 if (in_comparison)
2446 printf (" & ");
2447 else
2448 printf (" && ");
2449 break;
2450 case IOR:
2451 if (in_comparison)
2452 printf (" | ");
2453 else
2454 printf (" || ");
2455 break;
2456 case XOR:
2457 printf (" ^ ");
2458 break;
2459 case LSHIFT:
2460 case ASHIFT:
2461 printf (" << ");
2462 break;
2463 case LSHIFTRT:
2464 case ASHIFTRT:
2465 printf (" >> ");
2466 break;
2469 write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator);
2470 break;
2472 case NOT:
2473 /* Special-case (not (eq_attrq "alternative" "x")) */
2474 if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
2475 && XSTR (XEXP (exp, 0), 0) == alternative_name)
2477 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
2478 break;
2481 /* Otherwise, fall through to normal unary operator. */
2483 /* Unary operators. */
2484 case ABS: case NEG:
2485 switch (code)
2487 case NOT:
2488 if (in_comparison)
2489 printf ("~ ");
2490 else
2491 printf ("! ");
2492 break;
2493 case ABS:
2494 printf ("abs ");
2495 break;
2496 case NEG:
2497 printf ("-");
2498 break;
2501 write_test_expr (XEXP (exp, 0), in_comparison);
2502 break;
2504 /* Comparison test of an attribute with a value. Most of these will
2505 have been removed by optimization. Handle "alternative"
2506 specially and give error if EQ_ATTR present inside a comparison. */
2507 case EQ_ATTR:
2508 if (in_comparison)
2509 fatal ("EQ_ATTR not valid inside comparison");
2511 if (XSTR (exp, 0) == alternative_name)
2513 printf ("which_alternative == %s", XSTR (exp, 1));
2514 break;
2517 attr = find_attr (XSTR (exp, 0), 0);
2518 if (! attr) abort ();
2519 printf ("get_attr_%s (insn) == ", attr->name);
2520 write_attr_valueq (attr, XSTR (exp, 1));
2521 break;
2523 /* See if an operand matches a predicate. */
2524 case MATCH_OPERAND:
2525 /* If only a mode is given, just ensure the mode matches the operand.
2526 If neither a mode nor predicate is given, error. */
2527 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
2529 if (GET_MODE (exp) == VOIDmode)
2530 fatal ("Null MATCH_OPERAND specified as test");
2531 else
2532 printf ("GET_MODE (operands[%d]) == %smode",
2533 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
2535 else
2536 printf ("%s (operands[%d], %smode)",
2537 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
2538 break;
2540 /* Constant integer. */
2541 case CONST_INT:
2542 printf ("%d", XINT (exp, 0));
2543 break;
2545 /* A random C expression. */
2546 case SYMBOL_REF:
2547 printf ("%s", XSTR (exp, 0));
2548 break;
2550 /* The address of the branch target. */
2551 case MATCH_DUP:
2552 printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
2553 break;
2555 /* The address of the current insn. It would be more consistent with
2556 other usage to make this the address of the NEXT insn, but this gets
2557 too confusing because of the ambiguity regarding the length of the
2558 current insn. */
2559 case PC:
2560 printf ("insn_current_address");
2561 break;
2563 default:
2564 fatal ("bad RTX code `%s' in attribute calculation\n",
2565 GET_RTX_NAME (code));
2568 printf (")");
2571 /* Given an attribute value, return the maximum CONST_STRING argument
2572 encountered. It is assumed that they are all numeric. */
2574 static int
2575 max_attr_value (exp)
2576 rtx exp;
2578 int current_max = 0;
2579 int n;
2580 int i;
2582 if (GET_CODE (exp) == CONST_STRING)
2583 return atoi (XSTR (exp, 0));
2585 else if (GET_CODE (exp) == COND)
2587 for (i = 0; i < XVECLEN (exp, 0); i += 2)
2589 n = max_attr_value (XVECEXP (exp, 0, i + 1));
2590 if (n > current_max)
2591 current_max = n;
2594 n = max_attr_value (XEXP (exp, 1));
2595 if (n > current_max)
2596 current_max = n;
2599 else
2600 abort ();
2602 return current_max;
2605 /* Scan an attribute value, possibly a conditional, and record what actions
2606 will be required to do any conditional tests in it.
2608 Specifically, set
2609 `must_extract' if we need to extract the insn operands
2610 `must_constrain' if we must compute `which_alternative'
2611 `address_used' if an address expression was used
2614 static void
2615 walk_attr_value (exp)
2616 rtx exp;
2618 register int i, j;
2619 register char *fmt;
2620 RTX_CODE code;
2622 if (exp == NULL)
2623 return;
2625 code = GET_CODE (exp);
2626 switch (code)
2628 case SYMBOL_REF:
2629 /* Since this is an arbitrary expression, it can look at anything. */
2630 must_extract = must_constrain = 1;
2631 return;
2633 case MATCH_OPERAND:
2634 must_extract = 1;
2635 return;
2637 case EQ_ATTR:
2638 if (XSTR (exp, 0) == alternative_name)
2639 must_extract = must_constrain = 1;
2640 return;
2642 case MATCH_DUP:
2643 case PC:
2644 address_used = 1;
2645 return;
2648 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
2649 switch (*fmt++)
2651 case 'e':
2652 case 'u':
2653 walk_attr_value (XEXP (exp, i));
2654 break;
2656 case 'E':
2657 if (XVEC (exp, i) != NULL)
2658 for (j = 0; j < XVECLEN (exp, i); j++)
2659 walk_attr_value (XVECEXP (exp, i, j));
2660 break;
2664 /* Write out a function to obtain the attribute for a given INSN. */
2666 static void
2667 write_attr_get (attr)
2668 struct attr_desc *attr;
2670 struct attr_value *av, *common_av;
2672 /* Find the most used attribute value. Handle that as the `default' of the
2673 switch we will generate. */
2674 common_av = find_most_used (attr);
2676 /* Write out start of function, then all values with explicit `case' lines,
2677 then a `default', then the value with the most uses. */
2678 if (attr->is_numeric)
2679 printf ("int\n");
2680 else
2681 printf ("enum attr_%s\n", attr->name);
2683 /* If the attribute name starts with a star, the remainder is the name of
2684 the subroutine to use, instead of `get_attr_...'. */
2685 if (attr->name[0] == '*')
2686 printf ("%s (insn)\n", &attr->name[1]);
2687 else
2688 printf ("get_attr_%s (insn)\n", attr->name);
2689 printf (" rtx insn;\n");
2690 printf ("{\n");
2691 printf (" switch (recog_memoized (insn))\n");
2692 printf (" {\n");
2694 for (av = attr->first_value; av; av = av->next)
2695 if (av != common_av)
2696 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
2698 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
2699 printf (" }\n}\n\n");
2702 /* Given an AND tree of known true terms (because we are inside an `if' with
2703 that as the condition or are in an `else' clause) and an expression,
2704 replace any known true terms with TRUE. Use `simplify_and_tree' to do
2705 the bulk of the work. */
2707 static rtx
2708 eliminate_known_true (known_true, exp, insn_code, insn_index)
2709 rtx known_true;
2710 rtx exp;
2711 int insn_code, insn_index;
2713 rtx term;
2715 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
2717 if (GET_CODE (known_true) == AND)
2719 exp = eliminate_known_true (XEXP (known_true, 0), exp,
2720 insn_code, insn_index);
2721 exp = eliminate_known_true (XEXP (known_true, 1), exp,
2722 insn_code, insn_index);
2724 else
2726 term = known_true;
2727 exp = simplify_and_tree (exp, &term, insn_code, insn_index);
2730 return exp;
2733 /* Write out a series of tests and assignment statements to perform tests and
2734 sets of an attribute value. We are passed an indentation amount and prefix
2735 and suffix strings to write around each attribute value (e.g., "return"
2736 and ";"). */
2738 static void
2739 write_attr_set (attr, indent, value, prefix, suffix, known_true,
2740 insn_code, insn_index)
2741 struct attr_desc *attr;
2742 int indent;
2743 rtx value;
2744 char *prefix;
2745 char *suffix;
2746 rtx known_true;
2747 int insn_code, insn_index;
2749 if (GET_CODE (value) == CONST_STRING)
2751 write_indent (indent);
2752 printf ("%s ", prefix);
2753 write_attr_value (attr, value);
2754 printf ("%s\n", suffix);
2756 else if (GET_CODE (value) == COND)
2758 /* Assume the default value will be the default of the COND unless we
2759 find an always true expression. */
2760 rtx default_val = XEXP (value, 1);
2761 rtx our_known_true = known_true;
2762 rtx newexp;
2763 int first_if = 1;
2764 int i;
2766 for (i = 0; i < XVECLEN (value, 0); i += 2)
2768 rtx testexp;
2769 rtx inner_true;
2771 testexp = eliminate_known_true (our_known_true,
2772 XVECEXP (value, 0, i),
2773 insn_code, insn_index);
2774 newexp = rtx_alloc (NOT);
2775 XEXP (newexp, 0) = testexp;
2776 newexp = insert_right_side (AND, our_known_true, newexp,
2777 insn_code, insn_index);
2779 /* If the test expression is always true or if the next `known_true'
2780 expression is always false, this is the last case, so break
2781 out and let this value be the `else' case. */
2782 if (testexp == true_rtx || newexp == false_rtx)
2784 default_val = XVECEXP (value, 0, i + 1);
2785 break;
2788 /* Compute the expression to pass to our recursive call as being
2789 known true. */
2790 inner_true = insert_right_side (AND, our_known_true,
2791 testexp, insn_code, insn_index);
2793 /* If this is always false, skip it. */
2794 if (inner_true == false_rtx)
2795 continue;
2797 write_indent (indent);
2798 printf ("%sif ", first_if ? "" : "else ");
2799 first_if = 0;
2800 write_test_expr (testexp, 0);
2801 printf ("\n");
2802 write_indent (indent + 2);
2803 printf ("{\n");
2805 write_attr_set (attr, indent + 4,
2806 XVECEXP (value, 0, i + 1), prefix, suffix,
2807 inner_true, insn_code, insn_index);
2808 write_indent (indent + 2);
2809 printf ("}\n");
2810 our_known_true = newexp;
2813 if (! first_if)
2815 write_indent (indent);
2816 printf ("else\n");
2817 write_indent (indent + 2);
2818 printf ("{\n");
2821 write_attr_set (attr, first_if ? indent : indent + 4, default_val,
2822 prefix, suffix, our_known_true, insn_code, insn_index);
2824 if (! first_if)
2826 write_indent (indent + 2);
2827 printf ("}\n");
2830 else
2831 abort ();
2834 /* Write out the computation for one attribute value. */
2836 static void
2837 write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, known_true)
2838 struct attr_desc *attr;
2839 struct attr_value *av;
2840 int write_case_lines;
2841 char *prefix, *suffix;
2842 int indent;
2843 rtx known_true;
2845 struct insn_ent *ie;
2847 if (av->num_insns == 0)
2848 return;
2850 if (av->has_asm_insn)
2852 write_indent (indent);
2853 printf ("case -1:\n");
2854 write_indent (indent + 2);
2855 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
2856 write_indent (indent + 2);
2857 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
2858 write_indent (indent + 2);
2859 printf (" fatal_insn_not_found (insn);\n");
2862 if (write_case_lines)
2864 for (ie = av->first_insn; ie; ie = ie->next)
2865 if (ie->insn_code != -1)
2867 write_indent (indent);
2868 printf ("case %d:\n", ie->insn_code);
2871 else
2873 write_indent (indent);
2874 printf ("default:\n");
2877 /* See what we have to do to handle output this value. */
2878 must_extract = must_constrain = address_used = 0;
2879 walk_attr_value (av->value);
2881 if (must_extract)
2883 write_indent (indent + 2);
2884 printf ("insn_extract (insn);\n");
2887 if (must_constrain)
2889 #ifdef REGISTER_CONSTRAINTS
2890 write_indent (indent + 2);
2891 printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
2892 write_indent (indent + 2);
2893 printf (" fatal_insn_not_found (insn);\n");
2894 #endif
2897 write_attr_set (attr, indent + 2, av->value, prefix, suffix,
2898 known_true, av->first_insn->insn_code,
2899 av->first_insn->insn_index);
2901 if (strncmp (prefix, "return", 6))
2903 write_indent (indent + 2);
2904 printf ("break;\n");
2906 printf ("\n");
2909 /* Utilities to write names in various forms. */
2911 static void
2912 write_attr_valueq (attr, s)
2913 struct attr_desc *attr;
2914 char *s;
2916 if (attr->is_numeric)
2917 printf ("%s", s);
2918 else
2920 write_upcase (attr->name);
2921 printf ("_");
2922 write_upcase (s);
2926 static void
2927 write_attr_value (attr, value)
2928 struct attr_desc *attr;
2929 rtx value;
2931 if (GET_CODE (value) != CONST_STRING)
2932 abort ();
2934 write_attr_valueq (attr, XSTR (value, 0));
2937 static void
2938 write_upcase (str)
2939 char *str;
2941 while (*str)
2942 if (*str < 'a' || *str > 'z')
2943 printf ("%c", *str++);
2944 else
2945 printf ("%c", *str++ - 'a' + 'A');
2948 static void
2949 write_indent (indent)
2950 int indent;
2952 for (; indent > 8; indent -= 8)
2953 printf ("\t");
2955 for (; indent; indent--)
2956 printf (" ");
2959 /* Write a subroutine that is given an insn that requires a delay slot, a
2960 delay slot ordinal, and a candidate insn. It returns non-zero if the
2961 candidate can be placed in the specified delay slot of the insn.
2963 We can write as many as three subroutines. `eligible_for_delay'
2964 handles normal delay slots, `eligible_for_annul_true' indicates that
2965 the specified insn can be annulled if the branch is true, and likewise
2966 for `eligible_for_annul_false'.
2968 KIND is a string distingushing these three cases ("delay", "annul_true",
2969 or "annul_false"). */
2971 static void
2972 write_eligible_delay (kind)
2973 char *kind;
2975 struct delay_desc *delay;
2976 int max_slots;
2977 char str[50];
2978 struct attr_desc *attr;
2979 struct attr_value *av, *common_av;
2980 int i;
2982 /* Compute the maximum number of delay slots required. We use the delay
2983 ordinal times this number plus one, plus the slot number as an index into
2984 the appropriate predicate to test. */
2986 for (delay = delays, max_slots = 0; delay; delay = delay->next)
2987 if (XVECLEN (delay->def, 1) / 3 > max_slots)
2988 max_slots = XVECLEN (delay->def, 1) / 3;
2990 /* Write function prelude. */
2992 printf ("int\n");
2993 printf ("eligible_for_%s (delay_insn, slot, candidate_insn)\n", kind);
2994 printf (" rtx delay_insn;\n");
2995 printf (" int slot;\n");
2996 printf (" rtx candidate_insn;\n");
2997 printf ("{\n");
2998 printf (" rtx insn;\n");
2999 printf ("\n");
3000 printf (" if (slot >= %d)\n", max_slots);
3001 printf (" abort ();\n");
3002 printf ("\n");
3004 /* If more than one delay type, find out which type the delay insn is. */
3006 if (num_delays > 1)
3008 sprintf (str, "*delay_type", kind);
3009 attr = find_attr (str, 0);
3010 if (! attr) abort ();
3011 common_av = find_most_used (attr);
3013 printf (" insn = delay_insn;\n");
3014 printf (" switch (recog_memoized (insn))\n");
3015 printf (" {\n");
3017 sprintf (str, " * %d;\n break;", max_slots);
3018 for (av = attr->first_value; av; av = av->next)
3019 if (av != common_av)
3020 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
3022 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
3023 printf (" }\n\n");
3025 /* Ensure matched. Otherwise, shouldn't have been called. */
3026 printf (" if (slot < %d)\n", max_slots);
3027 printf (" abort ();\n\n");
3030 /* If just one type of delay slot, write simple switch. */
3031 if (num_delays == 1 && max_slots == 1)
3033 printf (" insn = candidate_insn;\n");
3034 printf (" switch (recog_memoized (insn))\n");
3035 printf (" {\n");
3037 attr = find_attr ("*delay_1_0", 0);
3038 if (! attr) abort ();
3039 common_av = find_most_used (attr);
3041 for (av = attr->first_value; av; av = av->next)
3042 if (av != common_av)
3043 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
3045 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
3046 printf (" }\n");
3049 else
3051 /* Write a nested CASE. The first indicates which condition we need to
3052 test, and the inner CASE tests the condition. */
3053 printf (" insn = candidate_insn;\n");
3054 printf (" switch (slot)\n");
3055 printf (" {\n");
3057 for (delay = delays; delay; delay = delay->next)
3058 for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
3060 printf (" case %d:\n",
3061 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
3062 printf (" switch (recog_memoized (insn))\n");
3063 printf ("\t{\n");
3065 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
3066 attr = find_attr (str, 0);
3067 if (! attr) abort ();
3068 common_av = find_most_used (attr);
3070 for (av = attr->first_value; av; av = av->next)
3071 if (av != common_av)
3072 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
3074 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
3075 printf (" }\n");
3078 printf (" default:\n");
3079 printf (" abort ();\n");
3080 printf (" }\n");
3083 printf ("}\n\n");
3086 /* Write routines to compute conflict cost for function units. Then write a
3087 table describing the available function units. */
3089 static void
3090 write_function_unit_info ()
3092 struct function_unit *unit;
3093 struct attr_desc *case_attr, *attr;
3094 struct attr_value *av, *common_av;
3095 rtx value;
3096 char *str;
3097 int using_case;
3098 int i;
3100 /* Write out conflict routines for function units. Don't bother writing
3101 one if there is only one busy value. */
3103 for (unit = units; unit; unit = unit->next)
3105 /* See if only one case exists and if there is a constant value for
3106 that case. If so, we don't need a function. */
3107 str = (char *) xmalloc (strlen (unit->name) + 10);
3108 sprintf (str, "*%s_cases", unit->name);
3109 attr = find_attr (str, 0);
3110 if (! attr) abort ();
3111 value = find_single_value (attr);
3112 if (value && GET_CODE (value) == CONST_STRING)
3114 sprintf (str, "*%s_case_%s", unit->name, XSTR (value, 0));
3115 attr = find_attr (str, 0);
3116 if (! attr) abort ();
3117 value = find_single_value (attr);
3118 if (value && GET_CODE (value) == CONST_STRING)
3120 unit->needs_conflict_function = 0;
3121 unit->default_cost = value;
3122 continue;
3126 /* The function first computes the case from the candidate insn. */
3127 unit->needs_conflict_function = 1;
3128 unit->default_cost = make_numeric_value (0);
3130 printf ("static int\n");
3131 printf ("%s_unit_conflict_cost (executing_insn, candidate_insn)\n",
3132 unit->name);
3133 printf (" rtx executing_insn;\n");
3134 printf (" rtx candidate_insn;\n");
3135 printf ("{\n");
3136 printf (" rtx insn;\n");
3137 printf (" int casenum;\n\n");
3138 printf (" insn = candidate_insn;\n");
3139 printf (" switch (recog_memoized (insn))\n");
3140 printf (" {\n");
3142 /* Write the `switch' statement to get the case value. */
3143 sprintf (str, "*%s_cases", unit->name);
3144 case_attr = find_attr (str, 0);
3145 if (! case_attr) abort ();
3146 common_av = find_most_used (case_attr);
3148 for (av = case_attr->first_value; av; av = av->next)
3149 if (av != common_av)
3150 write_attr_case (case_attr, av, 1,
3151 "casenum =", ";", 4, unit->condexp);
3153 write_attr_case (case_attr, common_av, 0,
3154 "casenum =", ";", 4, unit->condexp);
3155 printf (" }\n\n");
3157 /* Now write an outer switch statement on each case. Then write
3158 the tests on the executing function within each. */
3159 printf (" insn = executing_insn;\n");
3160 printf (" switch (casenum)\n");
3161 printf (" {\n");
3163 for (i = 0; i < unit->num_opclasses; i++)
3165 /* Ensure using this case. */
3166 using_case = 0;
3167 for (av = case_attr->first_value; av; av = av->next)
3168 if (av->num_insns
3169 && contained_in_p (make_numeric_value (i), av->value))
3170 using_case = 1;
3172 if (! using_case)
3173 continue;
3175 printf (" case %d:\n", i);
3176 sprintf (str, "*%s_case_%d", unit->name, i);
3177 attr = find_attr (str, 0);
3178 if (! attr) abort ();
3180 /* If single value, just write it. */
3181 value = find_single_value (attr);
3182 if (value)
3183 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2);
3184 else
3186 common_av = find_most_used (attr);
3187 printf (" switch (recog_memoized (insn))\n");
3188 printf ("\t{\n");
3190 for (av = attr->first_value; av; av = av->next)
3191 if (av != common_av)
3192 write_attr_case (attr, av, 1,
3193 "return", ";", 8, unit->condexp);
3195 write_attr_case (attr, common_av, 0,
3196 "return", ";", 8, unit->condexp);
3197 printf (" }\n\n");
3201 printf (" }\n}\n\n");
3204 /* Now that all functions have been written, write the table describing
3205 the function units. The name is included for documenation purposes
3206 only. */
3208 printf ("struct function_unit_desc function_units[] = {\n");
3210 for (unit = units; unit; unit = unit->next)
3212 printf (" {\"%s\", %d, %d, %d, %s, %s_unit_ready_cost, ",
3213 unit->name, 1 << unit->num, unit->multiplicity,
3214 unit->simultaneity, XSTR (unit->default_cost, 0), unit->name);
3216 if (unit->needs_conflict_function)
3217 printf ("%s_unit_conflict_cost", unit->name);
3218 else
3219 printf ("0");
3221 printf ("}, \n");
3224 printf ("};\n\n");
3227 /* This page contains miscellaneous utility routines. */
3229 /* Given a string, return the number of comma-separated elements in it.
3230 Return 0 for the null string. */
3232 static int
3233 n_comma_elts (s)
3234 char *s;
3236 int n;
3238 if (*s == '\0')
3239 return 0;
3241 for (n = 1; *s; s++)
3242 if (*s == ',')
3243 n++;
3245 return n;
3248 /* Given a pointer to a (char *), return a malloc'ed string containing the
3249 next comma-separated element. Advance the pointer to after the string
3250 scanned, or the end-of-string. Return NULL if at end of string. */
3252 static char *
3253 next_comma_elt (pstr)
3254 char **pstr;
3256 char *out_str;
3257 char *p;
3259 if (**pstr == '\0')
3260 return NULL;
3262 /* Find end of string to compute length. */
3263 for (p = *pstr; *p != ',' && *p != '\0'; p++)
3266 out_str = (char *) xmalloc (p - *pstr + 1);
3267 for (p = out_str; **pstr != ',' && **pstr != '\0'; (*pstr)++)
3268 *p++ = **pstr;
3270 *p++ = '\0';
3271 if (**pstr == ',')
3272 (*pstr)++;
3274 return out_str;
3277 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
3278 is non-zero, build a new attribute, if one does not exist. */
3280 static struct attr_desc *
3281 find_attr (name, create)
3282 char *name;
3283 int create;
3285 struct attr_desc *attr;
3286 char *new_name;
3288 /* Before we resort to using `strcmp', see if the string address matches
3289 anywhere. In most cases, it should have been canonicalized to do so. */
3290 if (name == alternative_name)
3291 return NULL;
3293 for (attr = attrs; attr; attr = attr->next)
3294 if (name == attr->name)
3295 return attr;
3297 /* Otherwise, do it the slow way. */
3298 for (attr = attrs; attr; attr = attr->next)
3299 if (! strcmp (name, attr->name))
3300 return attr;
3302 if (! create)
3303 return NULL;
3305 new_name = (char *) xmalloc (strlen (name) + 1);
3306 strcpy (new_name, name);
3308 attr = (struct attr_desc *) xmalloc (sizeof (struct attr_desc));
3309 attr->name = new_name;
3310 attr->first_value = attr->default_val = NULL;
3311 attr->is_numeric = attr->is_special = 0;
3312 attr->next = attrs;
3313 attrs = attr;
3315 return attr;
3318 /* Create internal attribute with the given default value. */
3320 static void
3321 make_internal_attr (name, value, special)
3322 char *name;
3323 rtx value;
3324 int special;
3326 struct attr_desc *attr;
3328 attr = find_attr (name, 1);
3329 if (attr->default_val)
3330 abort ();
3332 attr->is_numeric = 1;
3333 attr->is_special = special;
3334 attr->default_val = get_attr_value (value, attr, -2);
3337 /* Find the most used value of an attribute. */
3339 static struct attr_value *
3340 find_most_used (attr)
3341 struct attr_desc *attr;
3343 struct attr_value *av;
3344 struct attr_value *most_used;
3345 int nuses;
3347 most_used = NULL;
3348 nuses = -1;
3350 for (av = attr->first_value; av; av = av->next)
3351 if (av->num_insns > nuses)
3352 nuses = av->num_insns, most_used = av;
3354 return most_used;
3357 /* If an attribute only has a single value used, return it. Otherwise
3358 return NULL. */
3360 static rtx
3361 find_single_value (attr)
3362 struct attr_desc *attr;
3364 struct attr_value *av;
3365 rtx unique_value;
3367 unique_value = NULL;
3368 for (av = attr->first_value; av; av = av->next)
3369 if (av->num_insns)
3371 if (unique_value)
3372 return NULL;
3373 else
3374 unique_value = av->value;
3377 return unique_value;
3380 /* Return (attr_value "n") */
3382 static rtx
3383 make_numeric_value (n)
3384 int n;
3386 static rtx int_values[20];
3387 rtx exp;
3389 if (n < 0)
3390 abort ();
3392 if (n < 20 && int_values[n])
3393 return int_values[n];
3395 exp = rtx_alloc (CONST_STRING);
3396 XSTR (exp, 0) = (char *) xmalloc ((n < 1000 ? 4
3397 : HOST_BITS_PER_INT * 3 / 10 + 3));
3398 sprintf (XSTR (exp, 0), "%d", n);
3400 if (n < 20)
3401 int_values[n] = exp;
3403 return exp;
3406 char *
3407 xrealloc (ptr, size)
3408 char *ptr;
3409 unsigned size;
3411 char *result = (char *) realloc (ptr, size);
3412 if (!result)
3413 fatal ("virtual memory exhausted");
3414 return result;
3417 char *
3418 xmalloc (size)
3419 unsigned size;
3421 register char *val = (char *) malloc (size);
3423 if (val == 0)
3424 fatal ("virtual memory exhausted");
3425 return val;
3428 static void
3429 fatal (s, a1, a2)
3430 char *s;
3432 fprintf (stderr, "genattrtab: ");
3433 fprintf (stderr, s, a1, a2);
3434 fprintf (stderr, "\n");
3435 exit (FATAL_EXIT_CODE);
3438 /* More 'friendly' abort that prints the line and file.
3439 config.h can #define abort fancy_abort if you like that sort of thing. */
3441 void
3442 fancy_abort ()
3444 fatal ("Internal gcc abort.");
3448 main (argc, argv)
3449 int argc;
3450 char **argv;
3452 rtx desc;
3453 FILE *infile;
3454 extern rtx read_rtx ();
3455 register int c;
3456 struct attr_desc *attr;
3457 struct attr_value *av;
3458 struct insn_def *id;
3459 rtx tem;
3461 obstack_init (rtl_obstack);
3463 if (argc <= 1)
3464 fatal ("No input file name.");
3466 infile = fopen (argv[1], "r");
3467 if (infile == 0)
3469 perror (argv[1]);
3470 exit (FATAL_EXIT_CODE);
3473 init_rtl ();
3475 /* Set up true and false rtx's */
3476 true_rtx = rtx_alloc (CONST_INT);
3477 false_rtx = rtx_alloc (CONST_INT);
3478 XINT (true_rtx, 0) = 1;
3479 XINT (false_rtx, 0) = 0;
3480 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
3482 printf ("/* Generated automatically by the program `genattrtab'\n\
3483 from the machine description file `md'. */\n\n");
3485 /* Read the machine description. */
3487 while (1)
3489 c = read_skip_spaces (infile);
3490 if (c == EOF)
3491 break;
3492 ungetc (c, infile);
3494 desc = read_rtx (infile);
3495 if (GET_CODE (desc) == DEFINE_INSN
3496 || GET_CODE (desc) == DEFINE_PEEPHOLE
3497 || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
3498 gen_insn (desc);
3500 else if (GET_CODE (desc) == DEFINE_EXPAND)
3501 insn_code_number++, insn_index_number++;
3503 else if (GET_CODE (desc) == DEFINE_SPLIT)
3504 insn_code_number++, insn_index_number++;
3506 else if (GET_CODE (desc) == DEFINE_ATTR)
3508 gen_attr (desc);
3509 insn_index_number++;
3512 else if (GET_CODE (desc) == DEFINE_DELAY)
3514 gen_delay (desc);
3515 insn_index_number++;
3518 else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
3520 gen_unit (desc);
3521 insn_index_number++;
3525 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
3526 if (! got_define_asm_attributes)
3528 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
3529 XVEC (tem, 0) = rtvec_alloc (0);
3530 gen_insn (tem);
3533 /* Expand DEFINE_DELAY information into new attribute. */
3534 if (num_delays)
3535 expand_delays ();
3537 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
3538 if (num_units)
3539 expand_units ();
3541 printf ("#include \"config.h\"\n");
3542 printf ("#include \"rtl.h\"\n");
3543 printf ("#include \"insn-config.h\"\n");
3544 printf ("#include \"recog.h\"\n");
3545 printf ("#include \"regs.h\"\n");
3546 printf ("#include \"real.h\"\n");
3547 printf ("#include \"output.h\"\n");
3548 printf ("#include \"insn-attr.h\"\n");
3549 printf ("\n");
3550 printf ("#define operands recog_operand\n\n");
3552 /* Make `insn_alternatives'. */
3553 insn_alternatives = (int *) xmalloc (insn_code_number * sizeof (int));
3554 for (id = defs; id; id = id->next)
3555 if (id->insn_code >= 0)
3556 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
3558 /* Prepare to write out attribute subroutines by checking everything stored
3559 away and building the attribute cases. */
3561 check_defs ();
3562 for (attr = attrs; attr; attr = attr->next)
3564 check_attr_value (attr->default_val->value, attr);
3565 fill_attr (attr);
3568 /* Construct extra attributes for `length'. */
3569 make_length_attrs ();
3571 /* Perform any possible optimizations to speed up compilation. */
3572 optimize_attrs ();
3574 /* Now write out all the `gen_attr_...' routines. Do these before the
3575 special routines (specifically before write_function_unit_info), so
3576 that they get defined before they are used. */
3578 for (attr = attrs; attr; attr = attr->next)
3580 if (! attr->is_special)
3581 write_attr_get (attr);
3584 /* Write out delay eligibility information, if DEFINE_DELAY present.
3585 (The function to compute the number of delay slots will be written
3586 below.) */
3587 if (num_delays)
3589 write_eligible_delay ("delay");
3590 if (have_annul_true)
3591 write_eligible_delay ("annul_true");
3592 if (have_annul_false)
3593 write_eligible_delay ("annul_false");
3596 /* Write out information about function units. */
3597 if (num_units)
3598 write_function_unit_info ();
3600 fflush (stdout);
3601 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
3602 /* NOTREACHED */
3603 return 0;