1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
100 #define strcmp_check(S1, S2) ((S1) == (S2) \
102 : (gcc_assert (strcmp ((S1), (S2))), 1))
104 #define strcmp_check(S1, S2) ((S1) != (S2))
109 #include "coretypes.h"
112 #include "gensupport.h"
116 /* Flags for make_internal_attr's `special' parameter. */
118 #define ATTR_SPECIAL (1 << 0)
120 static struct obstack obstack1
, obstack2
;
121 static struct obstack
*hash_obstack
= &obstack1
;
122 static struct obstack
*temp_obstack
= &obstack2
;
124 /* enough space to reserve for printing out ints */
125 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
127 /* Define structures used to record attributes and values. */
129 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
130 encountered, we store all the relevant information into a
131 `struct insn_def'. This is done to allow attribute definitions to occur
132 anywhere in the file. */
136 struct insn_def
*next
; /* Next insn in chain. */
137 rtx def
; /* The DEFINE_... */
138 int insn_code
; /* Instruction number. */
139 int insn_index
; /* Expression numer in file, for errors. */
140 int lineno
; /* Line number. */
141 int num_alternatives
; /* Number of alternatives. */
142 int vec_idx
; /* Index of attribute vector in `def'. */
145 /* Once everything has been read in, we store in each attribute value a list
146 of insn codes that have that value. Here is the structure used for the
151 struct insn_ent
*next
; /* Next in chain. */
152 struct insn_def
*def
; /* Instruction definition. */
155 /* Each value of an attribute (either constant or computed) is assigned a
156 structure which is used as the listhead of the insns that have that
161 rtx value
; /* Value of attribute. */
162 struct attr_value
*next
; /* Next attribute value in chain. */
163 struct insn_ent
*first_insn
; /* First insn with this value. */
164 int num_insns
; /* Number of insns with this value. */
165 int has_asm_insn
; /* True if this value used for `asm' insns */
168 /* Structure for each attribute. */
172 char *name
; /* Name of attribute. */
173 struct attr_desc
*next
; /* Next attribute. */
174 struct attr_value
*first_value
; /* First value of this attribute. */
175 struct attr_value
*default_val
; /* Default value for this attribute. */
176 int lineno
: 24; /* Line number. */
177 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
178 unsigned is_const
: 1; /* Attribute value constant for each run. */
179 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
182 /* Structure for each DEFINE_DELAY. */
186 rtx def
; /* DEFINE_DELAY expression. */
187 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
188 int num
; /* Number of DEFINE_DELAY, starting at 1. */
189 int lineno
; /* Line number. */
192 struct attr_value_list
194 struct attr_value
*av
;
196 struct attr_desc
*attr
;
197 struct attr_value_list
*next
;
200 /* Listheads of above structures. */
202 /* This one is indexed by the first character of the attribute name. */
203 #define MAX_ATTRS_INDEX 256
204 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
205 static struct insn_def
*defs
;
206 static struct delay_desc
*delays
;
207 struct attr_value_list
**insn_code_values
;
209 /* Other variables. */
211 static int insn_code_number
;
212 static int insn_index_number
;
213 static int got_define_asm_attributes
;
214 static int must_extract
;
215 static int must_constrain
;
216 static int address_used
;
217 static int length_used
;
218 static int num_delays
;
219 static int have_annul_true
, have_annul_false
;
220 static int num_insn_ents
;
222 /* Stores, for each insn code, the number of constraint alternatives. */
224 static int *insn_n_alternatives
;
226 /* Stores, for each insn code, a bitmap that has bits on for each possible
229 static int *insn_alternatives
;
231 /* Used to simplify expressions. */
233 static rtx true_rtx
, false_rtx
;
235 /* Used to reduce calls to `strcmp' */
237 static const char *alternative_name
;
238 static const char *length_str
;
239 static const char *delay_type_str
;
240 static const char *delay_1_0_str
;
241 static const char *num_delay_slots_str
;
243 /* Simplify an expression. Only call the routine if there is something to
245 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
246 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
247 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
249 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
251 /* Forward declarations of functions used before their definitions, only. */
252 static char *attr_string (const char *, int);
253 static char *attr_printf (unsigned int, const char *, ...)
255 static rtx
make_numeric_value (int);
256 static struct attr_desc
*find_attr (const char **, int);
257 static rtx
mk_attr_alt (int);
258 static char *next_comma_elt (const char **);
259 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
260 static rtx
copy_boolean (rtx
);
261 static int compares_alternatives_p (rtx
);
262 static void make_internal_attr (const char *, rtx
, int);
263 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
264 static void walk_attr_value (rtx
);
265 static int max_attr_value (rtx
, int*);
266 static int min_attr_value (rtx
, int*);
267 static int or_attr_value (rtx
, int*);
268 static rtx
simplify_test_exp (rtx
, int, int);
269 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
270 static rtx
copy_rtx_unchanging (rtx
);
271 static bool attr_alt_subset_p (rtx
, rtx
);
272 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
273 static void clear_struct_flag (rtx
);
274 static void write_attr_valueq (struct attr_desc
*, const char *);
275 static struct attr_value
*find_most_used (struct attr_desc
*);
276 static void write_attr_set (struct attr_desc
*, int, rtx
,
277 const char *, const char *, rtx
,
279 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
280 int, const char *, const char *, int, rtx
);
281 static void write_attr_value (struct attr_desc
*, rtx
);
282 static void write_upcase (const char *);
283 static void write_indent (int);
284 static rtx
identity_fn (rtx
);
285 static rtx
zero_fn (rtx
);
286 static rtx
one_fn (rtx
);
287 static rtx
max_fn (rtx
);
288 static rtx
min_fn (rtx
);
290 #define oballoc(size) obstack_alloc (hash_obstack, size)
292 /* Hash table for sharing RTL and strings. */
294 /* Each hash table slot is a bucket containing a chain of these structures.
295 Strings are given negative hash codes; RTL expressions are given positive
300 struct attr_hash
*next
; /* Next structure in the bucket. */
301 int hashcode
; /* Hash code of this rtx or string. */
304 char *str
; /* The string (negative hash codes) */
305 rtx rtl
; /* or the RTL recorded here. */
309 /* Now here is the hash table. When recording an RTL, it is added to
310 the slot whose index is the hash code mod the table size. Note
311 that the hash table is used for several kinds of RTL (see attr_rtx)
312 and for strings. While all these live in the same table, they are
313 completely independent, and the hash code is computed differently
316 #define RTL_HASH_SIZE 4093
317 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
319 /* Here is how primitive or already-shared RTL's hash
321 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
323 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
326 attr_hash_add_rtx (int hashcode
, rtx rtl
)
330 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
331 h
->hashcode
= hashcode
;
333 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
334 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
337 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
340 attr_hash_add_string (int hashcode
, char *str
)
344 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
345 h
->hashcode
= -hashcode
;
347 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
348 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
351 /* Generate an RTL expression, but avoid duplicates.
352 Set the ATTR_PERMANENT_P flag for these permanent objects.
354 In some cases we cannot uniquify; then we return an ordinary
355 impermanent rtx with ATTR_PERMANENT_P clear.
359 rtx attr_rtx (code, [element1, ..., elementn]) */
362 attr_rtx_1 (enum rtx_code code
, va_list p
)
364 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
367 struct obstack
*old_obstack
= rtl_obstack
;
369 /* For each of several cases, search the hash table for an existing entry.
370 Use that entry if one is found; otherwise create a new RTL and add it
373 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
375 rtx arg0
= va_arg (p
, rtx
);
377 /* A permanent object cannot point to impermanent ones. */
378 if (! ATTR_PERMANENT_P (arg0
))
380 rt_val
= rtx_alloc (code
);
381 XEXP (rt_val
, 0) = arg0
;
385 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
386 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
387 if (h
->hashcode
== hashcode
388 && GET_CODE (h
->u
.rtl
) == code
389 && XEXP (h
->u
.rtl
, 0) == arg0
)
394 rtl_obstack
= hash_obstack
;
395 rt_val
= rtx_alloc (code
);
396 XEXP (rt_val
, 0) = arg0
;
399 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
400 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
401 || GET_RTX_CLASS (code
) == RTX_COMPARE
402 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
404 rtx arg0
= va_arg (p
, rtx
);
405 rtx arg1
= va_arg (p
, rtx
);
407 /* A permanent object cannot point to impermanent ones. */
408 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
410 rt_val
= rtx_alloc (code
);
411 XEXP (rt_val
, 0) = arg0
;
412 XEXP (rt_val
, 1) = arg1
;
416 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
417 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
418 if (h
->hashcode
== hashcode
419 && GET_CODE (h
->u
.rtl
) == code
420 && XEXP (h
->u
.rtl
, 0) == arg0
421 && XEXP (h
->u
.rtl
, 1) == arg1
)
426 rtl_obstack
= hash_obstack
;
427 rt_val
= rtx_alloc (code
);
428 XEXP (rt_val
, 0) = arg0
;
429 XEXP (rt_val
, 1) = arg1
;
432 else if (GET_RTX_LENGTH (code
) == 1
433 && GET_RTX_FORMAT (code
)[0] == 's')
435 char *arg0
= va_arg (p
, char *);
437 arg0
= DEF_ATTR_STRING (arg0
);
439 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
440 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
441 if (h
->hashcode
== hashcode
442 && GET_CODE (h
->u
.rtl
) == code
443 && XSTR (h
->u
.rtl
, 0) == arg0
)
448 rtl_obstack
= hash_obstack
;
449 rt_val
= rtx_alloc (code
);
450 XSTR (rt_val
, 0) = arg0
;
453 else if (GET_RTX_LENGTH (code
) == 2
454 && GET_RTX_FORMAT (code
)[0] == 's'
455 && GET_RTX_FORMAT (code
)[1] == 's')
457 char *arg0
= va_arg (p
, char *);
458 char *arg1
= va_arg (p
, char *);
460 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
461 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
462 if (h
->hashcode
== hashcode
463 && GET_CODE (h
->u
.rtl
) == code
464 && XSTR (h
->u
.rtl
, 0) == arg0
465 && XSTR (h
->u
.rtl
, 1) == arg1
)
470 rtl_obstack
= hash_obstack
;
471 rt_val
= rtx_alloc (code
);
472 XSTR (rt_val
, 0) = arg0
;
473 XSTR (rt_val
, 1) = arg1
;
476 else if (code
== CONST_INT
)
478 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
488 int i
; /* Array indices... */
489 const char *fmt
; /* Current rtx's format... */
491 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
493 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
494 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
498 case '0': /* Unused field. */
501 case 'i': /* An integer? */
502 XINT (rt_val
, i
) = va_arg (p
, int);
505 case 'w': /* A wide integer? */
506 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
509 case 's': /* A string? */
510 XSTR (rt_val
, i
) = va_arg (p
, char *);
513 case 'e': /* An expression? */
514 case 'u': /* An insn? Same except when printing. */
515 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
518 case 'E': /* An RTX vector? */
519 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
529 rtl_obstack
= old_obstack
;
530 attr_hash_add_rtx (hashcode
, rt_val
);
531 ATTR_PERMANENT_P (rt_val
) = 1;
536 attr_rtx (enum rtx_code code
, ...)
542 result
= attr_rtx_1 (code
, p
);
547 /* Create a new string printed with the printf line arguments into a space
548 of at most LEN bytes:
550 rtx attr_printf (len, format, [arg1, ..., argn]) */
553 attr_printf (unsigned int len
, const char *fmt
, ...)
560 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
562 vsprintf (str
, fmt
, p
);
565 return DEF_ATTR_STRING (str
);
569 attr_eq (const char *name
, const char *value
)
571 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
577 return XSTR (make_numeric_value (n
), 0);
580 /* Return a permanent (possibly shared) copy of a string STR (not assumed
581 to be null terminated) with LEN bytes. */
584 attr_string (const char *str
, int len
)
591 /* Compute the hash code. */
592 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
593 for (i
= 1; i
< len
; i
+= 2)
594 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
596 hashcode
= -hashcode
;
598 /* Search the table for the string. */
599 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
600 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
601 && !strncmp (h
->u
.str
, str
, len
))
602 return h
->u
.str
; /* <-- return if found. */
604 /* Not found; create a permanent copy and add it to the hash table. */
605 new_str
= obstack_alloc (hash_obstack
, len
+ 1);
606 memcpy (new_str
, str
, len
);
608 attr_hash_add_string (hashcode
, new_str
);
610 return new_str
; /* Return the new string. */
613 /* Check two rtx's for equality of contents,
614 taking advantage of the fact that if both are hashed
615 then they can't be equal unless they are the same object. */
618 attr_equal_p (rtx x
, rtx y
)
620 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
621 && rtx_equal_p (x
, y
)));
624 /* Copy an attribute value expression,
625 descending to all depths, but not copying any
626 permanent hashed subexpressions. */
629 attr_copy_rtx (rtx orig
)
634 const char *format_ptr
;
636 /* No need to copy a permanent object. */
637 if (ATTR_PERMANENT_P (orig
))
640 code
= GET_CODE (orig
);
658 copy
= rtx_alloc (code
);
659 PUT_MODE (copy
, GET_MODE (orig
));
660 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
661 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
662 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
664 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
666 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
668 switch (*format_ptr
++)
671 XEXP (copy
, i
) = XEXP (orig
, i
);
672 if (XEXP (orig
, i
) != NULL
)
673 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
678 XVEC (copy
, i
) = XVEC (orig
, i
);
679 if (XVEC (orig
, i
) != NULL
)
681 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
682 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
683 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
689 XINT (copy
, i
) = XINT (orig
, i
);
693 XWINT (copy
, i
) = XWINT (orig
, i
);
698 XSTR (copy
, i
) = XSTR (orig
, i
);
708 /* Given a test expression for an attribute, ensure it is validly formed.
709 IS_CONST indicates whether the expression is constant for each compiler
710 run (a constant expression may not test any particular insn).
712 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
713 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
714 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
716 Update the string address in EQ_ATTR expression to be the same used
717 in the attribute (or `alternative_name') to speed up subsequent
718 `find_attr' calls and eliminate most `strcmp' calls.
720 Return the new expression, if any. */
723 check_attr_test (rtx exp
, int is_const
, int lineno
)
725 struct attr_desc
*attr
;
726 struct attr_value
*av
;
727 const char *name_ptr
, *p
;
730 switch (GET_CODE (exp
))
733 /* Handle negation test. */
734 if (XSTR (exp
, 1)[0] == '!')
735 return check_attr_test (attr_rtx (NOT
,
736 attr_eq (XSTR (exp
, 0),
740 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
742 attr
= find_attr (&XSTR (exp
, 0), 0);
745 if (! strcmp (XSTR (exp
, 0), "alternative"))
746 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
748 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
751 if (is_const
&& ! attr
->is_const
)
752 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
755 /* Copy this just to make it permanent,
756 so expressions using it can be permanent too. */
757 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
759 /* It shouldn't be possible to simplify the value given to a
760 constant attribute, so don't expand this until it's time to
761 write the test expression. */
763 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
765 if (attr
->is_numeric
)
767 for (p
= XSTR (exp
, 1); *p
; p
++)
769 fatal ("attribute `%s' takes only numeric values",
774 for (av
= attr
->first_value
; av
; av
= av
->next
)
775 if (GET_CODE (av
->value
) == CONST_STRING
776 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
780 fatal ("unknown value `%s' for `%s' attribute",
781 XSTR (exp
, 1), XSTR (exp
, 0));
786 if (! strcmp (XSTR (exp
, 0), "alternative"))
790 name_ptr
= XSTR (exp
, 1);
791 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
792 set
|= 1 << atoi (p
);
794 return mk_attr_alt (set
);
798 /* Make an IOR tree of the possible values. */
800 name_ptr
= XSTR (exp
, 1);
801 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
803 newexp
= attr_eq (XSTR (exp
, 0), p
);
804 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
807 return check_attr_test (orexp
, is_const
, lineno
);
816 /* Either TRUE or FALSE. */
824 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
825 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
829 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
834 fatal ("RTL operator \"%s\" not valid in constant attribute test",
835 GET_RTX_NAME (GET_CODE (exp
)));
836 /* These cases can't be simplified. */
837 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
840 case LE
: case LT
: case GT
: case GE
:
841 case LEU
: case LTU
: case GTU
: case GEU
:
843 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
844 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
845 exp
= attr_rtx (GET_CODE (exp
),
846 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
847 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
848 /* These cases can't be simplified. */
849 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
855 /* These cases are valid for constant attributes, but can't be
857 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
858 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
862 fatal ("RTL operator \"%s\" not valid in attribute test",
863 GET_RTX_NAME (GET_CODE (exp
)));
869 /* Given an expression, ensure that it is validly formed and that all named
870 attribute values are valid for the given attribute. Issue a fatal error
871 if not. If no attribute is specified, assume a numeric attribute.
873 Return a perhaps modified replacement expression for the value. */
876 check_attr_value (rtx exp
, struct attr_desc
*attr
)
878 struct attr_value
*av
;
882 switch (GET_CODE (exp
))
885 if (attr
&& ! attr
->is_numeric
)
887 message_with_line (attr
->lineno
,
888 "CONST_INT not valid for non-numeric attribute %s",
894 if (INTVAL (exp
) < 0)
896 message_with_line (attr
->lineno
,
897 "negative numeric value specified for attribute %s",
905 if (! strcmp (XSTR (exp
, 0), "*"))
908 if (attr
== 0 || attr
->is_numeric
)
914 message_with_line (attr
? attr
->lineno
: 0,
915 "non-numeric value for numeric attribute %s",
916 attr
? attr
->name
: "internal");
923 for (av
= attr
->first_value
; av
; av
= av
->next
)
924 if (GET_CODE (av
->value
) == CONST_STRING
925 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
930 message_with_line (attr
->lineno
,
931 "unknown value `%s' for `%s' attribute",
932 XSTR (exp
, 0), attr
? attr
->name
: "internal");
938 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
939 attr
? attr
->is_const
: 0,
940 attr
? attr
->lineno
: 0);
941 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
942 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
950 if (attr
&& !attr
->is_numeric
)
952 message_with_line (attr
->lineno
,
953 "invalid operation `%s' for non-numeric attribute value",
954 GET_RTX_NAME (GET_CODE (exp
)));
962 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
963 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
972 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
976 if (XVECLEN (exp
, 0) % 2 != 0)
978 message_with_line (attr
->lineno
,
979 "first operand of COND must have even length");
984 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
986 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
987 attr
? attr
->is_const
: 0,
988 attr
? attr
->lineno
: 0);
989 XVECEXP (exp
, 0, i
+ 1)
990 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
993 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
998 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1001 message_with_line (attr
? attr
->lineno
: 0,
1002 "unknown attribute `%s' in ATTR",
1006 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1008 message_with_line (attr
->lineno
,
1009 "non-constant attribute `%s' referenced from `%s'",
1010 XSTR (exp
, 0), attr
->name
);
1014 && attr
->is_numeric
!= attr2
->is_numeric
)
1016 message_with_line (attr
->lineno
,
1017 "numeric attribute mismatch calling `%s' from `%s'",
1018 XSTR (exp
, 0), attr
->name
);
1025 /* A constant SYMBOL_REF is valid as a constant attribute test and
1026 is expanded later by make_canonical into a COND. In a non-constant
1027 attribute test, it is left be. */
1028 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1031 message_with_line (attr
? attr
->lineno
: 0,
1032 "invalid operation `%s' for attribute value",
1033 GET_RTX_NAME (GET_CODE (exp
)));
1041 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1042 It becomes a COND with each test being (eq_attr "alternative" "n") */
1045 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1047 int num_alt
= id
->num_alternatives
;
1051 if (XVECLEN (exp
, 1) != num_alt
)
1053 message_with_line (id
->lineno
,
1054 "bad number of entries in SET_ATTR_ALTERNATIVE");
1059 /* Make a COND with all tests but the last. Select the last value via the
1061 condexp
= rtx_alloc (COND
);
1062 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1064 for (i
= 0; i
< num_alt
- 1; i
++)
1067 p
= attr_numeral (i
);
1069 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1070 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1073 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1075 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1078 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1079 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1082 convert_set_attr (rtx exp
, struct insn_def
*id
)
1085 const char *name_ptr
;
1089 /* See how many alternative specified. */
1090 n
= n_comma_elts (XSTR (exp
, 1));
1092 return attr_rtx (SET
,
1093 attr_rtx (ATTR
, XSTR (exp
, 0)),
1094 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1096 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1097 XSTR (newexp
, 0) = XSTR (exp
, 0);
1098 XVEC (newexp
, 1) = rtvec_alloc (n
);
1100 /* Process each comma-separated name. */
1101 name_ptr
= XSTR (exp
, 1);
1103 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1104 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1106 return convert_set_attr_alternative (newexp
, id
);
1109 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1110 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1116 struct insn_def
*id
;
1117 struct attr_desc
*attr
;
1121 for (id
= defs
; id
; id
= id
->next
)
1123 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1126 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1128 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1129 switch (GET_CODE (value
))
1132 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1134 message_with_line (id
->lineno
, "bad attribute set");
1140 case SET_ATTR_ALTERNATIVE
:
1141 value
= convert_set_attr_alternative (value
, id
);
1145 value
= convert_set_attr (value
, id
);
1149 message_with_line (id
->lineno
, "invalid attribute code %s",
1150 GET_RTX_NAME (GET_CODE (value
)));
1154 if (value
== NULL_RTX
)
1157 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1159 message_with_line (id
->lineno
, "unknown attribute %s",
1160 XSTR (XEXP (value
, 0), 0));
1165 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1166 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1171 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1172 expressions by converting them into a COND. This removes cases from this
1173 program. Also, replace an attribute value of "*" with the default attribute
1177 make_canonical (struct attr_desc
*attr
, rtx exp
)
1182 switch (GET_CODE (exp
))
1185 exp
= make_numeric_value (INTVAL (exp
));
1189 if (! strcmp (XSTR (exp
, 0), "*"))
1191 if (attr
== 0 || attr
->default_val
== 0)
1192 fatal ("(attr_value \"*\") used in invalid context");
1193 exp
= attr
->default_val
->value
;
1196 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1201 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1203 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1204 This makes the COND something that won't be considered an arbitrary
1205 expression by walk_attr_value. */
1206 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1207 exp
= check_attr_value (exp
, attr
);
1211 newexp
= rtx_alloc (COND
);
1212 XVEC (newexp
, 0) = rtvec_alloc (2);
1213 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1214 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1216 XEXP (newexp
, 1) = XEXP (exp
, 2);
1219 /* Fall through to COND case since this is now a COND. */
1226 /* First, check for degenerate COND. */
1227 if (XVECLEN (exp
, 0) == 0)
1228 return make_canonical (attr
, XEXP (exp
, 1));
1229 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1231 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1233 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1234 XVECEXP (exp
, 0, i
+ 1)
1235 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1236 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1252 copy_boolean (rtx exp
)
1254 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1255 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1256 copy_boolean (XEXP (exp
, 1)));
1257 if (GET_CODE (exp
) == MATCH_OPERAND
)
1259 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1260 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1262 else if (GET_CODE (exp
) == EQ_ATTR
)
1264 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1265 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1271 /* Given a value and an attribute description, return a `struct attr_value *'
1272 that represents that value. This is either an existing structure, if the
1273 value has been previously encountered, or a newly-created structure.
1275 `insn_code' is the code of an insn whose attribute has the specified
1276 value (-2 if not processing an insn). We ensure that all insns for
1277 a given value have the same number of alternatives if the value checks
1280 static struct attr_value
*
1281 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1283 struct attr_value
*av
;
1286 value
= make_canonical (attr
, value
);
1287 if (compares_alternatives_p (value
))
1289 if (insn_code
< 0 || insn_alternatives
== NULL
)
1290 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1292 num_alt
= insn_alternatives
[insn_code
];
1295 for (av
= attr
->first_value
; av
; av
= av
->next
)
1296 if (rtx_equal_p (value
, av
->value
)
1297 && (num_alt
== 0 || av
->first_insn
== NULL
1298 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1301 av
= oballoc (sizeof (struct attr_value
));
1303 av
->next
= attr
->first_value
;
1304 attr
->first_value
= av
;
1305 av
->first_insn
= NULL
;
1307 av
->has_asm_insn
= 0;
1312 /* After all DEFINE_DELAYs have been read in, create internal attributes
1313 to generate the required routines.
1315 First, we compute the number of delay slots for each insn (as a COND of
1316 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1317 delay type is specified, we compute a similar function giving the
1318 DEFINE_DELAY ordinal for each insn.
1320 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1321 tells whether a given insn can be in that delay slot.
1323 Normal attribute filling and optimization expands these to contain the
1324 information needed to handle delay slots. */
1327 expand_delays (void)
1329 struct delay_desc
*delay
;
1335 /* First, generate data for `num_delay_slots' function. */
1337 condexp
= rtx_alloc (COND
);
1338 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1339 XEXP (condexp
, 1) = make_numeric_value (0);
1341 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1343 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1344 XVECEXP (condexp
, 0, i
+ 1)
1345 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1348 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1350 /* If more than one delay type, do the same for computing the delay type. */
1353 condexp
= rtx_alloc (COND
);
1354 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1355 XEXP (condexp
, 1) = make_numeric_value (0);
1357 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1359 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1360 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1363 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1366 /* For each delay possibility and delay slot, compute an eligibility
1367 attribute for non-annulled insns and for each type of annulled (annul
1368 if true and annul if false). */
1369 for (delay
= delays
; delay
; delay
= delay
->next
)
1371 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1373 condexp
= XVECEXP (delay
->def
, 1, i
);
1375 condexp
= false_rtx
;
1376 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1377 make_numeric_value (1), make_numeric_value (0));
1379 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1380 "*delay_%d_%d", delay
->num
, i
/ 3);
1381 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1383 if (have_annul_true
)
1385 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1386 if (condexp
== 0) condexp
= false_rtx
;
1387 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1388 make_numeric_value (1),
1389 make_numeric_value (0));
1390 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1391 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1392 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1395 if (have_annul_false
)
1397 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1398 if (condexp
== 0) condexp
= false_rtx
;
1399 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1400 make_numeric_value (1),
1401 make_numeric_value (0));
1402 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1403 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1404 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1410 /* Once all attributes and insns have been read and checked, we construct for
1411 each attribute value a list of all the insns that have that value for
1415 fill_attr (struct attr_desc
*attr
)
1417 struct attr_value
*av
;
1418 struct insn_ent
*ie
;
1419 struct insn_def
*id
;
1423 /* Don't fill constant attributes. The value is independent of
1424 any particular insn. */
1428 for (id
= defs
; id
; id
= id
->next
)
1430 /* If no value is specified for this insn for this attribute, use the
1433 if (XVEC (id
->def
, id
->vec_idx
))
1434 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1435 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1437 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1440 av
= attr
->default_val
;
1442 av
= get_attr_value (value
, attr
, id
->insn_code
);
1444 ie
= oballoc (sizeof (struct insn_ent
));
1446 insert_insn_ent (av
, ie
);
1450 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1451 test that checks relative positions of insns (uses MATCH_DUP or PC).
1452 If so, replace it with what is obtained by passing the expression to
1453 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1454 recursively on each value (including the default value). Otherwise,
1455 return the value returned by NO_ADDRESS_FN applied to EXP. */
1458 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1459 rtx (*address_fn
) (rtx
))
1464 if (GET_CODE (exp
) == COND
)
1466 /* See if any tests use addresses. */
1468 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1469 walk_attr_value (XVECEXP (exp
, 0, i
));
1472 return (*address_fn
) (exp
);
1474 /* Make a new copy of this COND, replacing each element. */
1475 newexp
= rtx_alloc (COND
);
1476 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1477 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1479 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1480 XVECEXP (newexp
, 0, i
+ 1)
1481 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1482 no_address_fn
, address_fn
);
1485 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1486 no_address_fn
, address_fn
);
1491 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1494 walk_attr_value (XEXP (exp
, 0));
1496 return (*address_fn
) (exp
);
1498 return attr_rtx (IF_THEN_ELSE
,
1499 substitute_address (XEXP (exp
, 0),
1500 no_address_fn
, address_fn
),
1501 substitute_address (XEXP (exp
, 1),
1502 no_address_fn
, address_fn
),
1503 substitute_address (XEXP (exp
, 2),
1504 no_address_fn
, address_fn
));
1507 return (*no_address_fn
) (exp
);
1510 /* Make new attributes from the `length' attribute. The following are made,
1511 each corresponding to a function called from `shorten_branches' or
1514 *insn_default_length This is the length of the insn to be returned
1515 by `get_attr_length' before `shorten_branches'
1516 has been called. In each case where the length
1517 depends on relative addresses, the largest
1518 possible is used. This routine is also used
1519 to compute the initial size of the insn.
1521 *insn_variable_length_p This returns 1 if the insn's length depends
1522 on relative addresses, zero otherwise.
1524 *insn_current_length This is only called when it is known that the
1525 insn has a variable length and returns the
1526 current length, based on relative addresses.
1530 make_length_attrs (void)
1532 static const char *new_names
[] =
1534 "*insn_default_length",
1536 "*insn_variable_length_p",
1537 "*insn_current_length"
1539 static rtx (*const no_address_fn
[]) (rtx
)
1540 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1541 static rtx (*const address_fn
[]) (rtx
)
1542 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1544 struct attr_desc
*length_attr
, *new_attr
;
1545 struct attr_value
*av
, *new_av
;
1546 struct insn_ent
*ie
, *new_ie
;
1548 /* See if length attribute is defined. If so, it must be numeric. Make
1549 it special so we don't output anything for it. */
1550 length_attr
= find_attr (&length_str
, 0);
1551 if (length_attr
== 0)
1554 if (! length_attr
->is_numeric
)
1555 fatal ("length attribute must be numeric");
1557 length_attr
->is_const
= 0;
1558 length_attr
->is_special
= 1;
1560 /* Make each new attribute, in turn. */
1561 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1563 make_internal_attr (new_names
[i
],
1564 substitute_address (length_attr
->default_val
->value
,
1565 no_address_fn
[i
], address_fn
[i
]),
1567 new_attr
= find_attr (&new_names
[i
], 0);
1568 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1569 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1571 new_av
= get_attr_value (substitute_address (av
->value
,
1574 new_attr
, ie
->def
->insn_code
);
1575 new_ie
= oballoc (sizeof (struct insn_ent
));
1576 new_ie
->def
= ie
->def
;
1577 insert_insn_ent (new_av
, new_ie
);
1582 /* Utility functions called from above routine. */
1585 identity_fn (rtx exp
)
1591 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1593 return make_numeric_value (0);
1597 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1599 return make_numeric_value (1);
1606 return make_numeric_value (max_attr_value (exp
, &unknown
));
1613 return make_numeric_value (min_attr_value (exp
, &unknown
));
1617 write_length_unit_log (void)
1619 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1620 struct attr_value
*av
;
1621 struct insn_ent
*ie
;
1622 unsigned int length_unit_log
, length_or
;
1625 if (length_attr
== 0)
1627 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1628 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1629 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1630 length_or
|= or_attr_value (av
->value
, &unknown
);
1633 length_unit_log
= 0;
1636 length_or
= ~length_or
;
1637 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1640 printf ("const int length_unit_log = %u;\n", length_unit_log
);
1643 /* Take a COND expression and see if any of the conditions in it can be
1644 simplified. If any are known true or known false for the particular insn
1645 code, the COND can be further simplified.
1647 Also call ourselves on any COND operations that are values of this COND.
1649 We do not modify EXP; rather, we make and return a new rtx. */
1652 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1655 /* We store the desired contents here,
1656 then build a new expression if they don't match EXP. */
1657 rtx defval
= XEXP (exp
, 1);
1658 rtx new_defval
= XEXP (exp
, 1);
1659 int len
= XVECLEN (exp
, 0);
1660 rtx
*tests
= XNEWVEC (rtx
, len
);
1664 /* This lets us free all storage allocated below, if appropriate. */
1665 obstack_finish (rtl_obstack
);
1667 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1669 /* See if default value needs simplification. */
1670 if (GET_CODE (defval
) == COND
)
1671 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1673 /* Simplify the subexpressions, and see what tests we can get rid of. */
1675 for (i
= 0; i
< len
; i
+= 2)
1677 rtx newtest
, newval
;
1679 /* Simplify this test. */
1680 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1683 newval
= tests
[i
+ 1];
1684 /* See if this value may need simplification. */
1685 if (GET_CODE (newval
) == COND
)
1686 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1688 /* Look for ways to delete or combine this test. */
1689 if (newtest
== true_rtx
)
1691 /* If test is true, make this value the default
1692 and discard this + any following tests. */
1694 defval
= tests
[i
+ 1];
1695 new_defval
= newval
;
1698 else if (newtest
== false_rtx
)
1700 /* If test is false, discard it and its value. */
1701 for (j
= i
; j
< len
- 2; j
++)
1702 tests
[j
] = tests
[j
+ 2];
1707 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1709 /* If this value and the value for the prev test are the same,
1713 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1714 insn_code
, insn_index
);
1716 /* Delete this test/value. */
1717 for (j
= i
; j
< len
- 2; j
++)
1718 tests
[j
] = tests
[j
+ 2];
1724 tests
[i
+ 1] = newval
;
1727 /* If the last test in a COND has the same value
1728 as the default value, that test isn't needed. */
1730 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1733 /* See if we changed anything. */
1734 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1737 for (i
= 0; i
< len
; i
++)
1738 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1746 if (GET_CODE (defval
) == COND
)
1747 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1755 rtx newexp
= rtx_alloc (COND
);
1757 XVEC (newexp
, 0) = rtvec_alloc (len
);
1758 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1759 XEXP (newexp
, 1) = new_defval
;
1766 /* Remove an insn entry from an attribute value. */
1769 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1771 struct insn_ent
*previe
;
1773 if (av
->first_insn
== ie
)
1774 av
->first_insn
= ie
->next
;
1777 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1779 previe
->next
= ie
->next
;
1783 if (ie
->def
->insn_code
== -1)
1784 av
->has_asm_insn
= 0;
1789 /* Insert an insn entry in an attribute value list. */
1792 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1794 ie
->next
= av
->first_insn
;
1795 av
->first_insn
= ie
;
1797 if (ie
->def
->insn_code
== -1)
1798 av
->has_asm_insn
= 1;
1803 /* This is a utility routine to take an expression that is a tree of either
1804 AND or IOR expressions and insert a new term. The new term will be
1805 inserted at the right side of the first node whose code does not match
1806 the root. A new node will be created with the root's code. Its left
1807 side will be the old right side and its right side will be the new
1810 If the `term' is itself a tree, all its leaves will be inserted. */
1813 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1817 /* Avoid consing in some special cases. */
1818 if (code
== AND
&& term
== true_rtx
)
1820 if (code
== AND
&& term
== false_rtx
)
1822 if (code
== AND
&& exp
== true_rtx
)
1824 if (code
== AND
&& exp
== false_rtx
)
1826 if (code
== IOR
&& term
== true_rtx
)
1828 if (code
== IOR
&& term
== false_rtx
)
1830 if (code
== IOR
&& exp
== true_rtx
)
1832 if (code
== IOR
&& exp
== false_rtx
)
1834 if (attr_equal_p (exp
, term
))
1837 if (GET_CODE (term
) == code
)
1839 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1840 insn_code
, insn_index
);
1841 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1842 insn_code
, insn_index
);
1847 if (GET_CODE (exp
) == code
)
1849 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1850 term
, insn_code
, insn_index
);
1851 if (new != XEXP (exp
, 1))
1852 /* Make a copy of this expression and call recursively. */
1853 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1859 /* Insert the new term. */
1860 newexp
= attr_rtx (code
, exp
, term
);
1863 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1866 /* If we have an expression which AND's a bunch of
1867 (not (eq_attrq "alternative" "n"))
1868 terms, we may have covered all or all but one of the possible alternatives.
1869 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1871 This routine is passed an expression and either AND or IOR. It returns a
1872 bitmask indicating which alternatives are mentioned within EXP. */
1875 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1878 if (GET_CODE (exp
) == code
)
1879 return compute_alternative_mask (XEXP (exp
, 0), code
)
1880 | compute_alternative_mask (XEXP (exp
, 1), code
);
1882 else if (code
== AND
&& GET_CODE (exp
) == NOT
1883 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1884 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1885 string
= XSTR (XEXP (exp
, 0), 1);
1887 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1888 && XSTR (exp
, 0) == alternative_name
)
1889 string
= XSTR (exp
, 1);
1891 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1893 if (code
== AND
&& XINT (exp
, 1))
1894 return XINT (exp
, 0);
1896 if (code
== IOR
&& !XINT (exp
, 1))
1897 return XINT (exp
, 0);
1905 return 1 << (string
[0] - '0');
1906 return 1 << atoi (string
);
1909 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1910 attribute with the value represented by that bit. */
1913 make_alternative_compare (int mask
)
1915 return mk_attr_alt (mask
);
1918 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1919 of "attr" for this insn code. From that value, we can compute a test
1920 showing when the EQ_ATTR will be true. This routine performs that
1921 computation. If a test condition involves an address, we leave the EQ_ATTR
1922 intact because addresses are only valid for the `length' attribute.
1924 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1925 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1928 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
1935 switch (GET_CODE (value
))
1938 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
1949 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
1950 gcc_assert (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2
1953 strcpy (string
, XSTR (exp
, 0));
1954 strcat (string
, "_");
1955 strcat (string
, XSTR (exp
, 1));
1956 for (p
= string
; *p
; p
++)
1959 newexp
= attr_rtx (EQ
, value
,
1960 attr_rtx (SYMBOL_REF
,
1961 DEF_ATTR_STRING (string
)));
1966 /* We construct an IOR of all the cases for which the
1967 requested attribute value is present. Since we start with
1968 FALSE, if it is not present, FALSE will be returned.
1970 Each case is the AND of the NOT's of the previous conditions with the
1971 current condition; in the default case the current condition is TRUE.
1973 For each possible COND value, call ourselves recursively.
1975 The extra TRUE and FALSE expressions will be eliminated by another
1976 call to the simplification routine. */
1981 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
1983 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
1984 insn_code
, insn_index
);
1986 right
= insert_right_side (AND
, andexp
, this,
1987 insn_code
, insn_index
);
1988 right
= insert_right_side (AND
, right
,
1989 evaluate_eq_attr (exp
,
1992 insn_code
, insn_index
),
1993 insn_code
, insn_index
);
1994 orexp
= insert_right_side (IOR
, orexp
, right
,
1995 insn_code
, insn_index
);
1997 /* Add this condition into the AND expression. */
1998 newexp
= attr_rtx (NOT
, this);
1999 andexp
= insert_right_side (AND
, andexp
, newexp
,
2000 insn_code
, insn_index
);
2003 /* Handle the default case. */
2004 right
= insert_right_side (AND
, andexp
,
2005 evaluate_eq_attr (exp
, XEXP (value
, 1),
2006 insn_code
, insn_index
),
2007 insn_code
, insn_index
);
2008 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2015 /* If uses an address, must return original expression. But set the
2016 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2019 walk_attr_value (newexp
);
2023 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2024 return copy_rtx_unchanging (exp
);
2031 /* This routine is called when an AND of a term with a tree of AND's is
2032 encountered. If the term or its complement is present in the tree, it
2033 can be replaced with TRUE or FALSE, respectively.
2035 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2036 be true and hence are complementary.
2038 There is one special case: If we see
2039 (and (not (eq_attr "att" "v1"))
2040 (eq_attr "att" "v2"))
2041 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2042 replace the term, not anything in the AND tree. So we pass a pointer to
2046 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2051 int left_eliminates_term
, right_eliminates_term
;
2053 if (GET_CODE (exp
) == AND
)
2055 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2056 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2057 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2059 newexp
= attr_rtx (AND
, left
, right
);
2061 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2065 else if (GET_CODE (exp
) == IOR
)
2067 /* For the IOR case, we do the same as above, except that we can
2068 only eliminate `term' if both sides of the IOR would do so. */
2070 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2071 left_eliminates_term
= (temp
== true_rtx
);
2074 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2075 right_eliminates_term
= (temp
== true_rtx
);
2077 if (left_eliminates_term
&& right_eliminates_term
)
2080 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2082 newexp
= attr_rtx (IOR
, left
, right
);
2084 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2088 /* Check for simplifications. Do some extra checking here since this
2089 routine is called so many times. */
2094 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2097 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2100 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2102 if (attr_alt_subset_p (*pterm
, exp
))
2105 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2108 if (attr_alt_subset_p (exp
, *pterm
))
2114 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2116 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2119 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2125 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2126 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2128 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2131 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2137 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2138 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2140 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2143 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2149 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2151 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2155 else if (GET_CODE (exp
) == NOT
)
2157 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2161 else if (GET_CODE (*pterm
) == NOT
)
2163 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2167 else if (attr_equal_p (exp
, *pterm
))
2173 /* Similar to `simplify_and_tree', but for IOR trees. */
2176 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2181 int left_eliminates_term
, right_eliminates_term
;
2183 if (GET_CODE (exp
) == IOR
)
2185 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2186 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2187 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2189 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2191 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2195 else if (GET_CODE (exp
) == AND
)
2197 /* For the AND case, we do the same as above, except that we can
2198 only eliminate `term' if both sides of the AND would do so. */
2200 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2201 left_eliminates_term
= (temp
== false_rtx
);
2204 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2205 right_eliminates_term
= (temp
== false_rtx
);
2207 if (left_eliminates_term
&& right_eliminates_term
)
2210 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2212 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2214 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2218 if (attr_equal_p (exp
, *pterm
))
2221 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2224 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2227 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2228 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2229 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2232 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2233 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2234 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2240 /* Compute approximate cost of the expression. Used to decide whether
2241 expression is cheap enough for inline. */
2243 attr_rtx_cost (rtx x
)
2249 code
= GET_CODE (x
);
2262 /* Alternatives don't result into function call. */
2263 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2270 const char *fmt
= GET_RTX_FORMAT (code
);
2271 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2277 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2278 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2281 cost
+= attr_rtx_cost (XEXP (x
, i
));
2291 /* Simplify test expression and use temporary obstack in order to avoid
2292 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2293 and avoid unnecessary copying if possible. */
2296 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2299 struct obstack
*old
;
2300 if (ATTR_IND_SIMPLIFIED_P (exp
))
2303 rtl_obstack
= temp_obstack
;
2304 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2306 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2308 return attr_copy_rtx (x
);
2311 /* Returns true if S1 is a subset of S2. */
2314 attr_alt_subset_p (rtx s1
, rtx s2
)
2316 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2319 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2322 return !(XINT (s1
, 0) & XINT (s2
, 0));
2328 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2335 /* Returns true if S1 is a subset of complement of S2. */
2338 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2340 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2343 return !(XINT (s1
, 0) & XINT (s2
, 0));
2346 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2349 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2359 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2362 attr_alt_intersection (rtx s1
, rtx s2
)
2364 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2366 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2369 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2372 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2375 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2378 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2383 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2388 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2391 attr_alt_union (rtx s1
, rtx s2
)
2393 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2395 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2398 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2401 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2404 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2407 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2413 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2417 /* Return EQ_ATTR_ALT expression representing complement of S. */
2420 attr_alt_complement (rtx s
)
2422 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2424 XINT (result
, 0) = XINT (s
, 0);
2425 XINT (result
, 1) = 1 - XINT (s
, 1);
2430 /* Return EQ_ATTR_ALT expression representing set containing elements set
2436 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2438 XINT (result
, 0) = e
;
2439 XINT (result
, 1) = 0;
2444 /* Given an expression, see if it can be simplified for a particular insn
2445 code based on the values of other attributes being tested. This can
2446 eliminate nested get_attr_... calls.
2448 Note that if an endless recursion is specified in the patterns, the
2449 optimization will loop. However, it will do so in precisely the cases where
2450 an infinite recursion loop could occur during compilation. It's better that
2454 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2457 struct attr_desc
*attr
;
2458 struct attr_value
*av
;
2459 struct insn_ent
*ie
;
2460 struct attr_value_list
*iv
;
2463 bool left_alt
, right_alt
;
2465 /* Don't re-simplify something we already simplified. */
2466 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2469 switch (GET_CODE (exp
))
2472 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2473 if (left
== false_rtx
)
2475 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2476 if (right
== false_rtx
)
2479 if (GET_CODE (left
) == EQ_ATTR_ALT
2480 && GET_CODE (right
) == EQ_ATTR_ALT
)
2482 exp
= attr_alt_intersection (left
, right
);
2483 return simplify_test_exp (exp
, insn_code
, insn_index
);
2486 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2487 present on both sides, apply the distributive law since this will
2488 yield simplifications. */
2489 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2490 && compute_alternative_mask (left
, IOR
)
2491 && compute_alternative_mask (right
, IOR
))
2493 if (GET_CODE (left
) == IOR
)
2500 newexp
= attr_rtx (IOR
,
2501 attr_rtx (AND
, left
, XEXP (right
, 0)),
2502 attr_rtx (AND
, left
, XEXP (right
, 1)));
2504 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2507 /* Try with the term on both sides. */
2508 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2509 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2510 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2512 if (left
== false_rtx
|| right
== false_rtx
)
2514 else if (left
== true_rtx
)
2518 else if (right
== true_rtx
)
2522 /* See if all or all but one of the insn's alternatives are specified
2523 in this tree. Optimize if so. */
2525 if (GET_CODE (left
) == NOT
)
2526 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2527 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2529 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2532 if (GET_CODE (right
) == NOT
)
2533 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2534 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2536 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2537 && XINT (right
, 1));
2540 && (GET_CODE (left
) == AND
2542 || GET_CODE (right
) == AND
2545 i
= compute_alternative_mask (exp
, AND
);
2546 if (i
& ~insn_alternatives
[insn_code
])
2547 fatal ("invalid alternative specified for pattern number %d",
2550 /* If all alternatives are excluded, this is false. */
2551 i
^= insn_alternatives
[insn_code
];
2554 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2556 /* If just one excluded, AND a comparison with that one to the
2557 front of the tree. The others will be eliminated by
2558 optimization. We do not want to do this if the insn has one
2559 alternative and we have tested none of them! */
2560 left
= make_alternative_compare (i
);
2561 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2562 newexp
= attr_rtx (AND
, left
, right
);
2564 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2568 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2570 newexp
= attr_rtx (AND
, left
, right
);
2571 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2576 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2577 if (left
== true_rtx
)
2579 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2580 if (right
== true_rtx
)
2583 if (GET_CODE (left
) == EQ_ATTR_ALT
2584 && GET_CODE (right
) == EQ_ATTR_ALT
)
2586 exp
= attr_alt_union (left
, right
);
2587 return simplify_test_exp (exp
, insn_code
, insn_index
);
2590 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2591 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2592 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2594 if (right
== true_rtx
|| left
== true_rtx
)
2596 else if (left
== false_rtx
)
2600 else if (right
== false_rtx
)
2605 /* Test for simple cases where the distributive law is useful. I.e.,
2606 convert (ior (and (x) (y))
2612 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2613 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2615 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2617 left
= XEXP (left
, 0);
2619 newexp
= attr_rtx (AND
, left
, right
);
2620 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2623 /* See if all or all but one of the insn's alternatives are specified
2624 in this tree. Optimize if so. */
2626 else if (insn_code
>= 0
2627 && (GET_CODE (left
) == IOR
2628 || (GET_CODE (left
) == EQ_ATTR_ALT
2630 || (GET_CODE (left
) == EQ_ATTR
2631 && XSTR (left
, 0) == alternative_name
)
2632 || GET_CODE (right
) == IOR
2633 || (GET_CODE (right
) == EQ_ATTR_ALT
2634 && !XINT (right
, 1))
2635 || (GET_CODE (right
) == EQ_ATTR
2636 && XSTR (right
, 0) == alternative_name
)))
2638 i
= compute_alternative_mask (exp
, IOR
);
2639 if (i
& ~insn_alternatives
[insn_code
])
2640 fatal ("invalid alternative specified for pattern number %d",
2643 /* If all alternatives are included, this is true. */
2644 i
^= insn_alternatives
[insn_code
];
2647 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2649 /* If just one excluded, IOR a comparison with that one to the
2650 front of the tree. The others will be eliminated by
2651 optimization. We do not want to do this if the insn has one
2652 alternative and we have tested none of them! */
2653 left
= make_alternative_compare (i
);
2654 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2655 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2657 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2661 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2663 newexp
= attr_rtx (IOR
, left
, right
);
2664 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2669 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2671 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2672 insn_code
, insn_index
);
2676 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2677 if (GET_CODE (left
) == NOT
)
2678 return XEXP (left
, 0);
2680 if (left
== false_rtx
)
2682 if (left
== true_rtx
)
2685 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2687 exp
= attr_alt_complement (left
);
2688 return simplify_test_exp (exp
, insn_code
, insn_index
);
2691 /* Try to apply De`Morgan's laws. */
2692 if (GET_CODE (left
) == IOR
)
2694 newexp
= attr_rtx (AND
,
2695 attr_rtx (NOT
, XEXP (left
, 0)),
2696 attr_rtx (NOT
, XEXP (left
, 1)));
2698 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2700 else if (GET_CODE (left
) == AND
)
2702 newexp
= attr_rtx (IOR
,
2703 attr_rtx (NOT
, XEXP (left
, 0)),
2704 attr_rtx (NOT
, XEXP (left
, 1)));
2706 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2708 else if (left
!= XEXP (exp
, 0))
2710 newexp
= attr_rtx (NOT
, left
);
2716 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2720 if (XSTR (exp
, 0) == alternative_name
)
2722 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2726 /* Look at the value for this insn code in the specified attribute.
2727 We normally can replace this comparison with the condition that
2728 would give this insn the values being tested for. */
2730 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2735 if (insn_code_values
)
2737 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2738 if (iv
->attr
== attr
)
2746 for (av
= attr
->first_value
; av
; av
= av
->next
)
2747 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2748 if (ie
->def
->insn_code
== insn_code
)
2755 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2756 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2757 if (attr_rtx_cost(x
) < 20)
2767 /* We have already simplified this expression. Simplifying it again
2768 won't buy anything unless we weren't given a valid insn code
2769 to process (i.e., we are canonicalizing something.). */
2771 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2772 return copy_rtx_unchanging (newexp
);
2777 /* Optimize the attribute lists by seeing if we can determine conditional
2778 values from the known values of other attributes. This will save subroutine
2779 calls during the compilation. */
2782 optimize_attrs (void)
2784 struct attr_desc
*attr
;
2785 struct attr_value
*av
;
2786 struct insn_ent
*ie
;
2789 struct attr_value_list
*ivbuf
;
2790 struct attr_value_list
*iv
;
2792 /* For each insn code, make a list of all the insn_ent's for it,
2793 for all values for all attributes. */
2795 if (num_insn_ents
== 0)
2798 /* Make 2 extra elements, for "code" values -2 and -1. */
2799 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2801 /* Offset the table address so we can index by -2 or -1. */
2802 insn_code_values
+= 2;
2804 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2806 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2807 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2808 for (av
= attr
->first_value
; av
; av
= av
->next
)
2809 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2814 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2815 insn_code_values
[ie
->def
->insn_code
] = iv
;
2819 /* Sanity check on num_insn_ents. */
2820 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2822 /* Process one insn code at a time. */
2823 for (i
= -2; i
< insn_code_number
; i
++)
2825 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2826 We use it to mean "already simplified for this insn". */
2827 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2828 clear_struct_flag (iv
->av
->value
);
2830 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2832 struct obstack
*old
= rtl_obstack
;
2837 if (GET_CODE (av
->value
) != COND
)
2840 rtl_obstack
= temp_obstack
;
2842 while (GET_CODE (newexp
) == COND
)
2844 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2845 ie
->def
->insn_index
);
2846 if (newexp2
== newexp
)
2852 if (newexp
!= av
->value
)
2854 newexp
= attr_copy_rtx (newexp
);
2855 remove_insn_ent (av
, ie
);
2856 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2858 insert_insn_ent (av
, ie
);
2864 free (insn_code_values
- 2);
2865 insn_code_values
= NULL
;
2868 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2871 clear_struct_flag (rtx x
)
2878 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2879 if (ATTR_IND_SIMPLIFIED_P (x
))
2882 code
= GET_CODE (x
);
2902 /* Compare the elements. If any pair of corresponding elements
2903 fail to match, return 0 for the whole things. */
2905 fmt
= GET_RTX_FORMAT (code
);
2906 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2912 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2913 clear_struct_flag (XVECEXP (x
, i
, j
));
2917 clear_struct_flag (XEXP (x
, i
));
2923 /* Create table entries for DEFINE_ATTR. */
2926 gen_attr (rtx exp
, int lineno
)
2928 struct attr_desc
*attr
;
2929 struct attr_value
*av
;
2930 const char *name_ptr
;
2933 /* Make a new attribute structure. Check for duplicate by looking at
2934 attr->default_val, since it is initialized by this routine. */
2935 attr
= find_attr (&XSTR (exp
, 0), 1);
2936 if (attr
->default_val
)
2938 message_with_line (lineno
, "duplicate definition for attribute %s",
2940 message_with_line (attr
->lineno
, "previous definition");
2944 attr
->lineno
= lineno
;
2946 if (*XSTR (exp
, 1) == '\0')
2947 attr
->is_numeric
= 1;
2950 name_ptr
= XSTR (exp
, 1);
2951 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
2953 av
= oballoc (sizeof (struct attr_value
));
2954 av
->value
= attr_rtx (CONST_STRING
, p
);
2955 av
->next
= attr
->first_value
;
2956 attr
->first_value
= av
;
2957 av
->first_insn
= NULL
;
2959 av
->has_asm_insn
= 0;
2963 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
2966 if (attr
->is_numeric
)
2968 message_with_line (lineno
,
2969 "constant attributes may not take numeric values");
2973 /* Get rid of the CONST node. It is allowed only at top-level. */
2974 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
2977 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
2979 message_with_line (lineno
,
2980 "`length' attribute must take numeric values");
2984 /* Set up the default value. */
2985 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
2986 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
2989 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2990 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2991 number of alternatives as this should be checked elsewhere. */
2994 count_alternatives (rtx exp
)
2999 if (GET_CODE (exp
) == MATCH_OPERAND
)
3000 return n_comma_elts (XSTR (exp
, 2));
3002 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3003 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3008 n
= count_alternatives (XEXP (exp
, i
));
3015 if (XVEC (exp
, i
) != NULL
)
3016 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3018 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3027 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3028 `alternative' attribute. */
3031 compares_alternatives_p (rtx exp
)
3036 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3039 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3040 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3045 if (compares_alternatives_p (XEXP (exp
, i
)))
3050 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3051 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3059 /* Returns nonzero is INNER is contained in EXP. */
3062 contained_in_p (rtx inner
, rtx exp
)
3067 if (rtx_equal_p (inner
, exp
))
3070 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3071 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3076 if (contained_in_p (inner
, XEXP (exp
, i
)))
3081 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3082 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
3090 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3093 gen_insn (rtx exp
, int lineno
)
3095 struct insn_def
*id
;
3097 id
= oballoc (sizeof (struct insn_def
));
3101 id
->lineno
= lineno
;
3103 switch (GET_CODE (exp
))
3106 id
->insn_code
= insn_code_number
;
3107 id
->insn_index
= insn_index_number
;
3108 id
->num_alternatives
= count_alternatives (exp
);
3109 if (id
->num_alternatives
== 0)
3110 id
->num_alternatives
= 1;
3114 case DEFINE_PEEPHOLE
:
3115 id
->insn_code
= insn_code_number
;
3116 id
->insn_index
= insn_index_number
;
3117 id
->num_alternatives
= count_alternatives (exp
);
3118 if (id
->num_alternatives
== 0)
3119 id
->num_alternatives
= 1;
3123 case DEFINE_ASM_ATTRIBUTES
:
3125 id
->insn_index
= -1;
3126 id
->num_alternatives
= 1;
3128 got_define_asm_attributes
= 1;
3136 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3137 true or annul false is specified, and make a `struct delay_desc'. */
3140 gen_delay (rtx def
, int lineno
)
3142 struct delay_desc
*delay
;
3145 if (XVECLEN (def
, 1) % 3 != 0)
3147 message_with_line (lineno
,
3148 "number of elements in DEFINE_DELAY must be multiple of three");
3153 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3155 if (XVECEXP (def
, 1, i
+ 1))
3156 have_annul_true
= 1;
3157 if (XVECEXP (def
, 1, i
+ 2))
3158 have_annul_false
= 1;
3161 delay
= oballoc (sizeof (struct delay_desc
));
3163 delay
->num
= ++num_delays
;
3164 delay
->next
= delays
;
3165 delay
->lineno
= lineno
;
3169 /* Given a piece of RTX, print a C expression to test its truth value.
3170 We use AND and IOR both for logical and bit-wise operations, so
3171 interpret them as logical unless they are inside a comparison expression.
3172 The first bit of FLAGS will be nonzero in that case.
3174 Set the second bit of FLAGS to make references to attribute values use
3175 a cached local variable instead of calling a function. */
3178 write_test_expr (rtx exp
, int flags
)
3180 int comparison_operator
= 0;
3182 struct attr_desc
*attr
;
3184 /* In order not to worry about operator precedence, surround our part of
3185 the expression with parentheses. */
3188 code
= GET_CODE (exp
);
3191 /* Binary operators. */
3194 printf ("(unsigned) ");
3200 comparison_operator
= 1;
3202 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3203 case AND
: case IOR
: case XOR
:
3204 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3205 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3221 printf (" >= (unsigned) ");
3224 printf (" > (unsigned) ");
3233 printf (" <= (unsigned) ");
3236 printf (" < (unsigned) ");
3279 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3283 /* Special-case (not (eq_attrq "alternative" "x")) */
3284 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3285 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3287 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3291 /* Otherwise, fall through to normal unary operator. */
3293 /* Unary operators. */
3313 write_test_expr (XEXP (exp
, 0), flags
);
3318 int set
= XINT (exp
, 0), bit
= 0;
3321 fatal ("EQ_ATTR_ALT not valid inside comparison");
3324 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3326 if (!(set
& (set
- 1)))
3328 if (!(set
& 0xffff))
3351 printf ("which_alternative %s= %d",
3352 XINT (exp
, 1) ? "!" : "=", bit
);
3356 printf ("%s((1 << which_alternative) & 0x%x)",
3357 XINT (exp
, 1) ? "!" : "", set
);
3362 /* Comparison test of an attribute with a value. Most of these will
3363 have been removed by optimization. Handle "alternative"
3364 specially and give error if EQ_ATTR present inside a comparison. */
3367 fatal ("EQ_ATTR not valid inside comparison");
3369 if (XSTR (exp
, 0) == alternative_name
)
3371 printf ("which_alternative == %s", XSTR (exp
, 1));
3375 attr
= find_attr (&XSTR (exp
, 0), 0);
3378 /* Now is the time to expand the value of a constant attribute. */
3381 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3388 printf ("attr_%s", attr
->name
);
3390 printf ("get_attr_%s (insn)", attr
->name
);
3392 write_attr_valueq (attr
, XSTR (exp
, 1));
3396 /* Comparison test of flags for define_delays. */
3399 fatal ("ATTR_FLAG not valid inside comparison");
3400 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3403 /* See if an operand matches a predicate. */
3405 /* If only a mode is given, just ensure the mode matches the operand.
3406 If neither a mode nor predicate is given, error. */
3407 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3409 if (GET_MODE (exp
) == VOIDmode
)
3410 fatal ("null MATCH_OPERAND specified as test");
3412 printf ("GET_MODE (operands[%d]) == %smode",
3413 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3416 printf ("%s (operands[%d], %smode)",
3417 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3420 /* Constant integer. */
3422 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3425 /* A random C expression. */
3427 print_c_condition (XSTR (exp
, 0));
3430 /* The address of the branch target. */
3432 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3433 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3437 /* The address of the current insn. We implement this actually as the
3438 address of the current insn for backward branches, but the last
3439 address of the next insn for forward branches, and both with
3440 adjustments that account for the worst-case possible stretching of
3441 intervening alignments between this insn and its destination. */
3442 printf ("insn_current_reference_address (insn)");
3446 printf ("%s", XSTR (exp
, 0));
3450 write_test_expr (XEXP (exp
, 0), flags
& 2);
3452 write_test_expr (XEXP (exp
, 1), flags
| 1);
3454 write_test_expr (XEXP (exp
, 2), flags
| 1);
3458 fatal ("bad RTX code `%s' in attribute calculation\n",
3459 GET_RTX_NAME (code
));
3465 /* Given an attribute value, return the maximum CONST_STRING argument
3466 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3469 max_attr_value (rtx exp
, int *unknownp
)
3474 switch (GET_CODE (exp
))
3477 current_max
= atoi (XSTR (exp
, 0));
3481 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3482 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3484 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3485 if (n
> current_max
)
3491 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3492 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3493 if (n
> current_max
)
3499 current_max
= INT_MAX
;
3506 /* Given an attribute value, return the minimum CONST_STRING argument
3507 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3510 min_attr_value (rtx exp
, int *unknownp
)
3515 switch (GET_CODE (exp
))
3518 current_min
= atoi (XSTR (exp
, 0));
3522 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3523 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3525 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3526 if (n
< current_min
)
3532 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3533 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3534 if (n
< current_min
)
3540 current_min
= INT_MAX
;
3547 /* Given an attribute value, return the result of ORing together all
3548 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3549 if the numeric value is not known. */
3552 or_attr_value (rtx exp
, int *unknownp
)
3557 switch (GET_CODE (exp
))
3560 current_or
= atoi (XSTR (exp
, 0));
3564 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3565 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3566 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3570 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3571 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3583 /* Scan an attribute value, possibly a conditional, and record what actions
3584 will be required to do any conditional tests in it.
3587 `must_extract' if we need to extract the insn operands
3588 `must_constrain' if we must compute `which_alternative'
3589 `address_used' if an address expression was used
3590 `length_used' if an (eq_attr "length" ...) was used
3594 walk_attr_value (rtx exp
)
3603 code
= GET_CODE (exp
);
3607 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3608 /* Since this is an arbitrary expression, it can look at anything.
3609 However, constant expressions do not depend on any particular
3611 must_extract
= must_constrain
= 1;
3619 must_extract
= must_constrain
= 1;
3623 if (XSTR (exp
, 0) == alternative_name
)
3624 must_extract
= must_constrain
= 1;
3625 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3645 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3650 walk_attr_value (XEXP (exp
, i
));
3654 if (XVEC (exp
, i
) != NULL
)
3655 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3656 walk_attr_value (XVECEXP (exp
, i
, j
));
3661 /* Write out a function to obtain the attribute for a given INSN. */
3664 write_attr_get (struct attr_desc
*attr
)
3666 struct attr_value
*av
, *common_av
;
3668 /* Find the most used attribute value. Handle that as the `default' of the
3669 switch we will generate. */
3670 common_av
= find_most_used (attr
);
3672 /* Write out start of function, then all values with explicit `case' lines,
3673 then a `default', then the value with the most uses. */
3674 if (!attr
->is_numeric
)
3675 printf ("enum attr_%s\n", attr
->name
);
3679 /* If the attribute name starts with a star, the remainder is the name of
3680 the subroutine to use, instead of `get_attr_...'. */
3681 if (attr
->name
[0] == '*')
3682 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3683 else if (attr
->is_const
== 0)
3684 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3687 printf ("get_attr_%s (void)\n", attr
->name
);
3690 for (av
= attr
->first_value
; av
; av
= av
->next
)
3691 if (av
->num_insns
== 1)
3692 write_attr_set (attr
, 2, av
->value
, "return", ";",
3693 true_rtx
, av
->first_insn
->def
->insn_code
,
3694 av
->first_insn
->def
->insn_index
);
3695 else if (av
->num_insns
!= 0)
3696 write_attr_set (attr
, 2, av
->value
, "return", ";",
3704 printf (" switch (recog_memoized (insn))\n");
3707 for (av
= attr
->first_value
; av
; av
= av
->next
)
3708 if (av
!= common_av
)
3709 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3711 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3712 printf (" }\n}\n\n");
3715 /* Given an AND tree of known true terms (because we are inside an `if' with
3716 that as the condition or are in an `else' clause) and an expression,
3717 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3718 the bulk of the work. */
3721 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3725 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3727 if (GET_CODE (known_true
) == AND
)
3729 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3730 insn_code
, insn_index
);
3731 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3732 insn_code
, insn_index
);
3737 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3743 /* Write out a series of tests and assignment statements to perform tests and
3744 sets of an attribute value. We are passed an indentation amount and prefix
3745 and suffix strings to write around each attribute value (e.g., "return"
3749 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3750 const char *prefix
, const char *suffix
, rtx known_true
,
3751 int insn_code
, int insn_index
)
3753 if (GET_CODE (value
) == COND
)
3755 /* Assume the default value will be the default of the COND unless we
3756 find an always true expression. */
3757 rtx default_val
= XEXP (value
, 1);
3758 rtx our_known_true
= known_true
;
3763 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3768 testexp
= eliminate_known_true (our_known_true
,
3769 XVECEXP (value
, 0, i
),
3770 insn_code
, insn_index
);
3771 newexp
= attr_rtx (NOT
, testexp
);
3772 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3773 insn_code
, insn_index
);
3775 /* If the test expression is always true or if the next `known_true'
3776 expression is always false, this is the last case, so break
3777 out and let this value be the `else' case. */
3778 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3780 default_val
= XVECEXP (value
, 0, i
+ 1);
3784 /* Compute the expression to pass to our recursive call as being
3786 inner_true
= insert_right_side (AND
, our_known_true
,
3787 testexp
, insn_code
, insn_index
);
3789 /* If this is always false, skip it. */
3790 if (inner_true
== false_rtx
)
3793 write_indent (indent
);
3794 printf ("%sif ", first_if
? "" : "else ");
3796 write_test_expr (testexp
, 0);
3798 write_indent (indent
+ 2);
3801 write_attr_set (attr
, indent
+ 4,
3802 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3803 inner_true
, insn_code
, insn_index
);
3804 write_indent (indent
+ 2);
3806 our_known_true
= newexp
;
3811 write_indent (indent
);
3813 write_indent (indent
+ 2);
3817 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
3818 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
3822 write_indent (indent
+ 2);
3828 write_indent (indent
);
3829 printf ("%s ", prefix
);
3830 write_attr_value (attr
, value
);
3831 printf ("%s\n", suffix
);
3835 /* Write a series of case statements for every instruction in list IE.
3836 INDENT is the amount of indentation to write before each case. */
3839 write_insn_cases (struct insn_ent
*ie
, int indent
)
3841 for (; ie
!= 0; ie
= ie
->next
)
3842 if (ie
->def
->insn_code
!= -1)
3844 write_indent (indent
);
3845 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
3846 printf ("case %d: /* define_peephole, line %d */\n",
3847 ie
->def
->insn_code
, ie
->def
->lineno
);
3849 printf ("case %d: /* %s */\n",
3850 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
3854 /* Write out the computation for one attribute value. */
3857 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
3858 int write_case_lines
, const char *prefix
, const char *suffix
,
3859 int indent
, rtx known_true
)
3861 if (av
->num_insns
== 0)
3864 if (av
->has_asm_insn
)
3866 write_indent (indent
);
3867 printf ("case -1:\n");
3868 write_indent (indent
+ 2);
3869 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3870 write_indent (indent
+ 2);
3871 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3872 write_indent (indent
+ 2);
3873 printf (" fatal_insn_not_found (insn);\n");
3876 if (write_case_lines
)
3877 write_insn_cases (av
->first_insn
, indent
);
3880 write_indent (indent
);
3881 printf ("default:\n");
3884 /* See what we have to do to output this value. */
3885 must_extract
= must_constrain
= address_used
= 0;
3886 walk_attr_value (av
->value
);
3890 write_indent (indent
+ 2);
3891 printf ("extract_constrain_insn_cached (insn);\n");
3893 else if (must_extract
)
3895 write_indent (indent
+ 2);
3896 printf ("extract_insn_cached (insn);\n");
3899 if (av
->num_insns
== 1)
3900 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3901 known_true
, av
->first_insn
->def
->insn_code
,
3902 av
->first_insn
->def
->insn_index
);
3904 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3907 if (strncmp (prefix
, "return", 6))
3909 write_indent (indent
+ 2);
3910 printf ("break;\n");
3915 /* Search for uses of non-const attributes and write code to cache them. */
3918 write_expr_attr_cache (rtx p
, struct attr_desc
*attr
)
3923 if (GET_CODE (p
) == EQ_ATTR
)
3925 if (XSTR (p
, 0) != attr
->name
)
3928 if (!attr
->is_numeric
)
3929 printf (" enum attr_%s ", attr
->name
);
3933 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
3937 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
3938 ie
= GET_RTX_LENGTH (GET_CODE (p
));
3939 for (i
= 0; i
< ie
; i
++)
3944 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
3949 je
= XVECLEN (p
, i
);
3950 for (j
= 0; j
< je
; ++j
)
3951 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
3960 /* Utilities to write in various forms. */
3963 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
3965 if (attr
->is_numeric
)
3971 if (num
> 9 || num
< 0)
3972 printf (" /* 0x%x */", num
);
3976 write_upcase (attr
->name
);
3983 write_attr_value (struct attr_desc
*attr
, rtx value
)
3987 switch (GET_CODE (value
))
3990 write_attr_valueq (attr
, XSTR (value
, 0));
3994 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
3998 print_c_condition (XSTR (value
, 0));
4003 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4004 printf ("get_attr_%s (%s)", attr2
->name
,
4005 (attr2
->is_const
? "" : "insn"));
4026 write_attr_value (attr
, XEXP (value
, 0));
4030 write_attr_value (attr
, XEXP (value
, 1));
4039 write_upcase (const char *str
)
4043 /* The argument of TOUPPER should not have side effects. */
4044 putchar (TOUPPER(*str
));
4050 write_indent (int indent
)
4052 for (; indent
> 8; indent
-= 8)
4055 for (; indent
; indent
--)
4059 /* Write a subroutine that is given an insn that requires a delay slot, a
4060 delay slot ordinal, and a candidate insn. It returns nonzero if the
4061 candidate can be placed in the specified delay slot of the insn.
4063 We can write as many as three subroutines. `eligible_for_delay'
4064 handles normal delay slots, `eligible_for_annul_true' indicates that
4065 the specified insn can be annulled if the branch is true, and likewise
4066 for `eligible_for_annul_false'.
4068 KIND is a string distinguishing these three cases ("delay", "annul_true",
4069 or "annul_false"). */
4072 write_eligible_delay (const char *kind
)
4074 struct delay_desc
*delay
;
4078 struct attr_desc
*attr
;
4079 struct attr_value
*av
, *common_av
;
4082 /* Compute the maximum number of delay slots required. We use the delay
4083 ordinal times this number plus one, plus the slot number as an index into
4084 the appropriate predicate to test. */
4086 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4087 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4088 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4090 /* Write function prelude. */
4093 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4096 printf (" rtx insn;\n");
4098 printf (" gcc_assert (slot < %d);\n", max_slots
);
4100 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4101 converts a compound instruction into a loop. */
4102 printf (" if (!INSN_P (candidate_insn))\n");
4103 printf (" return 0;\n");
4106 /* If more than one delay type, find out which type the delay insn is. */
4110 attr
= find_attr (&delay_type_str
, 0);
4112 common_av
= find_most_used (attr
);
4114 printf (" insn = delay_insn;\n");
4115 printf (" switch (recog_memoized (insn))\n");
4118 sprintf (str
, " * %d;\n break;", max_slots
);
4119 for (av
= attr
->first_value
; av
; av
= av
->next
)
4120 if (av
!= common_av
)
4121 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4123 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4126 /* Ensure matched. Otherwise, shouldn't have been called. */
4127 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4130 /* If just one type of delay slot, write simple switch. */
4131 if (num_delays
== 1 && max_slots
== 1)
4133 printf (" insn = candidate_insn;\n");
4134 printf (" switch (recog_memoized (insn))\n");
4137 attr
= find_attr (&delay_1_0_str
, 0);
4139 common_av
= find_most_used (attr
);
4141 for (av
= attr
->first_value
; av
; av
= av
->next
)
4142 if (av
!= common_av
)
4143 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4145 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4151 /* Write a nested CASE. The first indicates which condition we need to
4152 test, and the inner CASE tests the condition. */
4153 printf (" insn = candidate_insn;\n");
4154 printf (" switch (slot)\n");
4157 for (delay
= delays
; delay
; delay
= delay
->next
)
4158 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4160 printf (" case %d:\n",
4161 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4162 printf (" switch (recog_memoized (insn))\n");
4165 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4167 attr
= find_attr (&pstr
, 0);
4169 common_av
= find_most_used (attr
);
4171 for (av
= attr
->first_value
; av
; av
= av
->next
)
4172 if (av
!= common_av
)
4173 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4175 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4179 printf (" default:\n");
4180 printf (" gcc_unreachable ();\n");
4187 /* This page contains miscellaneous utility routines. */
4189 /* Given a pointer to a (char *), return a malloc'ed string containing the
4190 next comma-separated element. Advance the pointer to after the string
4191 scanned, or the end-of-string. Return NULL if at end of string. */
4194 next_comma_elt (const char **pstr
)
4198 start
= scan_comma_elt (pstr
);
4203 return attr_string (start
, *pstr
- start
);
4206 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4207 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4208 replaced by a pointer to a canonical copy of the string. */
4210 static struct attr_desc
*
4211 find_attr (const char **name_p
, int create
)
4213 struct attr_desc
*attr
;
4215 const char *name
= *name_p
;
4217 /* Before we resort to using `strcmp', see if the string address matches
4218 anywhere. In most cases, it should have been canonicalized to do so. */
4219 if (name
== alternative_name
)
4222 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4223 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4224 if (name
== attr
->name
)
4227 /* Otherwise, do it the slow way. */
4228 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4229 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4231 *name_p
= attr
->name
;
4238 attr
= oballoc (sizeof (struct attr_desc
));
4239 attr
->name
= DEF_ATTR_STRING (name
);
4240 attr
->first_value
= attr
->default_val
= NULL
;
4241 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4242 attr
->next
= attrs
[index
];
4243 attrs
[index
] = attr
;
4245 *name_p
= attr
->name
;
4250 /* Create internal attribute with the given default value. */
4253 make_internal_attr (const char *name
, rtx value
, int special
)
4255 struct attr_desc
*attr
;
4257 attr
= find_attr (&name
, 1);
4258 gcc_assert (!attr
->default_val
);
4260 attr
->is_numeric
= 1;
4262 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4263 attr
->default_val
= get_attr_value (value
, attr
, -2);
4266 /* Find the most used value of an attribute. */
4268 static struct attr_value
*
4269 find_most_used (struct attr_desc
*attr
)
4271 struct attr_value
*av
;
4272 struct attr_value
*most_used
;
4278 for (av
= attr
->first_value
; av
; av
= av
->next
)
4279 if (av
->num_insns
> nuses
)
4280 nuses
= av
->num_insns
, most_used
= av
;
4285 /* Return (attr_value "n") */
4288 make_numeric_value (int n
)
4290 static rtx int_values
[20];
4294 gcc_assert (n
>= 0);
4296 if (n
< 20 && int_values
[n
])
4297 return int_values
[n
];
4299 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4300 exp
= attr_rtx (CONST_STRING
, p
);
4303 int_values
[n
] = exp
;
4309 copy_rtx_unchanging (rtx orig
)
4311 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4314 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4318 /* Determine if an insn has a constant number of delay slots, i.e., the
4319 number of delay slots is not a function of the length of the insn. */
4322 write_const_num_delay_slots (void)
4324 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4325 struct attr_value
*av
;
4329 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4331 printf (" switch (recog_memoized (insn))\n");
4334 for (av
= attr
->first_value
; av
; av
= av
->next
)
4337 walk_attr_value (av
->value
);
4339 write_insn_cases (av
->first_insn
, 4);
4342 printf (" default:\n");
4343 printf (" return 1;\n");
4344 printf (" }\n}\n\n");
4348 /* Synthetic attributes used by insn-automata.c and the scheduler.
4349 These are primarily concerned with (define_insn_reservation)
4354 struct insn_reserv
*next
;
4357 int default_latency
;
4360 /* Sequence number of this insn. */
4363 /* Whether a (define_bypass) construct names this insn in its
4368 static struct insn_reserv
*all_insn_reservs
= 0;
4369 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4370 static size_t n_insn_reservs
;
4372 /* Store information from a DEFINE_INSN_RESERVATION for future
4373 attribute generation. */
4375 gen_insn_reserv (rtx def
)
4377 struct insn_reserv
*decl
= oballoc (sizeof (struct insn_reserv
));
4379 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4380 decl
->default_latency
= XINT (def
, 1);
4381 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4382 decl
->insn_num
= n_insn_reservs
;
4383 decl
->bypassed
= false;
4386 *last_insn_reserv_p
= decl
;
4387 last_insn_reserv_p
= &decl
->next
;
4391 /* Store information from a DEFINE_BYPASS for future attribute
4392 generation. The only thing we care about is the list of output
4393 insns, which will later be used to tag reservation structures with
4394 a 'bypassed' bit. */
4398 struct bypass_list
*next
;
4402 static struct bypass_list
*all_bypasses
;
4403 static size_t n_bypasses
;
4406 gen_bypass_1 (const char *s
, size_t len
)
4408 struct bypass_list
*b
;
4413 s
= attr_string (s
, len
);
4414 for (b
= all_bypasses
; b
; b
= b
->next
)
4416 return; /* already got that one */
4418 b
= oballoc (sizeof (struct bypass_list
));
4420 b
->next
= all_bypasses
;
4426 gen_bypass (rtx def
)
4428 const char *p
, *base
;
4430 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4433 gen_bypass_1 (base
, p
- base
);
4436 while (ISSPACE (*p
));
4439 gen_bypass_1 (base
, p
- base
);
4442 /* Find and mark all of the bypassed insns. */
4444 process_bypasses (void)
4446 struct bypass_list
*b
;
4447 struct insn_reserv
*r
;
4449 /* The reservation list is likely to be much longer than the bypass
4451 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4452 for (b
= all_bypasses
; b
; b
= b
->next
)
4453 if (r
->name
== b
->insn
)
4457 /* Create all of the attributes that describe automaton properties. */
4459 make_automaton_attrs (void)
4462 struct insn_reserv
*decl
;
4463 rtx code_exp
, lats_exp
, byps_exp
;
4465 if (n_insn_reservs
== 0)
4468 code_exp
= rtx_alloc (COND
);
4469 lats_exp
= rtx_alloc (COND
);
4471 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4472 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4474 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4475 XEXP (lats_exp
, 1) = make_numeric_value (0);
4477 for (decl
= all_insn_reservs
, i
= 0;
4479 decl
= decl
->next
, i
+= 2)
4481 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
4482 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
4484 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
4485 XVECEXP (lats_exp
, 0, i
+1) = make_numeric_value (decl
->default_latency
);
4488 if (n_bypasses
== 0)
4489 byps_exp
= make_numeric_value (0);
4492 process_bypasses ();
4494 byps_exp
= rtx_alloc (COND
);
4495 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypasses
* 2);
4496 XEXP (byps_exp
, 1) = make_numeric_value (0);
4497 for (decl
= all_insn_reservs
, i
= 0;
4502 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
4503 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
4508 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
4509 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
4510 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
4514 main (int argc
, char **argv
)
4517 struct attr_desc
*attr
;
4518 struct insn_def
*id
;
4522 progname
= "genattrtab";
4524 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
4525 return (FATAL_EXIT_CODE
);
4527 obstack_init (hash_obstack
);
4528 obstack_init (temp_obstack
);
4530 /* Set up true and false rtx's */
4531 true_rtx
= rtx_alloc (CONST_INT
);
4532 XWINT (true_rtx
, 0) = 1;
4533 false_rtx
= rtx_alloc (CONST_INT
);
4534 XWINT (false_rtx
, 0) = 0;
4535 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4536 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4538 alternative_name
= DEF_ATTR_STRING ("alternative");
4539 length_str
= DEF_ATTR_STRING ("length");
4540 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4541 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4542 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4544 printf ("/* Generated automatically by the program `genattrtab'\n\
4545 from the machine description file `md'. */\n\n");
4547 /* Read the machine description. */
4553 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4557 switch (GET_CODE (desc
))
4560 case DEFINE_PEEPHOLE
:
4561 case DEFINE_ASM_ATTRIBUTES
:
4562 gen_insn (desc
, lineno
);
4566 gen_attr (desc
, lineno
);
4570 gen_delay (desc
, lineno
);
4573 case DEFINE_INSN_RESERVATION
:
4574 gen_insn_reserv (desc
);
4584 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4585 insn_index_number
++;
4589 return FATAL_EXIT_CODE
;
4593 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4594 if (! got_define_asm_attributes
)
4596 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4597 XVEC (tem
, 0) = rtvec_alloc (0);
4601 /* Expand DEFINE_DELAY information into new attribute. */
4605 printf ("#include \"config.h\"\n");
4606 printf ("#include \"system.h\"\n");
4607 printf ("#include \"coretypes.h\"\n");
4608 printf ("#include \"tm.h\"\n");
4609 printf ("#include \"rtl.h\"\n");
4610 printf ("#include \"tm_p.h\"\n");
4611 printf ("#include \"insn-config.h\"\n");
4612 printf ("#include \"recog.h\"\n");
4613 printf ("#include \"regs.h\"\n");
4614 printf ("#include \"real.h\"\n");
4615 printf ("#include \"output.h\"\n");
4616 printf ("#include \"insn-attr.h\"\n");
4617 printf ("#include \"toplev.h\"\n");
4618 printf ("#include \"flags.h\"\n");
4619 printf ("#include \"function.h\"\n");
4621 printf ("#define operands recog_data.operand\n\n");
4623 /* Make `insn_alternatives'. */
4624 insn_alternatives
= oballoc (insn_code_number
* sizeof (int));
4625 for (id
= defs
; id
; id
= id
->next
)
4626 if (id
->insn_code
>= 0)
4627 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4629 /* Make `insn_n_alternatives'. */
4630 insn_n_alternatives
= oballoc (insn_code_number
* sizeof (int));
4631 for (id
= defs
; id
; id
= id
->next
)
4632 if (id
->insn_code
>= 0)
4633 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4635 /* Construct extra attributes for automata. */
4636 make_automaton_attrs ();
4638 /* Prepare to write out attribute subroutines by checking everything stored
4639 away and building the attribute cases. */
4643 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4644 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4645 attr
->default_val
->value
4646 = check_attr_value (attr
->default_val
->value
, attr
);
4649 return FATAL_EXIT_CODE
;
4651 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4652 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4655 /* Construct extra attributes for `length'. */
4656 make_length_attrs ();
4658 /* Perform any possible optimizations to speed up compilation. */
4661 /* Now write out all the `gen_attr_...' routines. Do these before the
4662 special routines so that they get defined before they are used. */
4664 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4665 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4667 if (! attr
->is_special
&& ! attr
->is_const
)
4668 write_attr_get (attr
);
4671 /* Write out delay eligibility information, if DEFINE_DELAY present.
4672 (The function to compute the number of delay slots will be written
4676 write_eligible_delay ("delay");
4677 if (have_annul_true
)
4678 write_eligible_delay ("annul_true");
4679 if (have_annul_false
)
4680 write_eligible_delay ("annul_false");
4683 /* Write out constant delay slot info. */
4684 write_const_num_delay_slots ();
4686 write_length_unit_log ();
4689 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);