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)
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
34 If the attribute `alternative', or a random C expression is present,
35 `constrain_operands' is called. If either of these cases of a reference to
36 an operand is found, `insn_extract' is called.
38 The special attribute `length' is also recognized. For this operand,
39 expressions involving the address of an operand or the current insn,
40 (address (pc)), are valid. In this case, an initial pass is made to
41 set all lengths that do not depend on address. Those that do are set to
42 the maximum length. Then each insn that depends on an address is checked
43 and possibly has its length changed. The process repeats until no further
44 changed are made. The resulting lengths are saved for use by
47 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
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
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. */
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
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
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. */
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. */
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. */
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
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
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 ();
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. */
298 check_attr_test (exp
)
301 struct attr_desc
*attr
;
302 struct attr_value
*av
;
306 switch (GET_CODE (exp
))
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);
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;
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",
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)))
352 fatal ("Unknown value `%s' for `%s' attribute",
353 XEXP (exp
, 1), XEXP (exp
, 0));
358 /* Make an IOR tree of the possible values. */
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
);
374 /* Either TRUE or FALSE. */
382 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0));
383 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1));
387 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0));
391 case LE
: case LT
: case GT
: case GE
:
392 case LEU
: case LTU
: case GTU
: case GEU
:
394 /* These cases can't be simplified. */
395 RTX_UNCHANGING_P (exp
) = 1;
399 fatal ("RTL operator \"%s\" not valid in attribute test",
400 GET_RTX_NAME (GET_CODE (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. */
411 check_attr_value (exp
, attr
)
413 struct attr_desc
*attr
;
415 struct attr_value
*av
;
419 switch (GET_CODE (exp
))
422 if (attr
&& ! attr
->is_numeric
)
423 fatal ("CONST_INT not valid for non-numeric `%s' attribute",
426 if (INTVAL (exp
) < 0)
427 fatal ("Negative numeric value specified for `%s' attribute",
433 if (! strcmp (XSTR (exp
, 0), "*"))
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
);
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)))
451 fatal ("Unknown value `%s' for `%s' attribute",
452 XSTR (exp
, 0), attr
? "internal" : attr
->name
);
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
);
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
);
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") */
485 convert_set_attr_alternative (exp
, num_alt
, insn_code
, insn_index
)
488 int insn_code
, insn_index
;
494 if (XVECLEN (exp
, 1) != num_alt
)
495 fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
498 /* Make a COND with all tests but the last. Select the last value via the
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
;
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. */
526 convert_set_attr (exp
, num_alt
, insn_code
, insn_index
)
529 int insn_code
, insn_index
;
536 /* See how many alternative specified. */
537 n
= n_comma_elts (XSTR (exp
, 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);
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);
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
573 struct attr_desc
*attr
;
577 for (id
= defs
; id
; id
= id
->next
)
579 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
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
))
588 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
589 fatal ("Bad attribute set in pattern %d", id
->insn_index
);
592 case SET_ATTR_ALTERNATIVE
:
593 value
= convert_set_attr_alternative (value
,
594 id
->num_alternatives
,
600 value
= convert_set_attr (value
, id
->num_alternatives
,
601 id
->insn_code
, id
->insn_index
);
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
625 make_canonical (attr
, exp
)
626 struct attr_desc
*attr
;
632 switch (GET_CODE (exp
))
635 exp
= make_numeric_value (INTVAL (exp
));
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
;
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);
657 /* Fall through to COND case since this is now a 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));
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
684 static struct attr_value
*
685 get_attr_value (value
, attr
, insn_code
)
687 struct attr_desc
*attr
;
690 struct attr_value
*av
;
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");
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
]))
708 av
= (struct attr_value
*) xmalloc (sizeof (struct attr_value
));
710 av
->next
= attr
->first_value
;
711 attr
->first_value
= av
;
712 av
->first_insn
= NULL
;
714 av
->has_asm_insn
= 0;
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. */
736 struct delay_desc
*delay
;
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. */
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);
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. */
829 operate_exp (op
, left
, right
)
833 int left_value
, right_value
;
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));
848 i
= left_value
+ right_value
;
852 i
= left_value
- right_value
;
856 i
= left_value
| right_value
;
860 if (left_value
> right_value
)
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));
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));
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
);
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
);
929 fatal ("Badly formed attribute value.");
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). */
959 struct function_unit
*unit
;
960 struct function_unit_op
*op
;
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
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
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
);
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
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
1044 struct attr_desc
*attr
;
1046 struct attr_value
*av
;
1047 struct insn_ent
*ie
;
1048 struct insn_def
*id
;
1052 for (id
= defs
; id
; id
= id
->next
)
1054 /* If no value is specified for this insn for this attribute, use the
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),
1061 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1064 av
= attr
->default_val
;
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
1083 substitute_address (exp
, no_address_fn
, address_fn
)
1085 rtx (*no_address_fn
) ();
1086 rtx (*address_fn
) ();
1091 if (GET_CODE (exp
) != COND
)
1092 return (*no_address_fn
) (exp
);
1094 /* See if any tests use addresses. */
1096 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1097 walk_attr_value (XVECEXP (exp
, 0, i
));
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),
1113 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1114 no_address_fn
, address_fn
);
1119 /* Make new attributes from the `length' attribute. The following are made,
1120 each corresponding to a function called from `shorten_branches' or
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.
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
};
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)
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
,
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. */
1198 return make_numeric_value (0);
1205 return make_numeric_value (1);
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. */
1225 simplify_cond (exp
, insn_code
, insn_index
)
1227 int insn_code
, insn_index
;
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);
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);
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
;
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
;
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);
1308 /* If this value and the value for the next test are the same, merge the
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);
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
;
1349 else if (XVECLEN (newexp
, 0) == 1)
1350 return XVECEXP (newexp
, 0, 0);
1352 return simplify_cond (newexp
, insn_code
, insn_index
);
1355 /* Remove an insn entry from an attribute value. */
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
;
1368 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1370 previe
->next
= ie
->next
;
1374 if (ie
->insn_code
== -1)
1375 av
->has_asm_insn
= 0;
1378 /* Insert an insn entry in an attribute value list. */
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
;
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
1399 If the `term' is itself a tree, all its leaves will be inserted. */
1402 insert_right_side (code
, exp
, term
, insn_code
, insn_index
)
1406 int insn_code
, insn_index
;
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
);
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
);
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. */
1448 compute_alternative_mask (exp
, 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));
1469 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1470 attribute with the value represented by that bit. */
1473 make_alternative_compare (mask
)
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;
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. */
1502 evaluate_eq_attr (exp
, value
, insn_code
, insn_index
)
1505 int insn_code
, insn_index
;
1512 if (GET_CODE (value
) == CONST_STRING
)
1514 if (! strcmp (XSTR (value
, 0), XSTR (exp
, 1)))
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. */
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
);
1565 /* If uses an address, must return original expression. */
1568 walk_attr_value (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
1591 simplify_and_tree (exp
, pterm
, insn_code
, insn_index
)
1594 int insn_code
, insn_index
;
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. */
1620 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
1621 left_eliminates_term
= (temp
== true_rtx
);
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
)
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. */
1646 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
1649 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
1652 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
1654 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
1657 if (! strcmp (XSTR (exp
, 1), XSTR (*pterm
, 1)))
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))
1669 if (! strcmp (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
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))
1681 if (! strcmp (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
1687 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
1689 if (rtx_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
1693 else if (GET_CODE (exp
) == NOT
)
1695 if (rtx_equal_p (XEXP (exp
, 0), *pterm
))
1699 else if (GET_CODE (*pterm
) == NOT
)
1701 if (rtx_equal_p (XEXP (*pterm
, 0), exp
))
1705 else if (rtx_equal_p (exp
, *pterm
))
1711 /* Similiar to `simplify_and_tree', but for IOR trees. */
1714 simplify_or_tree (exp
, pterm
, insn_code
, insn_index
)
1717 int insn_code
, insn_index
;
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. */
1743 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
1744 left_eliminates_term
= (temp
== false_rtx
);
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
)
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
))
1766 else if (GET_CODE (exp
) == NOT
&& rtx_equal_p (XEXP (exp
, 0), *pterm
))
1769 else if (GET_CODE (*pterm
) == NOT
&& rtx_equal_p (XEXP (*pterm
, 0), exp
))
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))
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))
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
1795 simplify_test_exp (exp
, insn_code
, insn_index
)
1797 int insn_code
, insn_index
;
1800 struct attr_desc
*attr
;
1801 struct attr_value
*av
;
1802 struct insn_ent
*ie
;
1806 switch (GET_CODE (exp
))
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
)
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
)
1843 else if (left
== true_rtx
)
1845 else if (right
== true_rtx
)
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",
1866 /* If all alternatives are excluded, this is false. */
1867 i
^= insn_alternatives
[insn_code
];
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
);
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
)
1905 else if (left
== false_rtx
)
1907 else if (right
== false_rtx
)
1910 /* Test for simple cases where the distributive law is useful. I.e.,
1911 convert (ior (and (x) (y))
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);
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",
1948 /* If all alternatives are included, this is true. */
1949 i
^= insn_alternatives
[insn_code
];
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
);
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
)
1985 else if (left
== true_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
;
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;
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. */
2044 struct attr_desc
*attr
;
2045 struct attr_value
*av
;
2046 struct insn_ent
*ie
, *nextie
;
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
)
2059 if (GET_CODE (av
->value
) != COND
)
2062 newexp
= simplify_cond (av
->value
, ie
->insn_code
,
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. */
2081 struct attr_desc
*attr
;
2082 struct attr_value
*av
;
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;
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
;
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. */
2123 count_alternatives (exp
)
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
++)
2138 n
= count_alternatives (XEXP (exp
, i
));
2145 if (XVEC (exp
, i
) != NULL
)
2146 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2148 n
= count_alternatives (XVECEXP (exp
, i
, j
));
2157 /* Returns non-zero if the given expression contains an EQ_ATTR with the
2158 `alternative' attribute. */
2161 compares_alternatives_p (exp
)
2167 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
2170 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
2171 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
2176 if (compares_alternatives_p (XEXP (exp
, i
)))
2181 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2182 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
2190 /* Returns non-zero is INNER is contained in EXP. */
2193 contained_in_p (inner
, exp
)
2200 if (rtx_equal_p (inner
, exp
))
2203 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
2204 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
2209 if (contained_in_p (inner
, XEXP (exp
, i
)))
2214 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2215 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
2223 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
2229 struct insn_def
*id
;
2231 id
= (struct insn_def
*) xmalloc (sizeof (struct insn_def
));
2236 switch (GET_CODE (exp
))
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;
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;
2256 case DEFINE_ASM_ATTRIBUTES
:
2258 id
->insn_index
= -1;
2259 id
->num_alternatives
= 1;
2261 got_define_asm_attributes
= 1;
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'. */
2273 struct delay_desc
*delay
;
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
));
2289 delay
->num
= ++num_delays
;
2290 delay
->next
= delays
;
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'. */
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.",
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
;
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
;
2342 /* Set our busy expression based on whether or not an optional conflict
2343 vector was specified. */
2346 /* Compute the IOR of all the specified expressions. */
2347 rtx orexp
= false_rtx
;
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);
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. */
2372 write_test_expr (exp
, in_comparison
)
2376 int comparison_operator
= 0;
2378 struct attr_desc
*attr
;
2380 /* In order not to worry about operator precedence, surround our part of
2381 the expression with parentheses. */
2384 code
= GET_CODE (exp
);
2387 /* Binary operators. */
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
);
2412 printf (" >= (unsigned) ");
2415 printf (" > (unsigned) ");
2424 printf (" <= (unsigned) ");
2427 printf (" < (unsigned) ");
2469 write_test_expr (XEXP (exp
, 1), in_comparison
|| comparison_operator
);
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));
2481 /* Otherwise, fall through to normal unary operator. */
2483 /* Unary operators. */
2501 write_test_expr (XEXP (exp
, 0), in_comparison
);
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. */
2509 fatal ("EQ_ATTR not valid inside comparison");
2511 if (XSTR (exp
, 0) == alternative_name
)
2513 printf ("which_alternative == %s", XSTR (exp
, 1));
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));
2523 /* See if an operand matches a predicate. */
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");
2532 printf ("GET_MODE (operands[%d]) == %smode",
2533 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
2536 printf ("%s (operands[%d], %smode)",
2537 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
2540 /* Constant integer. */
2542 printf ("%d", XINT (exp
, 0));
2545 /* A random C expression. */
2547 printf ("%s", XSTR (exp
, 0));
2550 /* The address of the branch target. */
2552 printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
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
2560 printf ("insn_current_address");
2564 fatal ("bad RTX code `%s' in attribute calculation\n",
2565 GET_RTX_NAME (code
));
2571 /* Given an attribute value, return the maximum CONST_STRING argument
2572 encountered. It is assumed that they are all numeric. */
2575 max_attr_value (exp
)
2578 int current_max
= 0;
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
)
2594 n
= max_attr_value (XEXP (exp
, 1));
2595 if (n
> 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.
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
2615 walk_attr_value (exp
)
2625 code
= GET_CODE (exp
);
2629 /* Since this is an arbitrary expression, it can look at anything. */
2630 must_extract
= must_constrain
= 1;
2638 if (XSTR (exp
, 0) == alternative_name
)
2639 must_extract
= must_constrain
= 1;
2648 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
2653 walk_attr_value (XEXP (exp
, i
));
2657 if (XVEC (exp
, i
) != NULL
)
2658 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2659 walk_attr_value (XVECEXP (exp
, i
, j
));
2664 /* Write out a function to obtain the attribute for a given INSN. */
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
)
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]);
2688 printf ("get_attr_%s (insn)\n", attr
->name
);
2689 printf (" rtx insn;\n");
2691 printf (" switch (recog_memoized (insn))\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. */
2708 eliminate_known_true (known_true
, exp
, insn_code
, insn_index
)
2711 int insn_code
, insn_index
;
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
);
2727 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
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"
2739 write_attr_set (attr
, indent
, value
, prefix
, suffix
, known_true
,
2740 insn_code
, insn_index
)
2741 struct attr_desc
*attr
;
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
;
2766 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
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);
2788 /* Compute the expression to pass to our recursive call as being
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
)
2797 write_indent (indent
);
2798 printf ("%sif ", first_if
? "" : "else ");
2800 write_test_expr (testexp
, 0);
2802 write_indent (indent
+ 2);
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);
2810 our_known_true
= newexp
;
2815 write_indent (indent
);
2817 write_indent (indent
+ 2);
2821 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
2822 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
2826 write_indent (indent
+ 2);
2834 /* Write out the computation for one attribute value. */
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
;
2845 struct insn_ent
*ie
;
2847 if (av
->num_insns
== 0)
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
);
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
);
2883 write_indent (indent
+ 2);
2884 printf ("insn_extract (insn);\n");
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");
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");
2909 /* Utilities to write names in various forms. */
2912 write_attr_valueq (attr
, s
)
2913 struct attr_desc
*attr
;
2916 if (attr
->is_numeric
)
2920 write_upcase (attr
->name
);
2927 write_attr_value (attr
, value
)
2928 struct attr_desc
*attr
;
2931 if (GET_CODE (value
) != CONST_STRING
)
2934 write_attr_valueq (attr
, XSTR (value
, 0));
2942 if (*str
< 'a' || *str
> 'z')
2943 printf ("%c", *str
++);
2945 printf ("%c", *str
++ - 'a' + 'A');
2949 write_indent (indent
)
2952 for (; indent
> 8; indent
-= 8)
2955 for (; indent
; indent
--)
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"). */
2972 write_eligible_delay (kind
)
2975 struct delay_desc
*delay
;
2978 struct attr_desc
*attr
;
2979 struct attr_value
*av
, *common_av
;
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. */
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");
2998 printf (" rtx insn;\n");
3000 printf (" if (slot >= %d)\n", max_slots
);
3001 printf (" abort ();\n");
3004 /* If more than one delay type, find out which type the delay insn is. */
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");
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
);
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");
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
);
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");
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");
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
);
3078 printf (" default:\n");
3079 printf (" abort ();\n");
3086 /* Write routines to compute conflict cost for function units. Then write a
3087 table describing the available function units. */
3090 write_function_unit_info ()
3092 struct function_unit
*unit
;
3093 struct attr_desc
*case_attr
, *attr
;
3094 struct attr_value
*av
, *common_av
;
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
;
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",
3133 printf (" rtx executing_insn;\n");
3134 printf (" rtx candidate_insn;\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");
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
);
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");
3163 for (i
= 0; i
< unit
->num_opclasses
; i
++)
3165 /* Ensure using this case. */
3167 for (av
= case_attr
->first_value
; av
; av
= av
->next
)
3169 && contained_in_p (make_numeric_value (i
), av
->value
))
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
);
3183 write_attr_set (attr
, 6, value
, "return", ";\n", true_rtx
, -2);
3186 common_av
= find_most_used (attr
);
3187 printf (" switch (recog_memoized (insn))\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
);
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
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
);
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. */
3241 for (n
= 1; *s
; s
++)
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. */
3253 next_comma_elt (pstr
)
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
)++)
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
)
3285 struct attr_desc
*attr
;
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
)
3293 for (attr
= attrs
; attr
; attr
= attr
->next
)
3294 if (name
== attr
->name
)
3297 /* Otherwise, do it the slow way. */
3298 for (attr
= attrs
; attr
; attr
= attr
->next
)
3299 if (! strcmp (name
, attr
->name
))
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;
3318 /* Create internal attribute with the given default value. */
3321 make_internal_attr (name
, value
, special
)
3326 struct attr_desc
*attr
;
3328 attr
= find_attr (name
, 1);
3329 if (attr
->default_val
)
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
;
3350 for (av
= attr
->first_value
; av
; av
= av
->next
)
3351 if (av
->num_insns
> nuses
)
3352 nuses
= av
->num_insns
, most_used
= av
;
3357 /* If an attribute only has a single value used, return it. Otherwise
3361 find_single_value (attr
)
3362 struct attr_desc
*attr
;
3364 struct attr_value
*av
;
3367 unique_value
= NULL
;
3368 for (av
= attr
->first_value
; av
; av
= av
->next
)
3374 unique_value
= av
->value
;
3377 return unique_value
;
3380 /* Return (attr_value "n") */
3383 make_numeric_value (n
)
3386 static rtx int_values
[20];
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
);
3401 int_values
[n
] = exp
;
3407 xrealloc (ptr
, size
)
3411 char *result
= (char *) realloc (ptr
, size
);
3413 fatal ("virtual memory exhausted");
3421 register char *val
= (char *) malloc (size
);
3424 fatal ("virtual memory exhausted");
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. */
3444 fatal ("Internal gcc abort.");
3454 extern rtx
read_rtx ();
3456 struct attr_desc
*attr
;
3457 struct attr_value
*av
;
3458 struct insn_def
*id
;
3461 obstack_init (rtl_obstack
);
3464 fatal ("No input file name.");
3466 infile
= fopen (argv
[1], "r");
3470 exit (FATAL_EXIT_CODE
);
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. */
3489 c
= read_skip_spaces (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
)
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
)
3509 insn_index_number
++;
3512 else if (GET_CODE (desc
) == DEFINE_DELAY
)
3515 insn_index_number
++;
3518 else if (GET_CODE (desc
) == DEFINE_FUNCTION_UNIT
)
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);
3533 /* Expand DEFINE_DELAY information into new attribute. */
3537 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
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");
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. */
3562 for (attr
= attrs
; attr
; attr
= attr
->next
)
3564 check_attr_value (attr
->default_val
->value
, attr
);
3568 /* Construct extra attributes for `length'. */
3569 make_length_attrs ();
3571 /* Perform any possible optimizations to speed up compilation. */
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
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. */
3598 write_function_unit_info ();
3601 exit (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);