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 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 /* Listheads of above structures. */
194 /* This one is indexed by the first character of the attribute name. */
195 #define MAX_ATTRS_INDEX 256
196 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
197 static struct insn_def
*defs
;
198 static struct delay_desc
*delays
;
200 /* Other variables. */
202 static int insn_code_number
;
203 static int insn_index_number
;
204 static int got_define_asm_attributes
;
205 static int must_extract
;
206 static int must_constrain
;
207 static int address_used
;
208 static int length_used
;
209 static int num_delays
;
210 static int have_annul_true
, have_annul_false
;
211 static int num_insn_ents
;
213 /* Stores, for each insn code, the number of constraint alternatives. */
215 static int *insn_n_alternatives
;
217 /* Stores, for each insn code, a bitmap that has bits on for each possible
220 static int *insn_alternatives
;
222 /* Used to simplify expressions. */
224 static rtx true_rtx
, false_rtx
;
226 /* Used to reduce calls to `strcmp' */
228 static const char *alternative_name
;
229 static const char *length_str
;
230 static const char *delay_type_str
;
231 static const char *delay_1_0_str
;
232 static const char *num_delay_slots_str
;
234 /* Simplify an expression. Only call the routine if there is something to
236 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
237 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
238 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
240 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
242 /* Forward declarations of functions used before their definitions, only. */
243 static char *attr_string (const char *, int);
244 static char *attr_printf (unsigned int, const char *, ...)
246 static rtx
make_numeric_value (int);
247 static struct attr_desc
*find_attr (const char **, int);
248 static rtx
mk_attr_alt (int);
249 static char *next_comma_elt (const char **);
250 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
251 static rtx
copy_boolean (rtx
);
252 static int compares_alternatives_p (rtx
);
253 static void make_internal_attr (const char *, rtx
, int);
254 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
255 static void walk_attr_value (rtx
);
256 static int max_attr_value (rtx
, int*);
257 static int min_attr_value (rtx
, int*);
258 static int or_attr_value (rtx
, int*);
259 static rtx
simplify_test_exp (rtx
, int, int);
260 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
261 static rtx
copy_rtx_unchanging (rtx
);
262 static bool attr_alt_subset_p (rtx
, rtx
);
263 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
264 static void clear_struct_flag (rtx
);
265 static void write_attr_valueq (struct attr_desc
*, const char *);
266 static struct attr_value
*find_most_used (struct attr_desc
*);
267 static void write_attr_set (struct attr_desc
*, int, rtx
,
268 const char *, const char *, rtx
,
270 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
271 int, const char *, const char *, int, rtx
);
272 static void write_attr_value (struct attr_desc
*, rtx
);
273 static void write_upcase (const char *);
274 static void write_indent (int);
275 static rtx
identity_fn (rtx
);
276 static rtx
zero_fn (rtx
);
277 static rtx
one_fn (rtx
);
278 static rtx
max_fn (rtx
);
279 static rtx
min_fn (rtx
);
281 #define oballoc(size) obstack_alloc (hash_obstack, size)
283 /* Hash table for sharing RTL and strings. */
285 /* Each hash table slot is a bucket containing a chain of these structures.
286 Strings are given negative hash codes; RTL expressions are given positive
291 struct attr_hash
*next
; /* Next structure in the bucket. */
292 int hashcode
; /* Hash code of this rtx or string. */
295 char *str
; /* The string (negative hash codes) */
296 rtx rtl
; /* or the RTL recorded here. */
300 /* Now here is the hash table. When recording an RTL, it is added to
301 the slot whose index is the hash code mod the table size. Note
302 that the hash table is used for several kinds of RTL (see attr_rtx)
303 and for strings. While all these live in the same table, they are
304 completely independent, and the hash code is computed differently
307 #define RTL_HASH_SIZE 4093
308 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
310 /* Here is how primitive or already-shared RTL's hash
312 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
314 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
317 attr_hash_add_rtx (int hashcode
, rtx rtl
)
321 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
322 h
->hashcode
= hashcode
;
324 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
325 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
328 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
331 attr_hash_add_string (int hashcode
, char *str
)
335 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
336 h
->hashcode
= -hashcode
;
338 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
339 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
342 /* Generate an RTL expression, but avoid duplicates.
343 Set the ATTR_PERMANENT_P flag for these permanent objects.
345 In some cases we cannot uniquify; then we return an ordinary
346 impermanent rtx with ATTR_PERMANENT_P clear.
350 rtx attr_rtx (code, [element1, ..., elementn]) */
353 attr_rtx_1 (enum rtx_code code
, va_list p
)
355 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
358 struct obstack
*old_obstack
= rtl_obstack
;
360 /* For each of several cases, search the hash table for an existing entry.
361 Use that entry if one is found; otherwise create a new RTL and add it
364 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
366 rtx arg0
= va_arg (p
, rtx
);
368 /* A permanent object cannot point to impermanent ones. */
369 if (! ATTR_PERMANENT_P (arg0
))
371 rt_val
= rtx_alloc (code
);
372 XEXP (rt_val
, 0) = arg0
;
376 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
377 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
378 if (h
->hashcode
== hashcode
379 && GET_CODE (h
->u
.rtl
) == code
380 && XEXP (h
->u
.rtl
, 0) == arg0
)
385 rtl_obstack
= hash_obstack
;
386 rt_val
= rtx_alloc (code
);
387 XEXP (rt_val
, 0) = arg0
;
390 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
391 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
392 || GET_RTX_CLASS (code
) == RTX_COMPARE
393 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
395 rtx arg0
= va_arg (p
, rtx
);
396 rtx arg1
= va_arg (p
, rtx
);
398 /* A permanent object cannot point to impermanent ones. */
399 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
401 rt_val
= rtx_alloc (code
);
402 XEXP (rt_val
, 0) = arg0
;
403 XEXP (rt_val
, 1) = arg1
;
407 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
408 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
409 if (h
->hashcode
== hashcode
410 && GET_CODE (h
->u
.rtl
) == code
411 && XEXP (h
->u
.rtl
, 0) == arg0
412 && XEXP (h
->u
.rtl
, 1) == arg1
)
417 rtl_obstack
= hash_obstack
;
418 rt_val
= rtx_alloc (code
);
419 XEXP (rt_val
, 0) = arg0
;
420 XEXP (rt_val
, 1) = arg1
;
423 else if (GET_RTX_LENGTH (code
) == 1
424 && GET_RTX_FORMAT (code
)[0] == 's')
426 char *arg0
= va_arg (p
, char *);
428 arg0
= DEF_ATTR_STRING (arg0
);
430 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
431 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
432 if (h
->hashcode
== hashcode
433 && GET_CODE (h
->u
.rtl
) == code
434 && XSTR (h
->u
.rtl
, 0) == arg0
)
439 rtl_obstack
= hash_obstack
;
440 rt_val
= rtx_alloc (code
);
441 XSTR (rt_val
, 0) = arg0
;
444 else if (GET_RTX_LENGTH (code
) == 2
445 && GET_RTX_FORMAT (code
)[0] == 's'
446 && GET_RTX_FORMAT (code
)[1] == 's')
448 char *arg0
= va_arg (p
, char *);
449 char *arg1
= va_arg (p
, char *);
451 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
452 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
453 if (h
->hashcode
== hashcode
454 && GET_CODE (h
->u
.rtl
) == code
455 && XSTR (h
->u
.rtl
, 0) == arg0
456 && XSTR (h
->u
.rtl
, 1) == arg1
)
461 rtl_obstack
= hash_obstack
;
462 rt_val
= rtx_alloc (code
);
463 XSTR (rt_val
, 0) = arg0
;
464 XSTR (rt_val
, 1) = arg1
;
467 else if (code
== CONST_INT
)
469 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
479 int i
; /* Array indices... */
480 const char *fmt
; /* Current rtx's format... */
482 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
484 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
485 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
489 case '0': /* Unused field. */
492 case 'i': /* An integer? */
493 XINT (rt_val
, i
) = va_arg (p
, int);
496 case 'w': /* A wide integer? */
497 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
500 case 's': /* A string? */
501 XSTR (rt_val
, i
) = va_arg (p
, char *);
504 case 'e': /* An expression? */
505 case 'u': /* An insn? Same except when printing. */
506 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
509 case 'E': /* An RTX vector? */
510 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
520 rtl_obstack
= old_obstack
;
521 attr_hash_add_rtx (hashcode
, rt_val
);
522 ATTR_PERMANENT_P (rt_val
) = 1;
527 attr_rtx (enum rtx_code code
, ...)
533 result
= attr_rtx_1 (code
, p
);
538 /* Create a new string printed with the printf line arguments into a space
539 of at most LEN bytes:
541 rtx attr_printf (len, format, [arg1, ..., argn]) */
544 attr_printf (unsigned int len
, const char *fmt
, ...)
551 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
553 vsprintf (str
, fmt
, p
);
556 return DEF_ATTR_STRING (str
);
560 attr_eq (const char *name
, const char *value
)
562 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
568 return XSTR (make_numeric_value (n
), 0);
571 /* Return a permanent (possibly shared) copy of a string STR (not assumed
572 to be null terminated) with LEN bytes. */
575 attr_string (const char *str
, int len
)
582 /* Compute the hash code. */
583 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
584 for (i
= 1; i
< len
; i
+= 2)
585 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
587 hashcode
= -hashcode
;
589 /* Search the table for the string. */
590 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
591 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
592 && !strncmp (h
->u
.str
, str
, len
))
593 return h
->u
.str
; /* <-- return if found. */
595 /* Not found; create a permanent copy and add it to the hash table. */
596 new_str
= obstack_alloc (hash_obstack
, len
+ 1);
597 memcpy (new_str
, str
, len
);
599 attr_hash_add_string (hashcode
, new_str
);
601 return new_str
; /* Return the new string. */
604 /* Check two rtx's for equality of contents,
605 taking advantage of the fact that if both are hashed
606 then they can't be equal unless they are the same object. */
609 attr_equal_p (rtx x
, rtx y
)
611 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
612 && rtx_equal_p (x
, y
)));
615 /* Copy an attribute value expression,
616 descending to all depths, but not copying any
617 permanent hashed subexpressions. */
620 attr_copy_rtx (rtx orig
)
625 const char *format_ptr
;
627 /* No need to copy a permanent object. */
628 if (ATTR_PERMANENT_P (orig
))
631 code
= GET_CODE (orig
);
649 copy
= rtx_alloc (code
);
650 PUT_MODE (copy
, GET_MODE (orig
));
651 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
652 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
653 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
655 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
657 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
659 switch (*format_ptr
++)
662 XEXP (copy
, i
) = XEXP (orig
, i
);
663 if (XEXP (orig
, i
) != NULL
)
664 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
669 XVEC (copy
, i
) = XVEC (orig
, i
);
670 if (XVEC (orig
, i
) != NULL
)
672 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
673 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
674 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
680 XINT (copy
, i
) = XINT (orig
, i
);
684 XWINT (copy
, i
) = XWINT (orig
, i
);
689 XSTR (copy
, i
) = XSTR (orig
, i
);
699 /* Given a test expression for an attribute, ensure it is validly formed.
700 IS_CONST indicates whether the expression is constant for each compiler
701 run (a constant expression may not test any particular insn).
703 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
704 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
705 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
707 Update the string address in EQ_ATTR expression to be the same used
708 in the attribute (or `alternative_name') to speed up subsequent
709 `find_attr' calls and eliminate most `strcmp' calls.
711 Return the new expression, if any. */
714 check_attr_test (rtx exp
, int is_const
, int lineno
)
716 struct attr_desc
*attr
;
717 struct attr_value
*av
;
718 const char *name_ptr
, *p
;
721 switch (GET_CODE (exp
))
724 /* Handle negation test. */
725 if (XSTR (exp
, 1)[0] == '!')
726 return check_attr_test (attr_rtx (NOT
,
727 attr_eq (XSTR (exp
, 0),
731 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
733 attr
= find_attr (&XSTR (exp
, 0), 0);
736 if (! strcmp (XSTR (exp
, 0), "alternative"))
737 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
739 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
742 if (is_const
&& ! attr
->is_const
)
743 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
746 /* Copy this just to make it permanent,
747 so expressions using it can be permanent too. */
748 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
750 /* It shouldn't be possible to simplify the value given to a
751 constant attribute, so don't expand this until it's time to
752 write the test expression. */
754 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
756 if (attr
->is_numeric
)
758 for (p
= XSTR (exp
, 1); *p
; p
++)
760 fatal ("attribute `%s' takes only numeric values",
765 for (av
= attr
->first_value
; av
; av
= av
->next
)
766 if (GET_CODE (av
->value
) == CONST_STRING
767 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
771 fatal ("unknown value `%s' for `%s' attribute",
772 XSTR (exp
, 1), XSTR (exp
, 0));
777 if (! strcmp (XSTR (exp
, 0), "alternative"))
781 name_ptr
= XSTR (exp
, 1);
782 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
783 set
|= 1 << atoi (p
);
785 return mk_attr_alt (set
);
789 /* Make an IOR tree of the possible values. */
791 name_ptr
= XSTR (exp
, 1);
792 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
794 newexp
= attr_eq (XSTR (exp
, 0), p
);
795 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
798 return check_attr_test (orexp
, is_const
, lineno
);
807 /* Either TRUE or FALSE. */
815 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
816 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
820 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
825 fatal ("RTL operator \"%s\" not valid in constant attribute test",
826 GET_RTX_NAME (GET_CODE (exp
)));
827 /* These cases can't be simplified. */
828 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
831 case LE
: case LT
: case GT
: case GE
:
832 case LEU
: case LTU
: case GTU
: case GEU
:
834 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
835 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
836 exp
= attr_rtx (GET_CODE (exp
),
837 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
838 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
839 /* These cases can't be simplified. */
840 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
846 /* These cases are valid for constant attributes, but can't be
848 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
849 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
853 fatal ("RTL operator \"%s\" not valid in attribute test",
854 GET_RTX_NAME (GET_CODE (exp
)));
860 /* Given an expression, ensure that it is validly formed and that all named
861 attribute values are valid for the given attribute. Issue a fatal error
862 if not. If no attribute is specified, assume a numeric attribute.
864 Return a perhaps modified replacement expression for the value. */
867 check_attr_value (rtx exp
, struct attr_desc
*attr
)
869 struct attr_value
*av
;
873 switch (GET_CODE (exp
))
876 if (attr
&& ! attr
->is_numeric
)
878 message_with_line (attr
->lineno
,
879 "CONST_INT not valid for non-numeric attribute %s",
885 if (INTVAL (exp
) < 0)
887 message_with_line (attr
->lineno
,
888 "negative numeric value specified for attribute %s",
896 if (! strcmp (XSTR (exp
, 0), "*"))
899 if (attr
== 0 || attr
->is_numeric
)
905 message_with_line (attr
? attr
->lineno
: 0,
906 "non-numeric value for numeric attribute %s",
907 attr
? attr
->name
: "internal");
914 for (av
= attr
->first_value
; av
; av
= av
->next
)
915 if (GET_CODE (av
->value
) == CONST_STRING
916 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
921 message_with_line (attr
->lineno
,
922 "unknown value `%s' for `%s' attribute",
923 XSTR (exp
, 0), attr
? attr
->name
: "internal");
929 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
930 attr
? attr
->is_const
: 0,
931 attr
? attr
->lineno
: 0);
932 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
933 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
941 if (attr
&& !attr
->is_numeric
)
943 message_with_line (attr
->lineno
,
944 "invalid operation `%s' for non-numeric attribute value",
945 GET_RTX_NAME (GET_CODE (exp
)));
953 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
954 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
963 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
967 if (XVECLEN (exp
, 0) % 2 != 0)
969 message_with_line (attr
->lineno
,
970 "first operand of COND must have even length");
975 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
977 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
978 attr
? attr
->is_const
: 0,
979 attr
? attr
->lineno
: 0);
980 XVECEXP (exp
, 0, i
+ 1)
981 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
984 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
989 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
992 message_with_line (attr
? attr
->lineno
: 0,
993 "unknown attribute `%s' in ATTR",
997 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
999 message_with_line (attr
->lineno
,
1000 "non-constant attribute `%s' referenced from `%s'",
1001 XSTR (exp
, 0), attr
->name
);
1005 && attr
->is_numeric
!= attr2
->is_numeric
)
1007 message_with_line (attr
->lineno
,
1008 "numeric attribute mismatch calling `%s' from `%s'",
1009 XSTR (exp
, 0), attr
->name
);
1016 /* A constant SYMBOL_REF is valid as a constant attribute test and
1017 is expanded later by make_canonical into a COND. In a non-constant
1018 attribute test, it is left be. */
1019 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1022 message_with_line (attr
? attr
->lineno
: 0,
1023 "invalid operation `%s' for attribute value",
1024 GET_RTX_NAME (GET_CODE (exp
)));
1032 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1033 It becomes a COND with each test being (eq_attr "alternative" "n") */
1036 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1038 int num_alt
= id
->num_alternatives
;
1042 if (XVECLEN (exp
, 1) != num_alt
)
1044 message_with_line (id
->lineno
,
1045 "bad number of entries in SET_ATTR_ALTERNATIVE");
1050 /* Make a COND with all tests but the last. Select the last value via the
1052 condexp
= rtx_alloc (COND
);
1053 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1055 for (i
= 0; i
< num_alt
- 1; i
++)
1058 p
= attr_numeral (i
);
1060 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1061 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1064 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1066 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1069 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1070 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1073 convert_set_attr (rtx exp
, struct insn_def
*id
)
1076 const char *name_ptr
;
1080 /* See how many alternative specified. */
1081 n
= n_comma_elts (XSTR (exp
, 1));
1083 return attr_rtx (SET
,
1084 attr_rtx (ATTR
, XSTR (exp
, 0)),
1085 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1087 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1088 XSTR (newexp
, 0) = XSTR (exp
, 0);
1089 XVEC (newexp
, 1) = rtvec_alloc (n
);
1091 /* Process each comma-separated name. */
1092 name_ptr
= XSTR (exp
, 1);
1094 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1095 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1097 return convert_set_attr_alternative (newexp
, id
);
1100 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1101 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1107 struct insn_def
*id
;
1108 struct attr_desc
*attr
;
1112 for (id
= defs
; id
; id
= id
->next
)
1114 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1117 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1119 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1120 switch (GET_CODE (value
))
1123 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1125 message_with_line (id
->lineno
, "bad attribute set");
1131 case SET_ATTR_ALTERNATIVE
:
1132 value
= convert_set_attr_alternative (value
, id
);
1136 value
= convert_set_attr (value
, id
);
1140 message_with_line (id
->lineno
, "invalid attribute code %s",
1141 GET_RTX_NAME (GET_CODE (value
)));
1145 if (value
== NULL_RTX
)
1148 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1150 message_with_line (id
->lineno
, "unknown attribute %s",
1151 XSTR (XEXP (value
, 0), 0));
1156 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1157 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1162 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1163 expressions by converting them into a COND. This removes cases from this
1164 program. Also, replace an attribute value of "*" with the default attribute
1168 make_canonical (struct attr_desc
*attr
, rtx exp
)
1173 switch (GET_CODE (exp
))
1176 exp
= make_numeric_value (INTVAL (exp
));
1180 if (! strcmp (XSTR (exp
, 0), "*"))
1182 if (attr
== 0 || attr
->default_val
== 0)
1183 fatal ("(attr_value \"*\") used in invalid context");
1184 exp
= attr
->default_val
->value
;
1187 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1192 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1194 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1195 This makes the COND something that won't be considered an arbitrary
1196 expression by walk_attr_value. */
1197 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1198 exp
= check_attr_value (exp
, attr
);
1202 newexp
= rtx_alloc (COND
);
1203 XVEC (newexp
, 0) = rtvec_alloc (2);
1204 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1205 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1207 XEXP (newexp
, 1) = XEXP (exp
, 2);
1210 /* Fall through to COND case since this is now a COND. */
1217 /* First, check for degenerate COND. */
1218 if (XVECLEN (exp
, 0) == 0)
1219 return make_canonical (attr
, XEXP (exp
, 1));
1220 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1222 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1224 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1225 XVECEXP (exp
, 0, i
+ 1)
1226 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1227 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1243 copy_boolean (rtx exp
)
1245 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1246 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1247 copy_boolean (XEXP (exp
, 1)));
1248 if (GET_CODE (exp
) == MATCH_OPERAND
)
1250 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1251 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1253 else if (GET_CODE (exp
) == EQ_ATTR
)
1255 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1256 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1262 /* Given a value and an attribute description, return a `struct attr_value *'
1263 that represents that value. This is either an existing structure, if the
1264 value has been previously encountered, or a newly-created structure.
1266 `insn_code' is the code of an insn whose attribute has the specified
1267 value (-2 if not processing an insn). We ensure that all insns for
1268 a given value have the same number of alternatives if the value checks
1271 static struct attr_value
*
1272 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1274 struct attr_value
*av
;
1277 value
= make_canonical (attr
, value
);
1278 if (compares_alternatives_p (value
))
1280 if (insn_code
< 0 || insn_alternatives
== NULL
)
1281 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1283 num_alt
= insn_alternatives
[insn_code
];
1286 for (av
= attr
->first_value
; av
; av
= av
->next
)
1287 if (rtx_equal_p (value
, av
->value
)
1288 && (num_alt
== 0 || av
->first_insn
== NULL
1289 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1292 av
= oballoc (sizeof (struct attr_value
));
1294 av
->next
= attr
->first_value
;
1295 attr
->first_value
= av
;
1296 av
->first_insn
= NULL
;
1298 av
->has_asm_insn
= 0;
1303 /* After all DEFINE_DELAYs have been read in, create internal attributes
1304 to generate the required routines.
1306 First, we compute the number of delay slots for each insn (as a COND of
1307 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1308 delay type is specified, we compute a similar function giving the
1309 DEFINE_DELAY ordinal for each insn.
1311 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1312 tells whether a given insn can be in that delay slot.
1314 Normal attribute filling and optimization expands these to contain the
1315 information needed to handle delay slots. */
1318 expand_delays (void)
1320 struct delay_desc
*delay
;
1326 /* First, generate data for `num_delay_slots' function. */
1328 condexp
= rtx_alloc (COND
);
1329 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1330 XEXP (condexp
, 1) = make_numeric_value (0);
1332 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1334 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1335 XVECEXP (condexp
, 0, i
+ 1)
1336 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1339 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1341 /* If more than one delay type, do the same for computing the delay type. */
1344 condexp
= rtx_alloc (COND
);
1345 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1346 XEXP (condexp
, 1) = make_numeric_value (0);
1348 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1350 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1351 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1354 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1357 /* For each delay possibility and delay slot, compute an eligibility
1358 attribute for non-annulled insns and for each type of annulled (annul
1359 if true and annul if false). */
1360 for (delay
= delays
; delay
; delay
= delay
->next
)
1362 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1364 condexp
= XVECEXP (delay
->def
, 1, i
);
1366 condexp
= false_rtx
;
1367 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1368 make_numeric_value (1), make_numeric_value (0));
1370 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1371 "*delay_%d_%d", delay
->num
, i
/ 3);
1372 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1374 if (have_annul_true
)
1376 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1377 if (condexp
== 0) condexp
= false_rtx
;
1378 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1379 make_numeric_value (1),
1380 make_numeric_value (0));
1381 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1382 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1383 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1386 if (have_annul_false
)
1388 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1389 if (condexp
== 0) condexp
= false_rtx
;
1390 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1391 make_numeric_value (1),
1392 make_numeric_value (0));
1393 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1394 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1395 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1401 /* Once all attributes and insns have been read and checked, we construct for
1402 each attribute value a list of all the insns that have that value for
1406 fill_attr (struct attr_desc
*attr
)
1408 struct attr_value
*av
;
1409 struct insn_ent
*ie
;
1410 struct insn_def
*id
;
1414 /* Don't fill constant attributes. The value is independent of
1415 any particular insn. */
1419 for (id
= defs
; id
; id
= id
->next
)
1421 /* If no value is specified for this insn for this attribute, use the
1424 if (XVEC (id
->def
, id
->vec_idx
))
1425 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1426 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1428 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1431 av
= attr
->default_val
;
1433 av
= get_attr_value (value
, attr
, id
->insn_code
);
1435 ie
= oballoc (sizeof (struct insn_ent
));
1437 insert_insn_ent (av
, ie
);
1441 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1442 test that checks relative positions of insns (uses MATCH_DUP or PC).
1443 If so, replace it with what is obtained by passing the expression to
1444 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1445 recursively on each value (including the default value). Otherwise,
1446 return the value returned by NO_ADDRESS_FN applied to EXP. */
1449 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1450 rtx (*address_fn
) (rtx
))
1455 if (GET_CODE (exp
) == COND
)
1457 /* See if any tests use addresses. */
1459 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1460 walk_attr_value (XVECEXP (exp
, 0, i
));
1463 return (*address_fn
) (exp
);
1465 /* Make a new copy of this COND, replacing each element. */
1466 newexp
= rtx_alloc (COND
);
1467 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1468 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1470 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1471 XVECEXP (newexp
, 0, i
+ 1)
1472 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1473 no_address_fn
, address_fn
);
1476 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1477 no_address_fn
, address_fn
);
1482 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1485 walk_attr_value (XEXP (exp
, 0));
1487 return (*address_fn
) (exp
);
1489 return attr_rtx (IF_THEN_ELSE
,
1490 substitute_address (XEXP (exp
, 0),
1491 no_address_fn
, address_fn
),
1492 substitute_address (XEXP (exp
, 1),
1493 no_address_fn
, address_fn
),
1494 substitute_address (XEXP (exp
, 2),
1495 no_address_fn
, address_fn
));
1498 return (*no_address_fn
) (exp
);
1501 /* Make new attributes from the `length' attribute. The following are made,
1502 each corresponding to a function called from `shorten_branches' or
1505 *insn_default_length This is the length of the insn to be returned
1506 by `get_attr_length' before `shorten_branches'
1507 has been called. In each case where the length
1508 depends on relative addresses, the largest
1509 possible is used. This routine is also used
1510 to compute the initial size of the insn.
1512 *insn_variable_length_p This returns 1 if the insn's length depends
1513 on relative addresses, zero otherwise.
1515 *insn_current_length This is only called when it is known that the
1516 insn has a variable length and returns the
1517 current length, based on relative addresses.
1521 make_length_attrs (void)
1523 static const char *new_names
[] =
1525 "*insn_default_length",
1527 "*insn_variable_length_p",
1528 "*insn_current_length"
1530 static rtx (*const no_address_fn
[]) (rtx
)
1531 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1532 static rtx (*const address_fn
[]) (rtx
)
1533 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1535 struct attr_desc
*length_attr
, *new_attr
;
1536 struct attr_value
*av
, *new_av
;
1537 struct insn_ent
*ie
, *new_ie
;
1539 /* See if length attribute is defined. If so, it must be numeric. Make
1540 it special so we don't output anything for it. */
1541 length_attr
= find_attr (&length_str
, 0);
1542 if (length_attr
== 0)
1545 if (! length_attr
->is_numeric
)
1546 fatal ("length attribute must be numeric");
1548 length_attr
->is_const
= 0;
1549 length_attr
->is_special
= 1;
1551 /* Make each new attribute, in turn. */
1552 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1554 make_internal_attr (new_names
[i
],
1555 substitute_address (length_attr
->default_val
->value
,
1556 no_address_fn
[i
], address_fn
[i
]),
1558 new_attr
= find_attr (&new_names
[i
], 0);
1559 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1560 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1562 new_av
= get_attr_value (substitute_address (av
->value
,
1565 new_attr
, ie
->def
->insn_code
);
1566 new_ie
= oballoc (sizeof (struct insn_ent
));
1567 new_ie
->def
= ie
->def
;
1568 insert_insn_ent (new_av
, new_ie
);
1573 /* Utility functions called from above routine. */
1576 identity_fn (rtx exp
)
1582 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1584 return make_numeric_value (0);
1588 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1590 return make_numeric_value (1);
1597 return make_numeric_value (max_attr_value (exp
, &unknown
));
1604 return make_numeric_value (min_attr_value (exp
, &unknown
));
1608 write_length_unit_log (void)
1610 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1611 struct attr_value
*av
;
1612 struct insn_ent
*ie
;
1613 unsigned int length_unit_log
, length_or
;
1616 if (length_attr
== 0)
1618 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1619 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1620 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1621 length_or
|= or_attr_value (av
->value
, &unknown
);
1624 length_unit_log
= 0;
1627 length_or
= ~length_or
;
1628 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1631 printf ("const int length_unit_log = %u;\n", length_unit_log
);
1634 /* Take a COND expression and see if any of the conditions in it can be
1635 simplified. If any are known true or known false for the particular insn
1636 code, the COND can be further simplified.
1638 Also call ourselves on any COND operations that are values of this COND.
1640 We do not modify EXP; rather, we make and return a new rtx. */
1643 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1646 /* We store the desired contents here,
1647 then build a new expression if they don't match EXP. */
1648 rtx defval
= XEXP (exp
, 1);
1649 rtx new_defval
= XEXP (exp
, 1);
1650 int len
= XVECLEN (exp
, 0);
1651 rtx
*tests
= XNEWVEC (rtx
, len
);
1655 /* This lets us free all storage allocated below, if appropriate. */
1656 obstack_finish (rtl_obstack
);
1658 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1660 /* See if default value needs simplification. */
1661 if (GET_CODE (defval
) == COND
)
1662 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1664 /* Simplify the subexpressions, and see what tests we can get rid of. */
1666 for (i
= 0; i
< len
; i
+= 2)
1668 rtx newtest
, newval
;
1670 /* Simplify this test. */
1671 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1674 newval
= tests
[i
+ 1];
1675 /* See if this value may need simplification. */
1676 if (GET_CODE (newval
) == COND
)
1677 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1679 /* Look for ways to delete or combine this test. */
1680 if (newtest
== true_rtx
)
1682 /* If test is true, make this value the default
1683 and discard this + any following tests. */
1685 defval
= tests
[i
+ 1];
1686 new_defval
= newval
;
1689 else if (newtest
== false_rtx
)
1691 /* If test is false, discard it and its value. */
1692 for (j
= i
; j
< len
- 2; j
++)
1693 tests
[j
] = tests
[j
+ 2];
1698 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1700 /* If this value and the value for the prev test are the same,
1704 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1705 insn_code
, insn_index
);
1707 /* Delete this test/value. */
1708 for (j
= i
; j
< len
- 2; j
++)
1709 tests
[j
] = tests
[j
+ 2];
1715 tests
[i
+ 1] = newval
;
1718 /* If the last test in a COND has the same value
1719 as the default value, that test isn't needed. */
1721 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1724 /* See if we changed anything. */
1725 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1728 for (i
= 0; i
< len
; i
++)
1729 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1737 if (GET_CODE (defval
) == COND
)
1738 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1746 rtx newexp
= rtx_alloc (COND
);
1748 XVEC (newexp
, 0) = rtvec_alloc (len
);
1749 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1750 XEXP (newexp
, 1) = new_defval
;
1757 /* Remove an insn entry from an attribute value. */
1760 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1762 struct insn_ent
*previe
;
1764 if (av
->first_insn
== ie
)
1765 av
->first_insn
= ie
->next
;
1768 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1770 previe
->next
= ie
->next
;
1774 if (ie
->def
->insn_code
== -1)
1775 av
->has_asm_insn
= 0;
1780 /* Insert an insn entry in an attribute value list. */
1783 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1785 ie
->next
= av
->first_insn
;
1786 av
->first_insn
= ie
;
1788 if (ie
->def
->insn_code
== -1)
1789 av
->has_asm_insn
= 1;
1794 /* This is a utility routine to take an expression that is a tree of either
1795 AND or IOR expressions and insert a new term. The new term will be
1796 inserted at the right side of the first node whose code does not match
1797 the root. A new node will be created with the root's code. Its left
1798 side will be the old right side and its right side will be the new
1801 If the `term' is itself a tree, all its leaves will be inserted. */
1804 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1808 /* Avoid consing in some special cases. */
1809 if (code
== AND
&& term
== true_rtx
)
1811 if (code
== AND
&& term
== false_rtx
)
1813 if (code
== AND
&& exp
== true_rtx
)
1815 if (code
== AND
&& exp
== false_rtx
)
1817 if (code
== IOR
&& term
== true_rtx
)
1819 if (code
== IOR
&& term
== false_rtx
)
1821 if (code
== IOR
&& exp
== true_rtx
)
1823 if (code
== IOR
&& exp
== false_rtx
)
1825 if (attr_equal_p (exp
, term
))
1828 if (GET_CODE (term
) == code
)
1830 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1831 insn_code
, insn_index
);
1832 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1833 insn_code
, insn_index
);
1838 if (GET_CODE (exp
) == code
)
1840 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1841 term
, insn_code
, insn_index
);
1842 if (new != XEXP (exp
, 1))
1843 /* Make a copy of this expression and call recursively. */
1844 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1850 /* Insert the new term. */
1851 newexp
= attr_rtx (code
, exp
, term
);
1854 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1857 /* If we have an expression which AND's a bunch of
1858 (not (eq_attrq "alternative" "n"))
1859 terms, we may have covered all or all but one of the possible alternatives.
1860 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1862 This routine is passed an expression and either AND or IOR. It returns a
1863 bitmask indicating which alternatives are mentioned within EXP. */
1866 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1869 if (GET_CODE (exp
) == code
)
1870 return compute_alternative_mask (XEXP (exp
, 0), code
)
1871 | compute_alternative_mask (XEXP (exp
, 1), code
);
1873 else if (code
== AND
&& GET_CODE (exp
) == NOT
1874 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1875 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1876 string
= XSTR (XEXP (exp
, 0), 1);
1878 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1879 && XSTR (exp
, 0) == alternative_name
)
1880 string
= XSTR (exp
, 1);
1882 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1884 if (code
== AND
&& XINT (exp
, 1))
1885 return XINT (exp
, 0);
1887 if (code
== IOR
&& !XINT (exp
, 1))
1888 return XINT (exp
, 0);
1896 return 1 << (string
[0] - '0');
1897 return 1 << atoi (string
);
1900 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1901 attribute with the value represented by that bit. */
1904 make_alternative_compare (int mask
)
1906 return mk_attr_alt (mask
);
1909 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1910 of "attr" for this insn code. From that value, we can compute a test
1911 showing when the EQ_ATTR will be true. This routine performs that
1912 computation. If a test condition involves an address, we leave the EQ_ATTR
1913 intact because addresses are only valid for the `length' attribute.
1915 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1916 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1919 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
1926 switch (GET_CODE (value
))
1929 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
1940 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
1941 gcc_assert (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2
1944 strcpy (string
, XSTR (exp
, 0));
1945 strcat (string
, "_");
1946 strcat (string
, XSTR (exp
, 1));
1947 for (p
= string
; *p
; p
++)
1950 newexp
= attr_rtx (EQ
, value
,
1951 attr_rtx (SYMBOL_REF
,
1952 DEF_ATTR_STRING (string
)));
1957 /* We construct an IOR of all the cases for which the
1958 requested attribute value is present. Since we start with
1959 FALSE, if it is not present, FALSE will be returned.
1961 Each case is the AND of the NOT's of the previous conditions with the
1962 current condition; in the default case the current condition is TRUE.
1964 For each possible COND value, call ourselves recursively.
1966 The extra TRUE and FALSE expressions will be eliminated by another
1967 call to the simplification routine. */
1972 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
1974 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
1975 insn_code
, insn_index
);
1977 right
= insert_right_side (AND
, andexp
, this,
1978 insn_code
, insn_index
);
1979 right
= insert_right_side (AND
, right
,
1980 evaluate_eq_attr (exp
,
1983 insn_code
, insn_index
),
1984 insn_code
, insn_index
);
1985 orexp
= insert_right_side (IOR
, orexp
, right
,
1986 insn_code
, insn_index
);
1988 /* Add this condition into the AND expression. */
1989 newexp
= attr_rtx (NOT
, this);
1990 andexp
= insert_right_side (AND
, andexp
, newexp
,
1991 insn_code
, insn_index
);
1994 /* Handle the default case. */
1995 right
= insert_right_side (AND
, andexp
,
1996 evaluate_eq_attr (exp
, XEXP (value
, 1),
1997 insn_code
, insn_index
),
1998 insn_code
, insn_index
);
1999 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2006 /* If uses an address, must return original expression. But set the
2007 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2010 walk_attr_value (newexp
);
2014 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2015 return copy_rtx_unchanging (exp
);
2022 /* This routine is called when an AND of a term with a tree of AND's is
2023 encountered. If the term or its complement is present in the tree, it
2024 can be replaced with TRUE or FALSE, respectively.
2026 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2027 be true and hence are complementary.
2029 There is one special case: If we see
2030 (and (not (eq_attr "att" "v1"))
2031 (eq_attr "att" "v2"))
2032 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2033 replace the term, not anything in the AND tree. So we pass a pointer to
2037 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2042 int left_eliminates_term
, right_eliminates_term
;
2044 if (GET_CODE (exp
) == AND
)
2046 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2047 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2048 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2050 newexp
= attr_rtx (AND
, left
, right
);
2052 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2056 else if (GET_CODE (exp
) == IOR
)
2058 /* For the IOR case, we do the same as above, except that we can
2059 only eliminate `term' if both sides of the IOR would do so. */
2061 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2062 left_eliminates_term
= (temp
== true_rtx
);
2065 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2066 right_eliminates_term
= (temp
== true_rtx
);
2068 if (left_eliminates_term
&& right_eliminates_term
)
2071 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2073 newexp
= attr_rtx (IOR
, left
, right
);
2075 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2079 /* Check for simplifications. Do some extra checking here since this
2080 routine is called so many times. */
2085 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2088 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2091 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2093 if (attr_alt_subset_p (*pterm
, exp
))
2096 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2099 if (attr_alt_subset_p (exp
, *pterm
))
2105 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2107 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2110 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2116 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2117 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2119 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2122 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2128 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2129 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2131 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2134 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2140 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2142 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2146 else if (GET_CODE (exp
) == NOT
)
2148 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2152 else if (GET_CODE (*pterm
) == NOT
)
2154 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2158 else if (attr_equal_p (exp
, *pterm
))
2164 /* Similar to `simplify_and_tree', but for IOR trees. */
2167 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2172 int left_eliminates_term
, right_eliminates_term
;
2174 if (GET_CODE (exp
) == IOR
)
2176 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2177 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2178 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2180 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2182 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2186 else if (GET_CODE (exp
) == AND
)
2188 /* For the AND case, we do the same as above, except that we can
2189 only eliminate `term' if both sides of the AND would do so. */
2191 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2192 left_eliminates_term
= (temp
== false_rtx
);
2195 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2196 right_eliminates_term
= (temp
== false_rtx
);
2198 if (left_eliminates_term
&& right_eliminates_term
)
2201 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2203 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2205 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2209 if (attr_equal_p (exp
, *pterm
))
2212 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2215 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2218 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2219 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2220 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2223 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2224 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2225 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2231 /* Compute approximate cost of the expression. Used to decide whether
2232 expression is cheap enough for inline. */
2234 attr_rtx_cost (rtx x
)
2240 code
= GET_CODE (x
);
2253 /* Alternatives don't result into function call. */
2254 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2261 const char *fmt
= GET_RTX_FORMAT (code
);
2262 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2268 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2269 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2272 cost
+= attr_rtx_cost (XEXP (x
, i
));
2282 /* Simplify test expression and use temporary obstack in order to avoid
2283 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2284 and avoid unnecessary copying if possible. */
2287 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2290 struct obstack
*old
;
2291 if (ATTR_IND_SIMPLIFIED_P (exp
))
2294 rtl_obstack
= temp_obstack
;
2295 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2297 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2299 return attr_copy_rtx (x
);
2302 /* Returns true if S1 is a subset of S2. */
2305 attr_alt_subset_p (rtx s1
, rtx s2
)
2307 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2310 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2313 return !(XINT (s1
, 0) & XINT (s2
, 0));
2319 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2326 /* Returns true if S1 is a subset of complement of S2. */
2329 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2331 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2334 return !(XINT (s1
, 0) & XINT (s2
, 0));
2337 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2340 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2350 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2353 attr_alt_intersection (rtx s1
, rtx s2
)
2355 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2357 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2360 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2363 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2366 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2369 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2374 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2379 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2382 attr_alt_union (rtx s1
, rtx s2
)
2384 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2386 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2389 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2392 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2395 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2398 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2404 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2408 /* Return EQ_ATTR_ALT expression representing complement of S. */
2411 attr_alt_complement (rtx s
)
2413 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2415 XINT (result
, 0) = XINT (s
, 0);
2416 XINT (result
, 1) = 1 - XINT (s
, 1);
2421 /* Return EQ_ATTR_ALT expression representing set containing elements set
2427 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2429 XINT (result
, 0) = e
;
2430 XINT (result
, 1) = 0;
2435 /* Given an expression, see if it can be simplified for a particular insn
2436 code based on the values of other attributes being tested. This can
2437 eliminate nested get_attr_... calls.
2439 Note that if an endless recursion is specified in the patterns, the
2440 optimization will loop. However, it will do so in precisely the cases where
2441 an infinite recursion loop could occur during compilation. It's better that
2445 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2448 struct attr_desc
*attr
;
2449 struct attr_value
*av
;
2450 struct insn_ent
*ie
;
2453 bool left_alt
, right_alt
;
2455 /* Don't re-simplify something we already simplified. */
2456 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2459 switch (GET_CODE (exp
))
2462 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2463 if (left
== false_rtx
)
2465 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2466 if (right
== false_rtx
)
2469 if (GET_CODE (left
) == EQ_ATTR_ALT
2470 && GET_CODE (right
) == EQ_ATTR_ALT
)
2472 exp
= attr_alt_intersection (left
, right
);
2473 return simplify_test_exp (exp
, insn_code
, insn_index
);
2476 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2477 present on both sides, apply the distributive law since this will
2478 yield simplifications. */
2479 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2480 && compute_alternative_mask (left
, IOR
)
2481 && compute_alternative_mask (right
, IOR
))
2483 if (GET_CODE (left
) == IOR
)
2490 newexp
= attr_rtx (IOR
,
2491 attr_rtx (AND
, left
, XEXP (right
, 0)),
2492 attr_rtx (AND
, left
, XEXP (right
, 1)));
2494 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2497 /* Try with the term on both sides. */
2498 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2499 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2500 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2502 if (left
== false_rtx
|| right
== false_rtx
)
2504 else if (left
== true_rtx
)
2508 else if (right
== true_rtx
)
2512 /* See if all or all but one of the insn's alternatives are specified
2513 in this tree. Optimize if so. */
2515 if (GET_CODE (left
) == NOT
)
2516 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2517 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2519 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2522 if (GET_CODE (right
) == NOT
)
2523 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2524 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2526 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2527 && XINT (right
, 1));
2530 && (GET_CODE (left
) == AND
2532 || GET_CODE (right
) == AND
2535 i
= compute_alternative_mask (exp
, AND
);
2536 if (i
& ~insn_alternatives
[insn_code
])
2537 fatal ("invalid alternative specified for pattern number %d",
2540 /* If all alternatives are excluded, this is false. */
2541 i
^= insn_alternatives
[insn_code
];
2544 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2546 /* If just one excluded, AND a comparison with that one to the
2547 front of the tree. The others will be eliminated by
2548 optimization. We do not want to do this if the insn has one
2549 alternative and we have tested none of them! */
2550 left
= make_alternative_compare (i
);
2551 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2552 newexp
= attr_rtx (AND
, left
, right
);
2554 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2558 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2560 newexp
= attr_rtx (AND
, left
, right
);
2561 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2566 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2567 if (left
== true_rtx
)
2569 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2570 if (right
== true_rtx
)
2573 if (GET_CODE (left
) == EQ_ATTR_ALT
2574 && GET_CODE (right
) == EQ_ATTR_ALT
)
2576 exp
= attr_alt_union (left
, right
);
2577 return simplify_test_exp (exp
, insn_code
, insn_index
);
2580 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2581 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2582 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2584 if (right
== true_rtx
|| left
== true_rtx
)
2586 else if (left
== false_rtx
)
2590 else if (right
== false_rtx
)
2595 /* Test for simple cases where the distributive law is useful. I.e.,
2596 convert (ior (and (x) (y))
2602 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2603 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2605 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2607 left
= XEXP (left
, 0);
2609 newexp
= attr_rtx (AND
, left
, right
);
2610 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2613 /* See if all or all but one of the insn's alternatives are specified
2614 in this tree. Optimize if so. */
2616 else if (insn_code
>= 0
2617 && (GET_CODE (left
) == IOR
2618 || (GET_CODE (left
) == EQ_ATTR_ALT
2620 || (GET_CODE (left
) == EQ_ATTR
2621 && XSTR (left
, 0) == alternative_name
)
2622 || GET_CODE (right
) == IOR
2623 || (GET_CODE (right
) == EQ_ATTR_ALT
2624 && !XINT (right
, 1))
2625 || (GET_CODE (right
) == EQ_ATTR
2626 && XSTR (right
, 0) == alternative_name
)))
2628 i
= compute_alternative_mask (exp
, IOR
);
2629 if (i
& ~insn_alternatives
[insn_code
])
2630 fatal ("invalid alternative specified for pattern number %d",
2633 /* If all alternatives are included, this is true. */
2634 i
^= insn_alternatives
[insn_code
];
2637 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2639 /* If just one excluded, IOR a comparison with that one to the
2640 front of the tree. The others will be eliminated by
2641 optimization. We do not want to do this if the insn has one
2642 alternative and we have tested none of them! */
2643 left
= make_alternative_compare (i
);
2644 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2645 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2647 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2651 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2653 newexp
= attr_rtx (IOR
, left
, right
);
2654 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2659 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2661 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2662 insn_code
, insn_index
);
2666 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2667 if (GET_CODE (left
) == NOT
)
2668 return XEXP (left
, 0);
2670 if (left
== false_rtx
)
2672 if (left
== true_rtx
)
2675 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2677 exp
= attr_alt_complement (left
);
2678 return simplify_test_exp (exp
, insn_code
, insn_index
);
2681 /* Try to apply De`Morgan's laws. */
2682 if (GET_CODE (left
) == IOR
)
2684 newexp
= attr_rtx (AND
,
2685 attr_rtx (NOT
, XEXP (left
, 0)),
2686 attr_rtx (NOT
, XEXP (left
, 1)));
2688 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2690 else if (GET_CODE (left
) == AND
)
2692 newexp
= attr_rtx (IOR
,
2693 attr_rtx (NOT
, XEXP (left
, 0)),
2694 attr_rtx (NOT
, XEXP (left
, 1)));
2696 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2698 else if (left
!= XEXP (exp
, 0))
2700 newexp
= attr_rtx (NOT
, left
);
2706 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2710 if (XSTR (exp
, 0) == alternative_name
)
2712 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2716 /* Look at the value for this insn code in the specified attribute.
2717 We normally can replace this comparison with the condition that
2718 would give this insn the values being tested for. */
2720 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2721 for (av
= attr
->first_value
; av
; av
= av
->next
)
2722 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2723 if (ie
->def
->insn_code
== insn_code
)
2726 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2727 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2728 if (attr_rtx_cost(x
) < 20)
2737 /* We have already simplified this expression. Simplifying it again
2738 won't buy anything unless we weren't given a valid insn code
2739 to process (i.e., we are canonicalizing something.). */
2741 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2742 return copy_rtx_unchanging (newexp
);
2747 /* Optimize the attribute lists by seeing if we can determine conditional
2748 values from the known values of other attributes. This will save subroutine
2749 calls during the compilation. */
2752 optimize_attrs (void)
2754 struct attr_desc
*attr
;
2755 struct attr_value
*av
;
2756 struct insn_ent
*ie
;
2759 struct attr_value_list
2761 struct attr_value
*av
;
2762 struct insn_ent
*ie
;
2763 struct attr_desc
*attr
;
2764 struct attr_value_list
*next
;
2766 struct attr_value_list
**insn_code_values
;
2767 struct attr_value_list
*ivbuf
;
2768 struct attr_value_list
*iv
;
2770 /* For each insn code, make a list of all the insn_ent's for it,
2771 for all values for all attributes. */
2773 if (num_insn_ents
== 0)
2776 /* Make 2 extra elements, for "code" values -2 and -1. */
2777 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2779 /* Offset the table address so we can index by -2 or -1. */
2780 insn_code_values
+= 2;
2782 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2784 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2785 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2786 for (av
= attr
->first_value
; av
; av
= av
->next
)
2787 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2792 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2793 insn_code_values
[ie
->def
->insn_code
] = iv
;
2797 /* Sanity check on num_insn_ents. */
2798 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2800 /* Process one insn code at a time. */
2801 for (i
= -2; i
< insn_code_number
; i
++)
2803 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2804 We use it to mean "already simplified for this insn". */
2805 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2806 clear_struct_flag (iv
->av
->value
);
2808 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2810 struct obstack
*old
= rtl_obstack
;
2815 if (GET_CODE (av
->value
) != COND
)
2818 rtl_obstack
= temp_obstack
;
2820 while (GET_CODE (newexp
) == COND
)
2822 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2823 ie
->def
->insn_index
);
2824 if (newexp2
== newexp
)
2830 if (newexp
!= av
->value
)
2832 newexp
= attr_copy_rtx (newexp
);
2833 remove_insn_ent (av
, ie
);
2834 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2836 insert_insn_ent (av
, ie
);
2842 free (insn_code_values
- 2);
2845 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2848 clear_struct_flag (rtx x
)
2855 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2856 if (ATTR_IND_SIMPLIFIED_P (x
))
2859 code
= GET_CODE (x
);
2879 /* Compare the elements. If any pair of corresponding elements
2880 fail to match, return 0 for the whole things. */
2882 fmt
= GET_RTX_FORMAT (code
);
2883 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2889 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2890 clear_struct_flag (XVECEXP (x
, i
, j
));
2894 clear_struct_flag (XEXP (x
, i
));
2900 /* Create table entries for DEFINE_ATTR. */
2903 gen_attr (rtx exp
, int lineno
)
2905 struct attr_desc
*attr
;
2906 struct attr_value
*av
;
2907 const char *name_ptr
;
2910 /* Make a new attribute structure. Check for duplicate by looking at
2911 attr->default_val, since it is initialized by this routine. */
2912 attr
= find_attr (&XSTR (exp
, 0), 1);
2913 if (attr
->default_val
)
2915 message_with_line (lineno
, "duplicate definition for attribute %s",
2917 message_with_line (attr
->lineno
, "previous definition");
2921 attr
->lineno
= lineno
;
2923 if (*XSTR (exp
, 1) == '\0')
2924 attr
->is_numeric
= 1;
2927 name_ptr
= XSTR (exp
, 1);
2928 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
2930 av
= oballoc (sizeof (struct attr_value
));
2931 av
->value
= attr_rtx (CONST_STRING
, p
);
2932 av
->next
= attr
->first_value
;
2933 attr
->first_value
= av
;
2934 av
->first_insn
= NULL
;
2936 av
->has_asm_insn
= 0;
2940 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
2943 if (attr
->is_numeric
)
2945 message_with_line (lineno
,
2946 "constant attributes may not take numeric values");
2950 /* Get rid of the CONST node. It is allowed only at top-level. */
2951 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
2954 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
2956 message_with_line (lineno
,
2957 "`length' attribute must take numeric values");
2961 /* Set up the default value. */
2962 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
2963 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
2966 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2967 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2968 number of alternatives as this should be checked elsewhere. */
2971 count_alternatives (rtx exp
)
2976 if (GET_CODE (exp
) == MATCH_OPERAND
)
2977 return n_comma_elts (XSTR (exp
, 2));
2979 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
2980 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
2985 n
= count_alternatives (XEXP (exp
, i
));
2992 if (XVEC (exp
, i
) != NULL
)
2993 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2995 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3004 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3005 `alternative' attribute. */
3008 compares_alternatives_p (rtx exp
)
3013 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3016 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3017 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3022 if (compares_alternatives_p (XEXP (exp
, i
)))
3027 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3028 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3036 /* Returns nonzero is INNER is contained in EXP. */
3039 contained_in_p (rtx inner
, rtx exp
)
3044 if (rtx_equal_p (inner
, exp
))
3047 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3048 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3053 if (contained_in_p (inner
, XEXP (exp
, i
)))
3058 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3059 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
3067 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3070 gen_insn (rtx exp
, int lineno
)
3072 struct insn_def
*id
;
3074 id
= oballoc (sizeof (struct insn_def
));
3078 id
->lineno
= lineno
;
3080 switch (GET_CODE (exp
))
3083 id
->insn_code
= insn_code_number
;
3084 id
->insn_index
= insn_index_number
;
3085 id
->num_alternatives
= count_alternatives (exp
);
3086 if (id
->num_alternatives
== 0)
3087 id
->num_alternatives
= 1;
3091 case DEFINE_PEEPHOLE
:
3092 id
->insn_code
= insn_code_number
;
3093 id
->insn_index
= insn_index_number
;
3094 id
->num_alternatives
= count_alternatives (exp
);
3095 if (id
->num_alternatives
== 0)
3096 id
->num_alternatives
= 1;
3100 case DEFINE_ASM_ATTRIBUTES
:
3102 id
->insn_index
= -1;
3103 id
->num_alternatives
= 1;
3105 got_define_asm_attributes
= 1;
3113 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3114 true or annul false is specified, and make a `struct delay_desc'. */
3117 gen_delay (rtx def
, int lineno
)
3119 struct delay_desc
*delay
;
3122 if (XVECLEN (def
, 1) % 3 != 0)
3124 message_with_line (lineno
,
3125 "number of elements in DEFINE_DELAY must be multiple of three");
3130 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3132 if (XVECEXP (def
, 1, i
+ 1))
3133 have_annul_true
= 1;
3134 if (XVECEXP (def
, 1, i
+ 2))
3135 have_annul_false
= 1;
3138 delay
= oballoc (sizeof (struct delay_desc
));
3140 delay
->num
= ++num_delays
;
3141 delay
->next
= delays
;
3142 delay
->lineno
= lineno
;
3146 /* Given a piece of RTX, print a C expression to test its truth value.
3147 We use AND and IOR both for logical and bit-wise operations, so
3148 interpret them as logical unless they are inside a comparison expression.
3149 The first bit of FLAGS will be nonzero in that case.
3151 Set the second bit of FLAGS to make references to attribute values use
3152 a cached local variable instead of calling a function. */
3155 write_test_expr (rtx exp
, int flags
)
3157 int comparison_operator
= 0;
3159 struct attr_desc
*attr
;
3161 /* In order not to worry about operator precedence, surround our part of
3162 the expression with parentheses. */
3165 code
= GET_CODE (exp
);
3168 /* Binary operators. */
3171 printf ("(unsigned) ");
3177 comparison_operator
= 1;
3179 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3180 case AND
: case IOR
: case XOR
:
3181 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3182 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3198 printf (" >= (unsigned) ");
3201 printf (" > (unsigned) ");
3210 printf (" <= (unsigned) ");
3213 printf (" < (unsigned) ");
3256 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3260 /* Special-case (not (eq_attrq "alternative" "x")) */
3261 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3262 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3264 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3268 /* Otherwise, fall through to normal unary operator. */
3270 /* Unary operators. */
3290 write_test_expr (XEXP (exp
, 0), flags
);
3295 int set
= XINT (exp
, 0), bit
= 0;
3298 fatal ("EQ_ATTR_ALT not valid inside comparison");
3301 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3303 if (!(set
& (set
- 1)))
3305 if (!(set
& 0xffff))
3328 printf ("which_alternative %s= %d",
3329 XINT (exp
, 1) ? "!" : "=", bit
);
3333 printf ("%s((1 << which_alternative) & 0x%x)",
3334 XINT (exp
, 1) ? "!" : "", set
);
3339 /* Comparison test of an attribute with a value. Most of these will
3340 have been removed by optimization. Handle "alternative"
3341 specially and give error if EQ_ATTR present inside a comparison. */
3344 fatal ("EQ_ATTR not valid inside comparison");
3346 if (XSTR (exp
, 0) == alternative_name
)
3348 printf ("which_alternative == %s", XSTR (exp
, 1));
3352 attr
= find_attr (&XSTR (exp
, 0), 0);
3355 /* Now is the time to expand the value of a constant attribute. */
3358 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3365 printf ("attr_%s", attr
->name
);
3367 printf ("get_attr_%s (insn)", attr
->name
);
3369 write_attr_valueq (attr
, XSTR (exp
, 1));
3373 /* Comparison test of flags for define_delays. */
3376 fatal ("ATTR_FLAG not valid inside comparison");
3377 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3380 /* See if an operand matches a predicate. */
3382 /* If only a mode is given, just ensure the mode matches the operand.
3383 If neither a mode nor predicate is given, error. */
3384 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3386 if (GET_MODE (exp
) == VOIDmode
)
3387 fatal ("null MATCH_OPERAND specified as test");
3389 printf ("GET_MODE (operands[%d]) == %smode",
3390 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3393 printf ("%s (operands[%d], %smode)",
3394 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3397 /* Constant integer. */
3399 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3402 /* A random C expression. */
3404 print_c_condition (XSTR (exp
, 0));
3407 /* The address of the branch target. */
3409 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3410 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3414 /* The address of the current insn. We implement this actually as the
3415 address of the current insn for backward branches, but the last
3416 address of the next insn for forward branches, and both with
3417 adjustments that account for the worst-case possible stretching of
3418 intervening alignments between this insn and its destination. */
3419 printf ("insn_current_reference_address (insn)");
3423 printf ("%s", XSTR (exp
, 0));
3427 write_test_expr (XEXP (exp
, 0), flags
& 2);
3429 write_test_expr (XEXP (exp
, 1), flags
| 1);
3431 write_test_expr (XEXP (exp
, 2), flags
| 1);
3435 fatal ("bad RTX code `%s' in attribute calculation\n",
3436 GET_RTX_NAME (code
));
3442 /* Given an attribute value, return the maximum CONST_STRING argument
3443 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3446 max_attr_value (rtx exp
, int *unknownp
)
3451 switch (GET_CODE (exp
))
3454 current_max
= atoi (XSTR (exp
, 0));
3458 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3459 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3461 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3462 if (n
> current_max
)
3468 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3469 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3470 if (n
> current_max
)
3476 current_max
= INT_MAX
;
3483 /* Given an attribute value, return the minimum CONST_STRING argument
3484 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3487 min_attr_value (rtx exp
, int *unknownp
)
3492 switch (GET_CODE (exp
))
3495 current_min
= atoi (XSTR (exp
, 0));
3499 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3500 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3502 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3503 if (n
< current_min
)
3509 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3510 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3511 if (n
< current_min
)
3517 current_min
= INT_MAX
;
3524 /* Given an attribute value, return the result of ORing together all
3525 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3526 if the numeric value is not known. */
3529 or_attr_value (rtx exp
, int *unknownp
)
3534 switch (GET_CODE (exp
))
3537 current_or
= atoi (XSTR (exp
, 0));
3541 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3542 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3543 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3547 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3548 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3560 /* Scan an attribute value, possibly a conditional, and record what actions
3561 will be required to do any conditional tests in it.
3564 `must_extract' if we need to extract the insn operands
3565 `must_constrain' if we must compute `which_alternative'
3566 `address_used' if an address expression was used
3567 `length_used' if an (eq_attr "length" ...) was used
3571 walk_attr_value (rtx exp
)
3580 code
= GET_CODE (exp
);
3584 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3585 /* Since this is an arbitrary expression, it can look at anything.
3586 However, constant expressions do not depend on any particular
3588 must_extract
= must_constrain
= 1;
3596 must_extract
= must_constrain
= 1;
3600 if (XSTR (exp
, 0) == alternative_name
)
3601 must_extract
= must_constrain
= 1;
3602 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3622 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3627 walk_attr_value (XEXP (exp
, i
));
3631 if (XVEC (exp
, i
) != NULL
)
3632 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3633 walk_attr_value (XVECEXP (exp
, i
, j
));
3638 /* Write out a function to obtain the attribute for a given INSN. */
3641 write_attr_get (struct attr_desc
*attr
)
3643 struct attr_value
*av
, *common_av
;
3645 /* Find the most used attribute value. Handle that as the `default' of the
3646 switch we will generate. */
3647 common_av
= find_most_used (attr
);
3649 /* Write out start of function, then all values with explicit `case' lines,
3650 then a `default', then the value with the most uses. */
3651 if (!attr
->is_numeric
)
3652 printf ("enum attr_%s\n", attr
->name
);
3656 /* If the attribute name starts with a star, the remainder is the name of
3657 the subroutine to use, instead of `get_attr_...'. */
3658 if (attr
->name
[0] == '*')
3659 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3660 else if (attr
->is_const
== 0)
3661 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3664 printf ("get_attr_%s (void)\n", attr
->name
);
3667 for (av
= attr
->first_value
; av
; av
= av
->next
)
3668 if (av
->num_insns
== 1)
3669 write_attr_set (attr
, 2, av
->value
, "return", ";",
3670 true_rtx
, av
->first_insn
->def
->insn_code
,
3671 av
->first_insn
->def
->insn_index
);
3672 else if (av
->num_insns
!= 0)
3673 write_attr_set (attr
, 2, av
->value
, "return", ";",
3681 printf (" switch (recog_memoized (insn))\n");
3684 for (av
= attr
->first_value
; av
; av
= av
->next
)
3685 if (av
!= common_av
)
3686 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3688 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3689 printf (" }\n}\n\n");
3692 /* Given an AND tree of known true terms (because we are inside an `if' with
3693 that as the condition or are in an `else' clause) and an expression,
3694 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3695 the bulk of the work. */
3698 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3702 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3704 if (GET_CODE (known_true
) == AND
)
3706 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3707 insn_code
, insn_index
);
3708 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3709 insn_code
, insn_index
);
3714 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3720 /* Write out a series of tests and assignment statements to perform tests and
3721 sets of an attribute value. We are passed an indentation amount and prefix
3722 and suffix strings to write around each attribute value (e.g., "return"
3726 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3727 const char *prefix
, const char *suffix
, rtx known_true
,
3728 int insn_code
, int insn_index
)
3730 if (GET_CODE (value
) == COND
)
3732 /* Assume the default value will be the default of the COND unless we
3733 find an always true expression. */
3734 rtx default_val
= XEXP (value
, 1);
3735 rtx our_known_true
= known_true
;
3740 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3745 testexp
= eliminate_known_true (our_known_true
,
3746 XVECEXP (value
, 0, i
),
3747 insn_code
, insn_index
);
3748 newexp
= attr_rtx (NOT
, testexp
);
3749 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3750 insn_code
, insn_index
);
3752 /* If the test expression is always true or if the next `known_true'
3753 expression is always false, this is the last case, so break
3754 out and let this value be the `else' case. */
3755 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3757 default_val
= XVECEXP (value
, 0, i
+ 1);
3761 /* Compute the expression to pass to our recursive call as being
3763 inner_true
= insert_right_side (AND
, our_known_true
,
3764 testexp
, insn_code
, insn_index
);
3766 /* If this is always false, skip it. */
3767 if (inner_true
== false_rtx
)
3770 write_indent (indent
);
3771 printf ("%sif ", first_if
? "" : "else ");
3773 write_test_expr (testexp
, 0);
3775 write_indent (indent
+ 2);
3778 write_attr_set (attr
, indent
+ 4,
3779 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3780 inner_true
, insn_code
, insn_index
);
3781 write_indent (indent
+ 2);
3783 our_known_true
= newexp
;
3788 write_indent (indent
);
3790 write_indent (indent
+ 2);
3794 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
3795 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
3799 write_indent (indent
+ 2);
3805 write_indent (indent
);
3806 printf ("%s ", prefix
);
3807 write_attr_value (attr
, value
);
3808 printf ("%s\n", suffix
);
3812 /* Write a series of case statements for every instruction in list IE.
3813 INDENT is the amount of indentation to write before each case. */
3816 write_insn_cases (struct insn_ent
*ie
, int indent
)
3818 for (; ie
!= 0; ie
= ie
->next
)
3819 if (ie
->def
->insn_code
!= -1)
3821 write_indent (indent
);
3822 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
3823 printf ("case %d: /* define_peephole, line %d */\n",
3824 ie
->def
->insn_code
, ie
->def
->lineno
);
3826 printf ("case %d: /* %s */\n",
3827 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
3831 /* Write out the computation for one attribute value. */
3834 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
3835 int write_case_lines
, const char *prefix
, const char *suffix
,
3836 int indent
, rtx known_true
)
3838 if (av
->num_insns
== 0)
3841 if (av
->has_asm_insn
)
3843 write_indent (indent
);
3844 printf ("case -1:\n");
3845 write_indent (indent
+ 2);
3846 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3847 write_indent (indent
+ 2);
3848 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3849 write_indent (indent
+ 2);
3850 printf (" fatal_insn_not_found (insn);\n");
3853 if (write_case_lines
)
3854 write_insn_cases (av
->first_insn
, indent
);
3857 write_indent (indent
);
3858 printf ("default:\n");
3861 /* See what we have to do to output this value. */
3862 must_extract
= must_constrain
= address_used
= 0;
3863 walk_attr_value (av
->value
);
3867 write_indent (indent
+ 2);
3868 printf ("extract_constrain_insn_cached (insn);\n");
3870 else if (must_extract
)
3872 write_indent (indent
+ 2);
3873 printf ("extract_insn_cached (insn);\n");
3876 if (av
->num_insns
== 1)
3877 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3878 known_true
, av
->first_insn
->def
->insn_code
,
3879 av
->first_insn
->def
->insn_index
);
3881 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3884 if (strncmp (prefix
, "return", 6))
3886 write_indent (indent
+ 2);
3887 printf ("break;\n");
3892 /* Search for uses of non-const attributes and write code to cache them. */
3895 write_expr_attr_cache (rtx p
, struct attr_desc
*attr
)
3900 if (GET_CODE (p
) == EQ_ATTR
)
3902 if (XSTR (p
, 0) != attr
->name
)
3905 if (!attr
->is_numeric
)
3906 printf (" enum attr_%s ", attr
->name
);
3910 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
3914 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
3915 ie
= GET_RTX_LENGTH (GET_CODE (p
));
3916 for (i
= 0; i
< ie
; i
++)
3921 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
3926 je
= XVECLEN (p
, i
);
3927 for (j
= 0; j
< je
; ++j
)
3928 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
3937 /* Utilities to write in various forms. */
3940 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
3942 if (attr
->is_numeric
)
3948 if (num
> 9 || num
< 0)
3949 printf (" /* 0x%x */", num
);
3953 write_upcase (attr
->name
);
3960 write_attr_value (struct attr_desc
*attr
, rtx value
)
3964 switch (GET_CODE (value
))
3967 write_attr_valueq (attr
, XSTR (value
, 0));
3971 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
3975 print_c_condition (XSTR (value
, 0));
3980 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
3981 printf ("get_attr_%s (%s)", attr2
->name
,
3982 (attr2
->is_const
? "" : "insn"));
4003 write_attr_value (attr
, XEXP (value
, 0));
4007 write_attr_value (attr
, XEXP (value
, 1));
4016 write_upcase (const char *str
)
4020 /* The argument of TOUPPER should not have side effects. */
4021 putchar (TOUPPER(*str
));
4027 write_indent (int indent
)
4029 for (; indent
> 8; indent
-= 8)
4032 for (; indent
; indent
--)
4036 /* Write a subroutine that is given an insn that requires a delay slot, a
4037 delay slot ordinal, and a candidate insn. It returns nonzero if the
4038 candidate can be placed in the specified delay slot of the insn.
4040 We can write as many as three subroutines. `eligible_for_delay'
4041 handles normal delay slots, `eligible_for_annul_true' indicates that
4042 the specified insn can be annulled if the branch is true, and likewise
4043 for `eligible_for_annul_false'.
4045 KIND is a string distinguishing these three cases ("delay", "annul_true",
4046 or "annul_false"). */
4049 write_eligible_delay (const char *kind
)
4051 struct delay_desc
*delay
;
4055 struct attr_desc
*attr
;
4056 struct attr_value
*av
, *common_av
;
4059 /* Compute the maximum number of delay slots required. We use the delay
4060 ordinal times this number plus one, plus the slot number as an index into
4061 the appropriate predicate to test. */
4063 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4064 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4065 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4067 /* Write function prelude. */
4070 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4073 printf (" rtx insn;\n");
4075 printf (" gcc_assert (slot < %d);\n", max_slots
);
4077 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4078 converts a compound instruction into a loop. */
4079 printf (" if (!INSN_P (candidate_insn))\n");
4080 printf (" return 0;\n");
4083 /* If more than one delay type, find out which type the delay insn is. */
4087 attr
= find_attr (&delay_type_str
, 0);
4089 common_av
= find_most_used (attr
);
4091 printf (" insn = delay_insn;\n");
4092 printf (" switch (recog_memoized (insn))\n");
4095 sprintf (str
, " * %d;\n break;", max_slots
);
4096 for (av
= attr
->first_value
; av
; av
= av
->next
)
4097 if (av
!= common_av
)
4098 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4100 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4103 /* Ensure matched. Otherwise, shouldn't have been called. */
4104 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4107 /* If just one type of delay slot, write simple switch. */
4108 if (num_delays
== 1 && max_slots
== 1)
4110 printf (" insn = candidate_insn;\n");
4111 printf (" switch (recog_memoized (insn))\n");
4114 attr
= find_attr (&delay_1_0_str
, 0);
4116 common_av
= find_most_used (attr
);
4118 for (av
= attr
->first_value
; av
; av
= av
->next
)
4119 if (av
!= common_av
)
4120 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4122 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4128 /* Write a nested CASE. The first indicates which condition we need to
4129 test, and the inner CASE tests the condition. */
4130 printf (" insn = candidate_insn;\n");
4131 printf (" switch (slot)\n");
4134 for (delay
= delays
; delay
; delay
= delay
->next
)
4135 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4137 printf (" case %d:\n",
4138 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4139 printf (" switch (recog_memoized (insn))\n");
4142 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4144 attr
= find_attr (&pstr
, 0);
4146 common_av
= find_most_used (attr
);
4148 for (av
= attr
->first_value
; av
; av
= av
->next
)
4149 if (av
!= common_av
)
4150 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4152 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4156 printf (" default:\n");
4157 printf (" gcc_unreachable ();\n");
4164 /* This page contains miscellaneous utility routines. */
4166 /* Given a pointer to a (char *), return a malloc'ed string containing the
4167 next comma-separated element. Advance the pointer to after the string
4168 scanned, or the end-of-string. Return NULL if at end of string. */
4171 next_comma_elt (const char **pstr
)
4175 start
= scan_comma_elt (pstr
);
4180 return attr_string (start
, *pstr
- start
);
4183 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4184 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4185 replaced by a pointer to a canonical copy of the string. */
4187 static struct attr_desc
*
4188 find_attr (const char **name_p
, int create
)
4190 struct attr_desc
*attr
;
4192 const char *name
= *name_p
;
4194 /* Before we resort to using `strcmp', see if the string address matches
4195 anywhere. In most cases, it should have been canonicalized to do so. */
4196 if (name
== alternative_name
)
4199 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4200 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4201 if (name
== attr
->name
)
4204 /* Otherwise, do it the slow way. */
4205 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4206 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4208 *name_p
= attr
->name
;
4215 attr
= oballoc (sizeof (struct attr_desc
));
4216 attr
->name
= DEF_ATTR_STRING (name
);
4217 attr
->first_value
= attr
->default_val
= NULL
;
4218 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4219 attr
->next
= attrs
[index
];
4220 attrs
[index
] = attr
;
4222 *name_p
= attr
->name
;
4227 /* Create internal attribute with the given default value. */
4230 make_internal_attr (const char *name
, rtx value
, int special
)
4232 struct attr_desc
*attr
;
4234 attr
= find_attr (&name
, 1);
4235 gcc_assert (!attr
->default_val
);
4237 attr
->is_numeric
= 1;
4239 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4240 attr
->default_val
= get_attr_value (value
, attr
, -2);
4243 /* Find the most used value of an attribute. */
4245 static struct attr_value
*
4246 find_most_used (struct attr_desc
*attr
)
4248 struct attr_value
*av
;
4249 struct attr_value
*most_used
;
4255 for (av
= attr
->first_value
; av
; av
= av
->next
)
4256 if (av
->num_insns
> nuses
)
4257 nuses
= av
->num_insns
, most_used
= av
;
4262 /* Return (attr_value "n") */
4265 make_numeric_value (int n
)
4267 static rtx int_values
[20];
4271 gcc_assert (n
>= 0);
4273 if (n
< 20 && int_values
[n
])
4274 return int_values
[n
];
4276 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4277 exp
= attr_rtx (CONST_STRING
, p
);
4280 int_values
[n
] = exp
;
4286 copy_rtx_unchanging (rtx orig
)
4288 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4291 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4295 /* Determine if an insn has a constant number of delay slots, i.e., the
4296 number of delay slots is not a function of the length of the insn. */
4299 write_const_num_delay_slots (void)
4301 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4302 struct attr_value
*av
;
4306 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4308 printf (" switch (recog_memoized (insn))\n");
4311 for (av
= attr
->first_value
; av
; av
= av
->next
)
4314 walk_attr_value (av
->value
);
4316 write_insn_cases (av
->first_insn
, 4);
4319 printf (" default:\n");
4320 printf (" return 1;\n");
4321 printf (" }\n}\n\n");
4325 /* Synthetic attributes used by insn-automata.c and the scheduler.
4326 These are primarily concerned with (define_insn_reservation)
4331 struct insn_reserv
*next
;
4334 int default_latency
;
4337 /* Sequence number of this insn. */
4340 /* Whether a (define_bypass) construct names this insn in its
4345 static struct insn_reserv
*all_insn_reservs
= 0;
4346 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4347 static size_t n_insn_reservs
;
4349 /* Store information from a DEFINE_INSN_RESERVATION for future
4350 attribute generation. */
4352 gen_insn_reserv (rtx def
)
4354 struct insn_reserv
*decl
= oballoc (sizeof (struct insn_reserv
));
4356 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4357 decl
->default_latency
= XINT (def
, 1);
4358 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4359 decl
->insn_num
= n_insn_reservs
;
4360 decl
->bypassed
= false;
4363 *last_insn_reserv_p
= decl
;
4364 last_insn_reserv_p
= &decl
->next
;
4368 /* Store information from a DEFINE_BYPASS for future attribute
4369 generation. The only thing we care about is the list of output
4370 insns, which will later be used to tag reservation structures with
4371 a 'bypassed' bit. */
4375 struct bypass_list
*next
;
4379 static struct bypass_list
*all_bypasses
;
4380 static size_t n_bypasses
;
4383 gen_bypass_1 (const char *s
, size_t len
)
4385 struct bypass_list
*b
;
4390 s
= attr_string (s
, len
);
4391 for (b
= all_bypasses
; b
; b
= b
->next
)
4393 return; /* already got that one */
4395 b
= oballoc (sizeof (struct bypass_list
));
4397 b
->next
= all_bypasses
;
4403 gen_bypass (rtx def
)
4405 const char *p
, *base
;
4407 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4410 gen_bypass_1 (base
, p
- base
);
4413 while (ISSPACE (*p
));
4416 gen_bypass_1 (base
, p
- base
);
4419 /* Find and mark all of the bypassed insns. */
4421 process_bypasses (void)
4423 struct bypass_list
*b
;
4424 struct insn_reserv
*r
;
4426 /* The reservation list is likely to be much longer than the bypass
4428 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4429 for (b
= all_bypasses
; b
; b
= b
->next
)
4430 if (r
->name
== b
->insn
)
4434 /* Create all of the attributes that describe automaton properties. */
4436 make_automaton_attrs (void)
4439 struct insn_reserv
*decl
;
4440 rtx code_exp
, lats_exp
, byps_exp
;
4442 if (n_insn_reservs
== 0)
4445 code_exp
= rtx_alloc (COND
);
4446 lats_exp
= rtx_alloc (COND
);
4448 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4449 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4451 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4452 XEXP (lats_exp
, 1) = make_numeric_value (0);
4454 for (decl
= all_insn_reservs
, i
= 0;
4456 decl
= decl
->next
, i
+= 2)
4458 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
4459 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
4461 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
4462 XVECEXP (lats_exp
, 0, i
+1) = make_numeric_value (decl
->default_latency
);
4465 if (n_bypasses
== 0)
4466 byps_exp
= make_numeric_value (0);
4469 process_bypasses ();
4471 byps_exp
= rtx_alloc (COND
);
4472 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypasses
* 2);
4473 XEXP (byps_exp
, 1) = make_numeric_value (0);
4474 for (decl
= all_insn_reservs
, i
= 0;
4479 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
4480 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
4485 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
4486 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
4487 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
4491 main (int argc
, char **argv
)
4494 struct attr_desc
*attr
;
4495 struct insn_def
*id
;
4499 progname
= "genattrtab";
4501 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
4502 return (FATAL_EXIT_CODE
);
4504 obstack_init (hash_obstack
);
4505 obstack_init (temp_obstack
);
4507 /* Set up true and false rtx's */
4508 true_rtx
= rtx_alloc (CONST_INT
);
4509 XWINT (true_rtx
, 0) = 1;
4510 false_rtx
= rtx_alloc (CONST_INT
);
4511 XWINT (false_rtx
, 0) = 0;
4512 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4513 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4515 alternative_name
= DEF_ATTR_STRING ("alternative");
4516 length_str
= DEF_ATTR_STRING ("length");
4517 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4518 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4519 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4521 printf ("/* Generated automatically by the program `genattrtab'\n\
4522 from the machine description file `md'. */\n\n");
4524 /* Read the machine description. */
4530 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4534 switch (GET_CODE (desc
))
4537 case DEFINE_PEEPHOLE
:
4538 case DEFINE_ASM_ATTRIBUTES
:
4539 gen_insn (desc
, lineno
);
4543 gen_attr (desc
, lineno
);
4547 gen_delay (desc
, lineno
);
4550 case DEFINE_INSN_RESERVATION
:
4551 gen_insn_reserv (desc
);
4561 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4562 insn_index_number
++;
4566 return FATAL_EXIT_CODE
;
4570 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4571 if (! got_define_asm_attributes
)
4573 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4574 XVEC (tem
, 0) = rtvec_alloc (0);
4578 /* Expand DEFINE_DELAY information into new attribute. */
4582 printf ("#include \"config.h\"\n");
4583 printf ("#include \"system.h\"\n");
4584 printf ("#include \"coretypes.h\"\n");
4585 printf ("#include \"tm.h\"\n");
4586 printf ("#include \"rtl.h\"\n");
4587 printf ("#include \"tm_p.h\"\n");
4588 printf ("#include \"insn-config.h\"\n");
4589 printf ("#include \"recog.h\"\n");
4590 printf ("#include \"regs.h\"\n");
4591 printf ("#include \"real.h\"\n");
4592 printf ("#include \"output.h\"\n");
4593 printf ("#include \"insn-attr.h\"\n");
4594 printf ("#include \"toplev.h\"\n");
4595 printf ("#include \"flags.h\"\n");
4596 printf ("#include \"function.h\"\n");
4598 printf ("#define operands recog_data.operand\n\n");
4600 /* Make `insn_alternatives'. */
4601 insn_alternatives
= oballoc (insn_code_number
* sizeof (int));
4602 for (id
= defs
; id
; id
= id
->next
)
4603 if (id
->insn_code
>= 0)
4604 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4606 /* Make `insn_n_alternatives'. */
4607 insn_n_alternatives
= oballoc (insn_code_number
* sizeof (int));
4608 for (id
= defs
; id
; id
= id
->next
)
4609 if (id
->insn_code
>= 0)
4610 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4612 /* Construct extra attributes for automata. */
4613 make_automaton_attrs ();
4615 /* Prepare to write out attribute subroutines by checking everything stored
4616 away and building the attribute cases. */
4620 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4621 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4622 attr
->default_val
->value
4623 = check_attr_value (attr
->default_val
->value
, attr
);
4626 return FATAL_EXIT_CODE
;
4628 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4629 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4632 /* Construct extra attributes for `length'. */
4633 make_length_attrs ();
4635 /* Perform any possible optimizations to speed up compilation. */
4638 /* Now write out all the `gen_attr_...' routines. Do these before the
4639 special routines so that they get defined before they are used. */
4641 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4642 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4644 if (! attr
->is_special
&& ! attr
->is_const
)
4645 write_attr_get (attr
);
4648 /* Write out delay eligibility information, if DEFINE_DELAY present.
4649 (The function to compute the number of delay slots will be written
4653 write_eligible_delay ("delay");
4654 if (have_annul_true
)
4655 write_eligible_delay ("annul_true");
4656 if (have_annul_false
)
4657 write_eligible_delay ("annul_false");
4660 /* Write out constant delay slot info. */
4661 write_const_num_delay_slots ();
4663 write_length_unit_log ();
4666 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);