1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@nyu.edu)
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21 /* This program handles insn attribues and the DEFINE_DELAY and
22 DEFINE_FUNCTION_UNIT definitions.
24 It produces a series of functions 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 or IF_THEN_ELSE that has a
1076 test that checks relative positions of insns (uses MATCH_DUP or PC).
1077 If so, replace it with what is obtained by passing the expression to
1078 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1079 recursively on each value (including the default value). Otherwise,
1080 return the value returned by NO_ADDRESS_FN applied to EXP. */
1083 substitute_address (exp
, no_address_fn
, address_fn
)
1085 rtx (*no_address_fn
) ();
1086 rtx (*address_fn
) ();
1091 if (GET_CODE (exp
) == COND
)
1093 /* See if any tests use addresses. */
1095 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1096 walk_attr_value (XVECEXP (exp
, 0, i
));
1099 return (*address_fn
) (exp
);
1101 /* Make a new copy of this COND, replacing each element. */
1102 newexp
= rtx_alloc (COND
);
1103 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1104 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1106 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1107 XVECEXP (newexp
, 0, i
+ 1)
1108 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1109 no_address_fn
, address_fn
);
1112 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1113 no_address_fn
, address_fn
);
1118 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1121 walk_attr_value (XEXP (exp
, 0));
1123 return (*address_fn
) (exp
);
1125 newexp
= rtx_alloc (IF_THEN_ELSE
);
1126 XEXP (newexp
, 0) = substitute_address (XEXP (exp
, 0),
1127 no_address_fn
, address_fn
);
1128 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1129 no_address_fn
, address_fn
);
1130 XEXP (newexp
, 2) = substitute_address (XEXP (exp
, 2),
1131 no_address_fn
, address_fn
);
1136 return (*no_address_fn
) (exp
);
1139 /* Make new attributes from the `length' attribute. The following are made,
1140 each corresponding to a function called from `shorten_branches' or
1143 *insn_default_length This is the length of the insn to be returned
1144 by `get_attr_length' before `shorten_branches'
1145 has been called. In each case where the length
1146 depends on relative addresses, the largest
1147 possible is used. This routine is also used
1148 to compute the initial size of the insn.
1150 *insn_variable_length_p This returns 1 if the insn's length depends
1151 on relative addresses, zero otherwise.
1153 *insn_current_length This is only called when it is known that the
1154 insn has a variable length and returns the
1155 current length, based on relative addresses.
1159 make_length_attrs ()
1161 static char *new_names
[] = {"*insn_default_length",
1162 "*insn_variable_length_p",
1163 "*insn_current_length"};
1164 static rtx (*no_address_fn
[]) () = {identity_fn
, zero_fn
, zero_fn
};
1165 static rtx (*address_fn
[]) () = {max_fn
, one_fn
, identity_fn
};
1167 struct attr_desc
*length_attr
, *new_attr
;
1168 struct attr_value
*av
, *new_av
;
1169 struct insn_ent
*ie
, *new_ie
;
1171 /* See if length attribute is defined. If so, it must be numeric. Make
1172 it special so we don't output anything for it. */
1173 length_attr
= find_attr ("length", 0);
1174 if (length_attr
== 0)
1177 if (! length_attr
->is_numeric
)
1178 fatal ("length attribute must be numeric.");
1180 length_attr
->is_special
= 1;
1182 /* Make each new attribute, in turn. */
1183 for (i
= 0; i
< sizeof new_names
/ sizeof new_names
[0]; i
++)
1185 make_internal_attr (new_names
[i
],
1186 substitute_address (length_attr
->default_val
->value
,
1187 no_address_fn
[i
], address_fn
[i
]),
1189 new_attr
= find_attr (new_names
[i
], 0);
1190 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1191 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1193 new_av
= get_attr_value (substitute_address (av
->value
,
1196 new_attr
, ie
->insn_code
);
1197 new_ie
= (struct insn_ent
*) xmalloc (sizeof (struct insn_ent
));
1198 new_ie
->insn_code
= ie
->insn_code
;
1199 new_ie
->insn_index
= ie
->insn_index
;
1200 insert_insn_ent (new_av
, new_ie
);
1205 /* Utility functions called from above routine. */
1218 return make_numeric_value (0);
1225 return make_numeric_value (1);
1232 return make_numeric_value (max_attr_value (exp
));
1235 /* Take a COND expression and see if any of the conditions in it can be
1236 simplified. If any are known true or known false for the particular insn
1237 code, the COND can be further simplified.
1239 Also call ourselves on any COND operations that are values of this COND.
1241 We only do the first replacement found directly and call ourselves
1242 recursively for subsequent replacements. */
1245 simplify_cond (exp
, insn_code
, insn_index
)
1247 int insn_code
, insn_index
;
1254 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1256 newtest
= SIMPLIFY_TEST_EXP (XVECEXP (exp
, 0, i
), insn_code
, insn_index
);
1257 if (newtest
== true_rtx
)
1259 /* Make a new COND with any previous conditions and the value for
1260 this pair as the default value. */
1261 newexp
= rtx_alloc (COND
);
1262 XVEC (newexp
, 0) = rtvec_alloc (i
);
1263 for (j
= 0; j
< i
; j
++)
1264 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
);
1266 XEXP (newexp
, 1) = XVECEXP (exp
, 0, i
+ 1);
1270 else if (newtest
== false_rtx
)
1272 /* Build a new COND without this test. */
1273 newexp
= rtx_alloc (COND
);
1274 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0) - 2);
1275 for (j
= 0; j
< i
; j
++)
1276 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
);
1278 for (j
= i
; j
< XVECLEN (newexp
, 0); j
++)
1279 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
+ 2);
1281 XEXP (newexp
, 1) = XEXP (exp
, 1);
1285 else if (newtest
!= XVECEXP (exp
, 0, i
))
1287 newexp
= rtx_alloc (COND
);
1288 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1289 for (j
= 0; j
< XVECLEN (exp
, 0); j
++)
1290 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
);
1291 XEXP (newexp
, 1) = XEXP (exp
, 1);
1293 XVECEXP (newexp
, 0, i
) = newtest
;
1297 /* See if this value may need simplification. */
1298 if (GET_CODE (XVECEXP (exp
, 0, i
+ 1)) == COND
)
1300 value
= simplify_cond (XVECEXP (exp
, 0, i
+ 1),
1301 insn_code
, insn_index
);
1302 if (value
!= XVECEXP (exp
, 0, i
+ 1))
1304 newexp
= rtx_alloc (COND
);
1305 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1306 for (j
= 0; j
< XVECLEN (exp
, 0); j
++)
1307 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
);
1308 XEXP (newexp
, 1) = XEXP (exp
, 1);
1310 XVECEXP (newexp
, 0, i
+ 1) = value
;
1315 /* If this is the last condition in a COND and our value is the same
1316 as the default value, our test isn't needed. */
1317 if (i
== XVECLEN (exp
, 0) - 2
1318 && rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), XEXP (exp
, 1)))
1320 newexp
= rtx_alloc (COND
);
1321 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0) - 2);
1322 for (j
= 0; j
< i
; j
++)
1323 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
);
1324 XEXP (newexp
, 1) = XEXP (exp
, 1);
1328 /* If this value and the value for the next test are the same, merge the
1330 else if (i
!= XVECLEN (exp
, 0) - 2
1331 && rtx_equal_p (XVECEXP (exp
, 0, i
+ 1),
1332 XVECEXP (exp
, 0, i
+ 3)))
1334 newexp
= rtx_alloc (COND
);
1335 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0) - 2);
1336 for (j
= 0; j
< i
; j
++)
1337 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
);
1339 XVECEXP (newexp
, 0, j
)
1340 = insert_right_side (IOR
, XVECEXP (exp
, 0, i
),
1341 XVECEXP (exp
, 0, i
+ 2),
1342 insn_code
, insn_index
);
1343 XVECEXP (newexp
, 0, j
+ 1) = XVECEXP (exp
, 0, i
+ 1);
1345 for (j
= i
+ 2; j
< XVECLEN (newexp
, 0); j
++)
1346 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
+ 2);
1348 XEXP (newexp
, 1) = XEXP (exp
, 1);
1353 /* See if default value needs simplification. */
1354 if (GET_CODE (XEXP (exp
, 1)) == COND
)
1356 value
= simplify_cond (XEXP (exp
, 1), insn_code
, insn_index
);
1357 if (value
!= XEXP (exp
, 1))
1359 newexp
= rtx_alloc (COND
);
1360 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1361 for (j
= 0; j
< XVECLEN (exp
, 0); j
++)
1362 XVECEXP (newexp
, 0, j
) = XVECEXP (exp
, 0, j
);
1363 XEXP (newexp
, 1) = value
;
1369 else if (XVECLEN (newexp
, 0) == 1)
1370 return XVECEXP (newexp
, 0, 0);
1372 return simplify_cond (newexp
, insn_code
, insn_index
);
1375 /* Remove an insn entry from an attribute value. */
1378 remove_insn_ent (av
, ie
)
1379 struct attr_value
*av
;
1380 struct insn_ent
*ie
;
1382 struct insn_ent
*previe
;
1384 if (av
->first_insn
== ie
)
1385 av
->first_insn
= ie
->next
;
1388 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1390 previe
->next
= ie
->next
;
1394 if (ie
->insn_code
== -1)
1395 av
->has_asm_insn
= 0;
1398 /* Insert an insn entry in an attribute value list. */
1401 insert_insn_ent (av
, ie
)
1402 struct attr_value
*av
;
1403 struct insn_ent
*ie
;
1405 ie
->next
= av
->first_insn
;
1406 av
->first_insn
= ie
;
1408 if (ie
->insn_code
== -1)
1409 av
->has_asm_insn
= 1;
1412 /* This is a utility routine to take an expression that is a tree of either
1413 AND or IOR expressions and insert a new term. The new term will be
1414 inserted at the right side of the first node whose code does not match
1415 the root. A new node will be created with the root's code. Its left
1416 side will be the old right side and its right side will be the new
1419 If the `term' is itself a tree, all its leaves will be inserted. */
1422 insert_right_side (code
, exp
, term
, insn_code
, insn_index
)
1426 int insn_code
, insn_index
;
1430 if (GET_CODE (term
) == code
)
1432 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1433 insn_code
, insn_index
);
1434 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1435 insn_code
, insn_index
);
1440 if (GET_CODE (exp
) == code
)
1442 /* Make a copy of this expression and call recursively. */
1443 newexp
= rtx_alloc (code
);
1444 XEXP (newexp
, 0) = XEXP (exp
, 0);
1445 XEXP (newexp
, 1) = insert_right_side (code
, XEXP (exp
, 1),
1446 term
, insn_code
, insn_index
);
1450 /* Insert the new term. */
1451 newexp
= rtx_alloc (code
);
1452 XEXP (newexp
, 0) = exp
;
1453 XEXP (newexp
, 1) = term
;
1456 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1459 /* If we have an expression which AND's a bunch of
1460 (not (eq_attrq "alternative" "n"))
1461 terms, we may have covered all or all but one of the possible alternatives.
1462 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1464 This routine is passed an expression and either AND or IOR. It returns a
1465 bitmask indicating which alternatives are present. */
1468 compute_alternative_mask (exp
, code
)
1472 if (GET_CODE (exp
) == code
)
1473 return compute_alternative_mask (XEXP (exp
, 0), code
)
1474 | compute_alternative_mask (XEXP (exp
, 1), code
);
1476 else if (code
== AND
&& GET_CODE (exp
) == NOT
1477 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1478 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1479 return 1 << atoi (XSTR (XEXP (exp
, 0), 1));
1481 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1482 && XSTR (exp
, 0) == alternative_name
)
1483 return 1 << atoi (XSTR (exp
, 1));
1489 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1490 attribute with the value represented by that bit. */
1493 make_alternative_compare (mask
)
1501 for (i
= 0; (mask
& (1 << i
)) == 0; i
++)
1504 alternative
= (char *) xmalloc (3);
1505 sprintf (alternative
, "%d", i
);
1507 newexp
= rtx_alloc (EQ_ATTR
);
1508 XSTR (newexp
, 0) = alternative_name
;
1509 XSTR (newexp
, 1) = alternative
;
1510 RTX_UNCHANGING_P (newexp
) = 1;
1515 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1516 of "attr" for this insn code. From that value, we can compute a test
1517 showing when the EQ_ATTR will be true. This routine performs that
1518 computation. If a test condition involves an address, we leave the EQ_ATTR
1519 intact because addresses are only valid for the `length' attribute. */
1522 evaluate_eq_attr (exp
, value
, insn_code
, insn_index
)
1525 int insn_code
, insn_index
;
1532 if (GET_CODE (value
) == CONST_STRING
)
1534 if (! strcmp (XSTR (value
, 0), XSTR (exp
, 1)))
1539 else if (GET_CODE (value
) == COND
)
1541 /* We construct an IOR of all the cases for which the requested attribute
1542 value is present. Since we start with FALSE, if it is not present,
1543 FALSE will be returned.
1545 Each case is the AND of the NOT's of the previous conditions with the
1546 current condition; in the default case the current condition is TRUE.
1548 For each possible COND value, call ourselves recursively.
1550 The extra TRUE and FALSE expressions will be eliminated by another
1551 call to the simplification routine. */
1556 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
1558 right
= insert_right_side (AND
, andexp
,
1559 XVECEXP (value
, 0, i
),
1560 insn_code
, insn_index
);
1561 right
= insert_right_side (AND
, right
,
1562 evaluate_eq_attr (exp
, XVECEXP (value
, 0, i
+ 1),
1563 insn_code
, insn_index
),
1564 insn_code
, insn_index
);
1565 orexp
= insert_right_side (IOR
, orexp
, right
,
1566 insn_code
, insn_index
);
1568 /* Add this condition into the AND expression. */
1569 newexp
= rtx_alloc (NOT
);
1570 XEXP (newexp
, 0) = XVECEXP (value
, 0, i
);
1571 andexp
= insert_right_side (AND
, andexp
, newexp
,
1572 insn_code
, insn_index
);
1575 /* Handle the default case. */
1576 right
= insert_right_side (AND
, andexp
,
1577 evaluate_eq_attr (exp
, XEXP (value
, 1),
1578 insn_code
, insn_index
),
1579 insn_code
, insn_index
);
1580 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
1585 /* If uses an address, must return original expression. */
1588 walk_attr_value (newexp
);
1596 /* This routine is called when an AND of a term with a tree of AND's is
1597 encountered. If the term or its complement is present in the tree, it
1598 can be replaced with TRUE or FALSE, respectively.
1600 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
1601 be true and hence are complementary.
1603 There is one special case: If we see
1604 (and (not (eq_attr "att" "v1"))
1605 (eq_attr "att" "v2"))
1606 this can be replaced by (eq_attr "att" "v2"). To do this we need to
1607 replace the term, not anything in the AND tree. So we pass a pointer to
1611 simplify_and_tree (exp
, pterm
, insn_code
, insn_index
)
1614 int insn_code
, insn_index
;
1619 int left_eliminates_term
, right_eliminates_term
;
1621 if (GET_CODE (exp
) == AND
)
1623 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
1624 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
1625 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
1627 newexp
= rtx_alloc (GET_CODE (exp
));
1628 XEXP (newexp
, 0) = left
;
1629 XEXP (newexp
, 1) = right
;
1631 exp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1635 else if (GET_CODE (exp
) == IOR
)
1637 /* For the IOR case, we do the same as above, except that we can
1638 only eliminate `term' if both sides of the IOR would do so. */
1640 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
1641 left_eliminates_term
= (temp
== true_rtx
);
1644 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
1645 right_eliminates_term
= (temp
== true_rtx
);
1647 if (left_eliminates_term
&& right_eliminates_term
)
1650 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
1652 newexp
= rtx_alloc (GET_CODE (exp
));
1653 XEXP (newexp
, 0) = left
;
1654 XEXP (newexp
, 1) = right
;
1656 exp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1660 /* Check for simplifications. Do some extra checking here since this
1661 routine is called so many times. */
1666 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
1669 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
1672 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
1674 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
1677 if (! strcmp (XSTR (exp
, 1), XSTR (*pterm
, 1)))
1683 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
1684 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
1686 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
1689 if (! strcmp (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
1695 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
1696 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
1698 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
1701 if (! strcmp (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
1707 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
1709 if (rtx_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
1713 else if (GET_CODE (exp
) == NOT
)
1715 if (rtx_equal_p (XEXP (exp
, 0), *pterm
))
1719 else if (GET_CODE (*pterm
) == NOT
)
1721 if (rtx_equal_p (XEXP (*pterm
, 0), exp
))
1725 else if (rtx_equal_p (exp
, *pterm
))
1731 /* Similiar to `simplify_and_tree', but for IOR trees. */
1734 simplify_or_tree (exp
, pterm
, insn_code
, insn_index
)
1737 int insn_code
, insn_index
;
1742 int left_eliminates_term
, right_eliminates_term
;
1744 if (GET_CODE (exp
) == IOR
)
1746 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
1747 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
1748 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
1750 newexp
= rtx_alloc (GET_CODE (exp
));
1751 XEXP (newexp
, 0) = left
;
1752 XEXP (newexp
, 1) = right
;
1754 exp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1758 else if (GET_CODE (exp
) == AND
)
1760 /* For the AND case, we do the same as above, except that we can
1761 only eliminate `term' if both sides of the AND would do so. */
1763 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
1764 left_eliminates_term
= (temp
== false_rtx
);
1767 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
1768 right_eliminates_term
= (temp
== false_rtx
);
1770 if (left_eliminates_term
&& right_eliminates_term
)
1773 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
1775 newexp
= rtx_alloc (GET_CODE (exp
));
1776 XEXP (newexp
, 0) = left
;
1777 XEXP (newexp
, 1) = right
;
1779 exp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1783 if (rtx_equal_p (exp
, *pterm
))
1786 else if (GET_CODE (exp
) == NOT
&& rtx_equal_p (XEXP (exp
, 0), *pterm
))
1789 else if (GET_CODE (*pterm
) == NOT
&& rtx_equal_p (XEXP (*pterm
, 0), exp
))
1792 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
1793 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1794 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
1797 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
1798 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
1799 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
1805 /* Given an expression, see if it can be simplified for a particular insn
1806 code based on the values of other attributes being tested. This can
1807 eliminate nested get_attr_... calls.
1809 Note that if an endless recursion is specified in the patterns, the
1810 optimization will loop. However, it will do so in precisely the cases where
1811 an infinite recursion loop could occur during compilation. It's better that
1815 simplify_test_exp (exp
, insn_code
, insn_index
)
1817 int insn_code
, insn_index
;
1820 struct attr_desc
*attr
;
1821 struct attr_value
*av
;
1822 struct insn_ent
*ie
;
1826 switch (GET_CODE (exp
))
1829 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
1830 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
1832 /* If either side is an IOR and we have (eq_attr "alternative" ..")
1833 present on both sides, apply the distributive law since this will
1834 yield simplications. */
1835 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
1836 && compute_alternative_mask (left
, IOR
)
1837 && compute_alternative_mask (right
, IOR
))
1839 if (GET_CODE (left
) == IOR
)
1846 newexp
= rtx_alloc (IOR
);
1847 XEXP (newexp
, 0) = rtx_alloc (AND
);
1848 XEXP (newexp
, 1) = rtx_alloc (AND
);
1849 XEXP (XEXP (newexp
, 0), 0) = XEXP (XEXP (newexp
, 1), 0) = left
;
1850 XEXP (XEXP (newexp
, 0), 1) = XEXP (right
, 0);
1851 XEXP (XEXP (newexp
, 1), 1) = XEXP (right
, 1);
1853 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1856 /* Try with the term on both sides. */
1857 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
1858 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
1859 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
1861 if (left
== false_rtx
|| right
== false_rtx
)
1863 else if (left
== true_rtx
)
1865 else if (right
== true_rtx
)
1868 /* See if all or all but one of the insn's alternatives are specified
1869 in this tree. Optimize if so. */
1871 else if (insn_code
>= 0
1872 && (GET_CODE (left
) == AND
1873 || (GET_CODE (left
) == NOT
1874 && GET_CODE (XEXP (left
, 0)) == EQ_ATTR
1875 && XSTR (XEXP (left
, 0), 0) == alternative_name
)
1876 || GET_CODE (right
) == AND
1877 || (GET_CODE (right
) == NOT
1878 && GET_CODE (XEXP (right
, 0)) == EQ_ATTR
1879 && XSTR (XEXP (right
, 0), 0) == alternative_name
)))
1881 i
= compute_alternative_mask (exp
, AND
);
1882 if (i
& ~insn_alternatives
[insn_code
])
1883 fatal ("Illegal alternative specified for pattern number %d",
1886 /* If all alternatives are excluded, this is false. */
1887 i
^= insn_alternatives
[insn_code
];
1890 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
1892 /* If just one excluded, AND a comparison with that one to the
1893 front of the tree. The others will be eliminated by
1894 optimization. We do not want to do this if the insn has one
1895 alternative and we have tested none of them! */
1896 left
= make_alternative_compare (i
);
1897 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
1898 newexp
= rtx_alloc (AND
);
1899 XEXP (newexp
, 0) = left
;
1900 XEXP (newexp
, 1) = right
;
1902 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1906 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
1908 newexp
= rtx_alloc (AND
);
1909 XEXP (newexp
, 0) = left
;
1910 XEXP (newexp
, 1) = right
;
1911 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1916 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
1917 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
1919 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
1920 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
1921 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
1923 if (right
== true_rtx
|| left
== true_rtx
)
1925 else if (left
== false_rtx
)
1927 else if (right
== false_rtx
)
1930 /* Test for simple cases where the distributive law is useful. I.e.,
1931 convert (ior (and (x) (y))
1937 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
1938 && rtx_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
1940 newexp
= rtx_alloc (IOR
);
1941 XEXP (newexp
, 0) = XEXP (left
, 1);
1942 XEXP (newexp
, 1) = XEXP (right
, 1);
1944 left
= XEXP (left
, 0);
1946 newexp
= rtx_alloc (AND
);
1947 XEXP (newexp
, 0) = left
;
1948 XEXP (newexp
, 1) = right
;
1949 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1952 /* See if all or all but one of the insn's alternatives are specified
1953 in this tree. Optimize if so. */
1955 else if (insn_code
>= 0
1956 && (GET_CODE (left
) == IOR
1957 || (GET_CODE (left
) == EQ_ATTR
1958 && XSTR (left
, 0) == alternative_name
)
1959 || GET_CODE (right
) == IOR
1960 || (GET_CODE (right
) == EQ_ATTR
1961 && XSTR (right
, 0) == alternative_name
)))
1963 i
= compute_alternative_mask (exp
, IOR
);
1964 if (i
& ~insn_alternatives
[insn_code
])
1965 fatal ("Illegal alternative specified for pattern number %d",
1968 /* If all alternatives are included, this is true. */
1969 i
^= insn_alternatives
[insn_code
];
1972 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
1974 /* If just one excluded, IOR a comparison with that one to the
1975 front of the tree. The others will be eliminated by
1976 optimization. We do not want to do this if the insn has one
1977 alternative and we have tested none of them! */
1978 left
= make_alternative_compare (i
);
1979 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
1980 newexp
= rtx_alloc (IOR
);
1981 XEXP (newexp
, 0) = rtx_alloc (NOT
);
1982 XEXP (XEXP (newexp
, 0), 0) = left
;
1983 XEXP (newexp
, 1) = right
;
1985 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1989 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
1991 newexp
= rtx_alloc (IOR
);
1992 XEXP (newexp
, 0) = left
;
1993 XEXP (newexp
, 1) = right
;
1994 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
1999 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2000 if (GET_CODE (left
) == NOT
)
2001 return XEXP (left
, 0);
2003 if (left
== false_rtx
)
2005 else if (left
== true_rtx
)
2008 /* Try to apply De`Morgan's laws. */
2009 else if (GET_CODE (left
) == IOR
)
2011 newexp
= rtx_alloc (AND
);
2012 XEXP (newexp
, 0) = rtx_alloc (NOT
);
2013 XEXP (XEXP (newexp
, 0), 0) = XEXP (left
, 0);
2014 XEXP (newexp
, 1) = rtx_alloc (NOT
);
2015 XEXP (XEXP (newexp
, 1), 0) = XEXP (left
, 1);
2017 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2019 else if (GET_CODE (left
) == AND
)
2021 newexp
= rtx_alloc (IOR
);
2022 XEXP (newexp
, 0) = rtx_alloc (NOT
);
2023 XEXP (XEXP (newexp
, 0), 0) = XEXP (left
, 0);
2024 XEXP (newexp
, 1) = rtx_alloc (NOT
);
2025 XEXP (XEXP (newexp
, 1), 0) = XEXP (left
, 1);
2027 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2029 else if (left
!= XEXP (exp
, 0))
2031 newexp
= rtx_alloc (NOT
);
2032 XEXP (newexp
, 0) = left
;
2037 /* Look at the value for this insn code in the specified attribute.
2038 We normally can replace this comparison with the condition that
2039 would give this insn the values being tested for. */
2040 if (XSTR (exp
, 0) != alternative_name
2041 && (attr
= find_attr (XSTR (exp
, 0), 0)) != NULL
)
2042 for (av
= attr
->first_value
; av
; av
= av
->next
)
2043 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2044 if (ie
->insn_code
== insn_code
)
2045 return evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2048 /* We have already simplified this expression. Simplifying it again
2049 won't buy anything unless we weren't given a valid insn code
2050 to process (i.e., we are canonicalizing something.). */
2051 if (insn_code
!= -2)
2052 RTX_UNCHANGING_P (newexp
) = 1;
2057 /* Optimize the attribute lists by seeing if we can determine conditional
2058 values from the known values of other attributes. This will save subroutine
2059 calls during the compilation. */
2064 struct attr_desc
*attr
;
2065 struct attr_value
*av
;
2066 struct insn_ent
*ie
, *nextie
;
2068 int something_changed
= 1;
2070 /* Loop until nothing changes for one iteration. */
2071 while (something_changed
)
2073 something_changed
= 0;
2074 for (attr
= attrs
; attr
; attr
= attr
->next
)
2075 for (av
= attr
->first_value
; av
; av
= av
->next
)
2076 for (ie
= av
->first_insn
; ie
; ie
= nextie
)
2079 if (GET_CODE (av
->value
) != COND
)
2082 newexp
= simplify_cond (av
->value
, ie
->insn_code
,
2084 if (newexp
!= av
->value
)
2086 remove_insn_ent (av
, ie
);
2087 insert_insn_ent (get_attr_value (newexp
, attr
,
2088 ie
->insn_code
), ie
);
2089 something_changed
= 1;
2095 /* Create table entries for DEFINE_ATTR. */
2101 struct attr_desc
*attr
;
2102 struct attr_value
*av
;
2106 /* Make a new attribute structure. Check for duplicate by looking at
2107 attr->default_val, since it is initialized by this routine. */
2108 attr
= find_attr (XSTR (exp
, 0), 1);
2109 if (attr
->default_val
)
2110 fatal ("Duplicate definition for `%s' attribute", attr
->name
);
2112 if (*XSTR (exp
, 1) == '\0')
2113 attr
->is_numeric
= 1;
2116 name_ptr
= XSTR (exp
, 1);
2117 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
2119 av
= (struct attr_value
*) xmalloc (sizeof (struct attr_value
));
2120 av
->value
= rtx_alloc (CONST_STRING
);
2121 XSTR (av
->value
, 0) = p
;
2122 av
->next
= attr
->first_value
;
2123 attr
->first_value
= av
;
2124 av
->first_insn
= NULL
;
2126 av
->has_asm_insn
= 0;
2130 if (! strcmp (attr
->name
, "length") && ! attr
->is_numeric
)
2131 fatal ("`length' attribute must take numeric values");
2133 /* Set up the default value. */
2134 check_attr_value (XEXP (exp
, 2), attr
);
2135 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
2138 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2139 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2140 number of alternatives as this should be checked elsewhere. */
2143 count_alternatives (exp
)
2149 if (GET_CODE (exp
) == MATCH_OPERAND
)
2150 return n_comma_elts (XSTR (exp
, 2));
2152 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
2153 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
2158 n
= count_alternatives (XEXP (exp
, i
));
2165 if (XVEC (exp
, i
) != NULL
)
2166 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2168 n
= count_alternatives (XVECEXP (exp
, i
, j
));
2177 /* Returns non-zero if the given expression contains an EQ_ATTR with the
2178 `alternative' attribute. */
2181 compares_alternatives_p (exp
)
2187 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
2190 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
2191 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
2196 if (compares_alternatives_p (XEXP (exp
, i
)))
2201 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2202 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
2210 /* Returns non-zero is INNER is contained in EXP. */
2213 contained_in_p (inner
, exp
)
2220 if (rtx_equal_p (inner
, exp
))
2223 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
2224 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
2229 if (contained_in_p (inner
, XEXP (exp
, i
)))
2234 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2235 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
2243 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
2249 struct insn_def
*id
;
2251 id
= (struct insn_def
*) xmalloc (sizeof (struct insn_def
));
2256 switch (GET_CODE (exp
))
2259 id
->insn_code
= insn_code_number
++;
2260 id
->insn_index
= insn_index_number
++;
2261 id
->num_alternatives
= count_alternatives (exp
);
2262 if (id
->num_alternatives
== 0)
2263 id
->num_alternatives
= 1;
2267 case DEFINE_PEEPHOLE
:
2268 id
->insn_code
= insn_code_number
++;
2269 id
->insn_index
= insn_index_number
++;
2270 id
->num_alternatives
= count_alternatives (exp
);
2271 if (id
->num_alternatives
== 0)
2272 id
->num_alternatives
= 1;
2276 case DEFINE_ASM_ATTRIBUTES
:
2278 id
->insn_index
= -1;
2279 id
->num_alternatives
= 1;
2281 got_define_asm_attributes
= 1;
2286 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
2287 true or annul false is specified, and make a `struct delay_desc'. */
2293 struct delay_desc
*delay
;
2296 if (XVECLEN (def
, 1) % 3 != 0)
2297 fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
2299 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
2301 if (XVECEXP (def
, 1, i
+ 1))
2302 have_annul_true
= 1;
2303 if (XVECEXP (def
, 1, i
+ 2))
2304 have_annul_false
= 1;
2307 delay
= (struct delay_desc
*) xmalloc (sizeof (struct delay_desc
));
2309 delay
->num
= ++num_delays
;
2310 delay
->next
= delays
;
2314 /* Process a DEFINE_FUNCTION_UNIT.
2316 This gives information about a function unit contained in the CPU.
2317 We fill in a `struct function_unit_op' and a `struct function_unit'
2318 with information used later by `expand_unit'. */
2324 struct function_unit
*unit
;
2325 struct function_unit_op
*op
;
2327 /* See if we have already seen this function unit. If so, check that
2328 the multipicity and simultaneity values are the same. If not, make
2329 a structure for this function unit. */
2330 for (unit
= units
; unit
; unit
= unit
->next
)
2331 if (! strcmp (unit
->name
, XSTR (def
, 0)))
2333 if (unit
->multiplicity
!= XINT (def
, 1)
2334 || unit
->simultaneity
!= XINT (def
, 2))
2335 fatal ("Differing specifications given for `%s' function unit.",
2342 unit
= (struct function_unit
*) xmalloc (sizeof (struct function_unit
));
2343 unit
->name
= XSTR (def
, 0);
2344 unit
->multiplicity
= XINT (def
, 1);
2345 unit
->simultaneity
= XINT (def
, 2);
2346 unit
->num
= num_units
++;
2347 unit
->num_opclasses
= 0;
2348 unit
->condexp
= false_rtx
;
2354 /* Make a new operation class structure entry and initialize it. */
2355 op
= (struct function_unit_op
*) xmalloc (sizeof (struct function_unit_op
));
2356 op
->condexp
= XEXP (def
, 3);
2357 op
->num
= unit
->num_opclasses
++;
2358 op
->ready
= XINT (def
, 4);
2359 op
->next
= unit
->ops
;
2362 /* Set our busy expression based on whether or not an optional conflict
2363 vector was specified. */
2366 /* Compute the IOR of all the specified expressions. */
2367 rtx orexp
= false_rtx
;
2370 for (i
= 0; i
< XVECLEN (def
, 6); i
++)
2371 orexp
= insert_right_side (IOR
, orexp
, XVECEXP (def
, 6, i
), -2);
2373 op
->busyexp
= rtx_alloc (IF_THEN_ELSE
);
2374 XEXP (op
->busyexp
, 0) = orexp
;
2375 XEXP (op
->busyexp
, 1) = make_numeric_value (XINT (def
, 5));
2376 XEXP (op
->busyexp
, 2) = make_numeric_value (0);
2379 op
->busyexp
= make_numeric_value (XINT (def
, 5));
2381 /* Merge our conditional into that of the function unit so we can determine
2382 which insns are used by the function unit. */
2383 unit
->condexp
= insert_right_side (IOR
, unit
->condexp
, op
->condexp
, -2);
2386 /* Given a piece of RTX, print a C expression to test it's truth value.
2387 We use AND and IOR both for logical and bit-wise operations, so
2388 interpret them as logical unless they are inside a comparison expression.
2389 The second operand of this function will be non-zero in that case. */
2392 write_test_expr (exp
, in_comparison
)
2396 int comparison_operator
= 0;
2398 struct attr_desc
*attr
;
2400 /* In order not to worry about operator precedence, surround our part of
2401 the expression with parentheses. */
2404 code
= GET_CODE (exp
);
2407 /* Binary operators. */
2409 case GE
: case GT
: case GEU
: case GTU
:
2410 case LE
: case LT
: case LEU
: case LTU
:
2411 comparison_operator
= 1;
2413 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
2414 case AND
: case IOR
: case XOR
:
2415 case LSHIFT
: case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
2416 write_test_expr (XEXP (exp
, 0), in_comparison
|| comparison_operator
);
2432 printf (" >= (unsigned) ");
2435 printf (" > (unsigned) ");
2444 printf (" <= (unsigned) ");
2447 printf (" < (unsigned) ");
2489 write_test_expr (XEXP (exp
, 1), in_comparison
|| comparison_operator
);
2493 /* Special-case (not (eq_attrq "alternative" "x")) */
2494 if (! in_comparison
&& GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2495 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
2497 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
2501 /* Otherwise, fall through to normal unary operator. */
2503 /* Unary operators. */
2521 write_test_expr (XEXP (exp
, 0), in_comparison
);
2524 /* Comparison test of an attribute with a value. Most of these will
2525 have been removed by optimization. Handle "alternative"
2526 specially and give error if EQ_ATTR present inside a comparison. */
2529 fatal ("EQ_ATTR not valid inside comparison");
2531 if (XSTR (exp
, 0) == alternative_name
)
2533 printf ("which_alternative == %s", XSTR (exp
, 1));
2537 attr
= find_attr (XSTR (exp
, 0), 0);
2538 if (! attr
) abort ();
2539 printf ("get_attr_%s (insn) == ", attr
->name
);
2540 write_attr_valueq (attr
, XSTR (exp
, 1));
2543 /* See if an operand matches a predicate. */
2545 /* If only a mode is given, just ensure the mode matches the operand.
2546 If neither a mode nor predicate is given, error. */
2547 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
2549 if (GET_MODE (exp
) == VOIDmode
)
2550 fatal ("Null MATCH_OPERAND specified as test");
2552 printf ("GET_MODE (operands[%d]) == %smode",
2553 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
2556 printf ("%s (operands[%d], %smode)",
2557 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
2560 /* Constant integer. */
2562 printf ("%d", XINT (exp
, 0));
2565 /* A random C expression. */
2567 printf ("%s", XSTR (exp
, 0));
2570 /* The address of the branch target. */
2572 printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
2575 /* The address of the current insn. It would be more consistent with
2576 other usage to make this the address of the NEXT insn, but this gets
2577 too confusing because of the ambiguity regarding the length of the
2580 printf ("insn_current_address");
2584 fatal ("bad RTX code `%s' in attribute calculation\n",
2585 GET_RTX_NAME (code
));
2591 /* Given an attribute value, return the maximum CONST_STRING argument
2592 encountered. It is assumed that they are all numeric. */
2595 max_attr_value (exp
)
2598 int current_max
= 0;
2602 if (GET_CODE (exp
) == CONST_STRING
)
2603 return atoi (XSTR (exp
, 0));
2605 else if (GET_CODE (exp
) == COND
)
2607 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
2609 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1));
2610 if (n
> current_max
)
2614 n
= max_attr_value (XEXP (exp
, 1));
2615 if (n
> current_max
)
2625 /* Scan an attribute value, possibly a conditional, and record what actions
2626 will be required to do any conditional tests in it.
2629 `must_extract' if we need to extract the insn operands
2630 `must_constrain' if we must compute `which_alternative'
2631 `address_used' if an address expression was used
2635 walk_attr_value (exp
)
2645 code
= GET_CODE (exp
);
2649 /* Since this is an arbitrary expression, it can look at anything. */
2650 must_extract
= must_constrain
= 1;
2658 if (XSTR (exp
, 0) == alternative_name
)
2659 must_extract
= must_constrain
= 1;
2668 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
2673 walk_attr_value (XEXP (exp
, i
));
2677 if (XVEC (exp
, i
) != NULL
)
2678 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2679 walk_attr_value (XVECEXP (exp
, i
, j
));
2684 /* Write out a function to obtain the attribute for a given INSN. */
2687 write_attr_get (attr
)
2688 struct attr_desc
*attr
;
2690 struct attr_value
*av
, *common_av
;
2692 /* Find the most used attribute value. Handle that as the `default' of the
2693 switch we will generate. */
2694 common_av
= find_most_used (attr
);
2696 /* Write out start of function, then all values with explicit `case' lines,
2697 then a `default', then the value with the most uses. */
2698 if (attr
->is_numeric
)
2701 printf ("enum attr_%s\n", attr
->name
);
2703 /* If the attribute name starts with a star, the remainder is the name of
2704 the subroutine to use, instead of `get_attr_...'. */
2705 if (attr
->name
[0] == '*')
2706 printf ("%s (insn)\n", &attr
->name
[1]);
2708 printf ("get_attr_%s (insn)\n", attr
->name
);
2709 printf (" rtx insn;\n");
2711 printf (" switch (recog_memoized (insn))\n");
2714 for (av
= attr
->first_value
; av
; av
= av
->next
)
2715 if (av
!= common_av
)
2716 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
2718 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
2719 printf (" }\n}\n\n");
2722 /* Given an AND tree of known true terms (because we are inside an `if' with
2723 that as the condition or are in an `else' clause) and an expression,
2724 replace any known true terms with TRUE. Use `simplify_and_tree' to do
2725 the bulk of the work. */
2728 eliminate_known_true (known_true
, exp
, insn_code
, insn_index
)
2731 int insn_code
, insn_index
;
2735 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
2737 if (GET_CODE (known_true
) == AND
)
2739 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
2740 insn_code
, insn_index
);
2741 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
2742 insn_code
, insn_index
);
2747 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
2753 /* Write out a series of tests and assignment statements to perform tests and
2754 sets of an attribute value. We are passed an indentation amount and prefix
2755 and suffix strings to write around each attribute value (e.g., "return"
2759 write_attr_set (attr
, indent
, value
, prefix
, suffix
, known_true
,
2760 insn_code
, insn_index
)
2761 struct attr_desc
*attr
;
2767 int insn_code
, insn_index
;
2769 if (GET_CODE (value
) == CONST_STRING
)
2771 write_indent (indent
);
2772 printf ("%s ", prefix
);
2773 write_attr_value (attr
, value
);
2774 printf ("%s\n", suffix
);
2776 else if (GET_CODE (value
) == COND
)
2778 /* Assume the default value will be the default of the COND unless we
2779 find an always true expression. */
2780 rtx default_val
= XEXP (value
, 1);
2781 rtx our_known_true
= known_true
;
2786 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2791 testexp
= eliminate_known_true (our_known_true
,
2792 XVECEXP (value
, 0, i
),
2793 insn_code
, insn_index
);
2794 newexp
= rtx_alloc (NOT
);
2795 XEXP (newexp
, 0) = testexp
;
2796 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
2797 insn_code
, insn_index
);
2799 /* If the test expression is always true or if the next `known_true'
2800 expression is always false, this is the last case, so break
2801 out and let this value be the `else' case. */
2802 if (testexp
== true_rtx
|| newexp
== false_rtx
)
2804 default_val
= XVECEXP (value
, 0, i
+ 1);
2808 /* Compute the expression to pass to our recursive call as being
2810 inner_true
= insert_right_side (AND
, our_known_true
,
2811 testexp
, insn_code
, insn_index
);
2813 /* If this is always false, skip it. */
2814 if (inner_true
== false_rtx
)
2817 write_indent (indent
);
2818 printf ("%sif ", first_if
? "" : "else ");
2820 write_test_expr (testexp
, 0);
2822 write_indent (indent
+ 2);
2825 write_attr_set (attr
, indent
+ 4,
2826 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
2827 inner_true
, insn_code
, insn_index
);
2828 write_indent (indent
+ 2);
2830 our_known_true
= newexp
;
2835 write_indent (indent
);
2837 write_indent (indent
+ 2);
2841 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
2842 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
2846 write_indent (indent
+ 2);
2854 /* Write out the computation for one attribute value. */
2857 write_attr_case (attr
, av
, write_case_lines
, prefix
, suffix
, indent
, known_true
)
2858 struct attr_desc
*attr
;
2859 struct attr_value
*av
;
2860 int write_case_lines
;
2861 char *prefix
, *suffix
;
2865 struct insn_ent
*ie
;
2867 if (av
->num_insns
== 0)
2870 if (av
->has_asm_insn
)
2872 write_indent (indent
);
2873 printf ("case -1:\n");
2874 write_indent (indent
+ 2);
2875 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
2876 write_indent (indent
+ 2);
2877 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
2878 write_indent (indent
+ 2);
2879 printf (" fatal_insn_not_found (insn);\n");
2882 if (write_case_lines
)
2884 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2885 if (ie
->insn_code
!= -1)
2887 write_indent (indent
);
2888 printf ("case %d:\n", ie
->insn_code
);
2893 write_indent (indent
);
2894 printf ("default:\n");
2897 /* See what we have to do to handle output this value. */
2898 must_extract
= must_constrain
= address_used
= 0;
2899 walk_attr_value (av
->value
);
2903 write_indent (indent
+ 2);
2904 printf ("insn_extract (insn);\n");
2909 #ifdef REGISTER_CONSTRAINTS
2910 write_indent (indent
+ 2);
2911 printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
2912 write_indent (indent
+ 2);
2913 printf (" fatal_insn_not_found (insn);\n");
2917 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
2918 known_true
, av
->first_insn
->insn_code
,
2919 av
->first_insn
->insn_index
);
2921 if (strncmp (prefix
, "return", 6))
2923 write_indent (indent
+ 2);
2924 printf ("break;\n");
2929 /* Utilities to write names in various forms. */
2932 write_attr_valueq (attr
, s
)
2933 struct attr_desc
*attr
;
2936 if (attr
->is_numeric
)
2940 write_upcase (attr
->name
);
2947 write_attr_value (attr
, value
)
2948 struct attr_desc
*attr
;
2951 if (GET_CODE (value
) != CONST_STRING
)
2954 write_attr_valueq (attr
, XSTR (value
, 0));
2962 if (*str
< 'a' || *str
> 'z')
2963 printf ("%c", *str
++);
2965 printf ("%c", *str
++ - 'a' + 'A');
2969 write_indent (indent
)
2972 for (; indent
> 8; indent
-= 8)
2975 for (; indent
; indent
--)
2979 /* Write a subroutine that is given an insn that requires a delay slot, a
2980 delay slot ordinal, and a candidate insn. It returns non-zero if the
2981 candidate can be placed in the specified delay slot of the insn.
2983 We can write as many as three subroutines. `eligible_for_delay'
2984 handles normal delay slots, `eligible_for_annul_true' indicates that
2985 the specified insn can be annulled if the branch is true, and likewise
2986 for `eligible_for_annul_false'.
2988 KIND is a string distingushing these three cases ("delay", "annul_true",
2989 or "annul_false"). */
2992 write_eligible_delay (kind
)
2995 struct delay_desc
*delay
;
2998 struct attr_desc
*attr
;
2999 struct attr_value
*av
, *common_av
;
3002 /* Compute the maximum number of delay slots required. We use the delay
3003 ordinal times this number plus one, plus the slot number as an index into
3004 the appropriate predicate to test. */
3006 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
3007 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
3008 max_slots
= XVECLEN (delay
->def
, 1) / 3;
3010 /* Write function prelude. */
3013 printf ("eligible_for_%s (delay_insn, slot, candidate_insn)\n", kind
);
3014 printf (" rtx delay_insn;\n");
3015 printf (" int slot;\n");
3016 printf (" rtx candidate_insn;\n");
3018 printf (" rtx insn;\n");
3020 printf (" if (slot >= %d)\n", max_slots
);
3021 printf (" abort ();\n");
3024 /* If more than one delay type, find out which type the delay insn is. */
3028 sprintf (str
, "*delay_type", kind
);
3029 attr
= find_attr (str
, 0);
3030 if (! attr
) abort ();
3031 common_av
= find_most_used (attr
);
3033 printf (" insn = delay_insn;\n");
3034 printf (" switch (recog_memoized (insn))\n");
3037 sprintf (str
, " * %d;\n break;", max_slots
);
3038 for (av
= attr
->first_value
; av
; av
= av
->next
)
3039 if (av
!= common_av
)
3040 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
3042 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
3045 /* Ensure matched. Otherwise, shouldn't have been called. */
3046 printf (" if (slot < %d)\n", max_slots
);
3047 printf (" abort ();\n\n");
3050 /* If just one type of delay slot, write simple switch. */
3051 if (num_delays
== 1 && max_slots
== 1)
3053 printf (" insn = candidate_insn;\n");
3054 printf (" switch (recog_memoized (insn))\n");
3057 attr
= find_attr ("*delay_1_0", 0);
3058 if (! attr
) abort ();
3059 common_av
= find_most_used (attr
);
3061 for (av
= attr
->first_value
; av
; av
= av
->next
)
3062 if (av
!= common_av
)
3063 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3065 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3071 /* Write a nested CASE. The first indicates which condition we need to
3072 test, and the inner CASE tests the condition. */
3073 printf (" insn = candidate_insn;\n");
3074 printf (" switch (slot)\n");
3077 for (delay
= delays
; delay
; delay
= delay
->next
)
3078 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
3080 printf (" case %d:\n",
3081 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
3082 printf (" switch (recog_memoized (insn))\n");
3085 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
3086 attr
= find_attr (str
, 0);
3087 if (! attr
) abort ();
3088 common_av
= find_most_used (attr
);
3090 for (av
= attr
->first_value
; av
; av
= av
->next
)
3091 if (av
!= common_av
)
3092 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
3094 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
3098 printf (" default:\n");
3099 printf (" abort ();\n");
3106 /* Write routines to compute conflict cost for function units. Then write a
3107 table describing the available function units. */
3110 write_function_unit_info ()
3112 struct function_unit
*unit
;
3113 struct attr_desc
*case_attr
, *attr
;
3114 struct attr_value
*av
, *common_av
;
3120 /* Write out conflict routines for function units. Don't bother writing
3121 one if there is only one busy value. */
3123 for (unit
= units
; unit
; unit
= unit
->next
)
3125 /* See if only one case exists and if there is a constant value for
3126 that case. If so, we don't need a function. */
3127 str
= (char *) xmalloc (strlen (unit
->name
) + 10);
3128 sprintf (str
, "*%s_cases", unit
->name
);
3129 attr
= find_attr (str
, 0);
3130 if (! attr
) abort ();
3131 value
= find_single_value (attr
);
3132 if (value
&& GET_CODE (value
) == CONST_STRING
)
3134 sprintf (str
, "*%s_case_%s", unit
->name
, XSTR (value
, 0));
3135 attr
= find_attr (str
, 0);
3136 if (! attr
) abort ();
3137 value
= find_single_value (attr
);
3138 if (value
&& GET_CODE (value
) == CONST_STRING
)
3140 unit
->needs_conflict_function
= 0;
3141 unit
->default_cost
= value
;
3146 /* The function first computes the case from the candidate insn. */
3147 unit
->needs_conflict_function
= 1;
3148 unit
->default_cost
= make_numeric_value (0);
3150 printf ("static int\n");
3151 printf ("%s_unit_conflict_cost (executing_insn, candidate_insn)\n",
3153 printf (" rtx executing_insn;\n");
3154 printf (" rtx candidate_insn;\n");
3156 printf (" rtx insn;\n");
3157 printf (" int casenum;\n\n");
3158 printf (" insn = candidate_insn;\n");
3159 printf (" switch (recog_memoized (insn))\n");
3162 /* Write the `switch' statement to get the case value. */
3163 sprintf (str
, "*%s_cases", unit
->name
);
3164 case_attr
= find_attr (str
, 0);
3165 if (! case_attr
) abort ();
3166 common_av
= find_most_used (case_attr
);
3168 for (av
= case_attr
->first_value
; av
; av
= av
->next
)
3169 if (av
!= common_av
)
3170 write_attr_case (case_attr
, av
, 1,
3171 "casenum =", ";", 4, unit
->condexp
);
3173 write_attr_case (case_attr
, common_av
, 0,
3174 "casenum =", ";", 4, unit
->condexp
);
3177 /* Now write an outer switch statement on each case. Then write
3178 the tests on the executing function within each. */
3179 printf (" insn = executing_insn;\n");
3180 printf (" switch (casenum)\n");
3183 for (i
= 0; i
< unit
->num_opclasses
; i
++)
3185 /* Ensure using this case. */
3187 for (av
= case_attr
->first_value
; av
; av
= av
->next
)
3189 && contained_in_p (make_numeric_value (i
), av
->value
))
3195 printf (" case %d:\n", i
);
3196 sprintf (str
, "*%s_case_%d", unit
->name
, i
);
3197 attr
= find_attr (str
, 0);
3198 if (! attr
) abort ();
3200 /* If single value, just write it. */
3201 value
= find_single_value (attr
);
3203 write_attr_set (attr
, 6, value
, "return", ";\n", true_rtx
, -2);
3206 common_av
= find_most_used (attr
);
3207 printf (" switch (recog_memoized (insn))\n");
3210 for (av
= attr
->first_value
; av
; av
= av
->next
)
3211 if (av
!= common_av
)
3212 write_attr_case (attr
, av
, 1,
3213 "return", ";", 8, unit
->condexp
);
3215 write_attr_case (attr
, common_av
, 0,
3216 "return", ";", 8, unit
->condexp
);
3221 printf (" }\n}\n\n");
3224 /* Now that all functions have been written, write the table describing
3225 the function units. The name is included for documenation purposes
3228 printf ("struct function_unit_desc function_units[] = {\n");
3230 for (unit
= units
; unit
; unit
= unit
->next
)
3232 printf (" {\"%s\", %d, %d, %d, %s, %s_unit_ready_cost, ",
3233 unit
->name
, 1 << unit
->num
, unit
->multiplicity
,
3234 unit
->simultaneity
, XSTR (unit
->default_cost
, 0), unit
->name
);
3236 if (unit
->needs_conflict_function
)
3237 printf ("%s_unit_conflict_cost", unit
->name
);
3247 /* This page contains miscellaneous utility routines. */
3249 /* Given a string, return the number of comma-separated elements in it.
3250 Return 0 for the null string. */
3261 for (n
= 1; *s
; s
++)
3268 /* Given a pointer to a (char *), return a malloc'ed string containing the
3269 next comma-separated element. Advance the pointer to after the string
3270 scanned, or the end-of-string. Return NULL if at end of string. */
3273 next_comma_elt (pstr
)
3282 /* Find end of string to compute length. */
3283 for (p
= *pstr
; *p
!= ',' && *p
!= '\0'; p
++)
3286 out_str
= (char *) xmalloc (p
- *pstr
+ 1);
3287 for (p
= out_str
; **pstr
!= ',' && **pstr
!= '\0'; (*pstr
)++)
3297 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
3298 is non-zero, build a new attribute, if one does not exist. */
3300 static struct attr_desc
*
3301 find_attr (name
, create
)
3305 struct attr_desc
*attr
;
3308 /* Before we resort to using `strcmp', see if the string address matches
3309 anywhere. In most cases, it should have been canonicalized to do so. */
3310 if (name
== alternative_name
)
3313 for (attr
= attrs
; attr
; attr
= attr
->next
)
3314 if (name
== attr
->name
)
3317 /* Otherwise, do it the slow way. */
3318 for (attr
= attrs
; attr
; attr
= attr
->next
)
3319 if (! strcmp (name
, attr
->name
))
3325 new_name
= (char *) xmalloc (strlen (name
) + 1);
3326 strcpy (new_name
, name
);
3328 attr
= (struct attr_desc
*) xmalloc (sizeof (struct attr_desc
));
3329 attr
->name
= new_name
;
3330 attr
->first_value
= attr
->default_val
= NULL
;
3331 attr
->is_numeric
= attr
->is_special
= 0;
3338 /* Create internal attribute with the given default value. */
3341 make_internal_attr (name
, value
, special
)
3346 struct attr_desc
*attr
;
3348 attr
= find_attr (name
, 1);
3349 if (attr
->default_val
)
3352 attr
->is_numeric
= 1;
3353 attr
->is_special
= special
;
3354 attr
->default_val
= get_attr_value (value
, attr
, -2);
3357 /* Find the most used value of an attribute. */
3359 static struct attr_value
*
3360 find_most_used (attr
)
3361 struct attr_desc
*attr
;
3363 struct attr_value
*av
;
3364 struct attr_value
*most_used
;
3370 for (av
= attr
->first_value
; av
; av
= av
->next
)
3371 if (av
->num_insns
> nuses
)
3372 nuses
= av
->num_insns
, most_used
= av
;
3377 /* If an attribute only has a single value used, return it. Otherwise
3381 find_single_value (attr
)
3382 struct attr_desc
*attr
;
3384 struct attr_value
*av
;
3387 unique_value
= NULL
;
3388 for (av
= attr
->first_value
; av
; av
= av
->next
)
3394 unique_value
= av
->value
;
3397 return unique_value
;
3400 /* Return (attr_value "n") */
3403 make_numeric_value (n
)
3406 static rtx int_values
[20];
3412 if (n
< 20 && int_values
[n
])
3413 return int_values
[n
];
3415 exp
= rtx_alloc (CONST_STRING
);
3416 XSTR (exp
, 0) = (char *) xmalloc ((n
< 1000 ? 4
3417 : HOST_BITS_PER_INT
* 3 / 10 + 3));
3418 sprintf (XSTR (exp
, 0), "%d", n
);
3421 int_values
[n
] = exp
;
3427 xrealloc (ptr
, size
)
3431 char *result
= (char *) realloc (ptr
, size
);
3433 fatal ("virtual memory exhausted");
3441 register char *val
= (char *) malloc (size
);
3444 fatal ("virtual memory exhausted");
3452 fprintf (stderr
, "genattrtab: ");
3453 fprintf (stderr
, s
, a1
, a2
);
3454 fprintf (stderr
, "\n");
3455 exit (FATAL_EXIT_CODE
);
3458 /* More 'friendly' abort that prints the line and file.
3459 config.h can #define abort fancy_abort if you like that sort of thing. */
3464 fatal ("Internal gcc abort.");
3474 extern rtx
read_rtx ();
3476 struct attr_desc
*attr
;
3477 struct attr_value
*av
;
3478 struct insn_def
*id
;
3481 obstack_init (rtl_obstack
);
3484 fatal ("No input file name.");
3486 infile
= fopen (argv
[1], "r");
3490 exit (FATAL_EXIT_CODE
);
3495 /* Set up true and false rtx's */
3496 true_rtx
= rtx_alloc (CONST_INT
);
3497 false_rtx
= rtx_alloc (CONST_INT
);
3498 XINT (true_rtx
, 0) = 1;
3499 XINT (false_rtx
, 0) = 0;
3500 RTX_UNCHANGING_P (true_rtx
) = RTX_UNCHANGING_P (false_rtx
) = 1;
3502 printf ("/* Generated automatically by the program `genattrtab'\n\
3503 from the machine description file `md'. */\n\n");
3505 /* Read the machine description. */
3509 c
= read_skip_spaces (infile
);
3514 desc
= read_rtx (infile
);
3515 if (GET_CODE (desc
) == DEFINE_INSN
3516 || GET_CODE (desc
) == DEFINE_PEEPHOLE
3517 || GET_CODE (desc
) == DEFINE_ASM_ATTRIBUTES
)
3520 else if (GET_CODE (desc
) == DEFINE_EXPAND
)
3521 insn_code_number
++, insn_index_number
++;
3523 else if (GET_CODE (desc
) == DEFINE_SPLIT
)
3524 insn_code_number
++, insn_index_number
++;
3526 else if (GET_CODE (desc
) == DEFINE_ATTR
)
3529 insn_index_number
++;
3532 else if (GET_CODE (desc
) == DEFINE_DELAY
)
3535 insn_index_number
++;
3538 else if (GET_CODE (desc
) == DEFINE_FUNCTION_UNIT
)
3541 insn_index_number
++;
3545 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
3546 if (! got_define_asm_attributes
)
3548 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
3549 XVEC (tem
, 0) = rtvec_alloc (0);
3553 /* Expand DEFINE_DELAY information into new attribute. */
3557 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */
3561 printf ("#include \"config.h\"\n");
3562 printf ("#include \"rtl.h\"\n");
3563 printf ("#include \"insn-config.h\"\n");
3564 printf ("#include \"recog.h\"\n");
3565 printf ("#include \"regs.h\"\n");
3566 printf ("#include \"real.h\"\n");
3567 printf ("#include \"output.h\"\n");
3568 printf ("#include \"insn-attr.h\"\n");
3570 printf ("#define operands recog_operand\n\n");
3572 /* Make `insn_alternatives'. */
3573 insn_alternatives
= (int *) xmalloc (insn_code_number
* sizeof (int));
3574 for (id
= defs
; id
; id
= id
->next
)
3575 if (id
->insn_code
>= 0)
3576 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
3578 /* Prepare to write out attribute subroutines by checking everything stored
3579 away and building the attribute cases. */
3582 for (attr
= attrs
; attr
; attr
= attr
->next
)
3584 check_attr_value (attr
->default_val
->value
, attr
);
3588 /* Construct extra attributes for `length'. */
3589 make_length_attrs ();
3591 /* Perform any possible optimizations to speed up compilation. */
3594 /* Now write out all the `gen_attr_...' routines. Do these before the
3595 special routines (specifically before write_function_unit_info), so
3596 that they get defined before they are used. */
3598 for (attr
= attrs
; attr
; attr
= attr
->next
)
3600 if (! attr
->is_special
)
3601 write_attr_get (attr
);
3604 /* Write out delay eligibility information, if DEFINE_DELAY present.
3605 (The function to compute the number of delay slots will be written
3609 write_eligible_delay ("delay");
3610 if (have_annul_true
)
3611 write_eligible_delay ("annul_true");
3612 if (have_annul_false
)
3613 write_eligible_delay ("annul_false");
3616 /* Write out information about function units. */
3618 write_function_unit_info ();
3621 exit (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);