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
);
962 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
966 if (XVECLEN (exp
, 0) % 2 != 0)
968 message_with_line (attr
->lineno
,
969 "first operand of COND must have even length");
974 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
976 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
977 attr
? attr
->is_const
: 0,
978 attr
? attr
->lineno
: 0);
979 XVECEXP (exp
, 0, i
+ 1)
980 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
983 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
988 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
991 message_with_line (attr
? attr
->lineno
: 0,
992 "unknown attribute `%s' in ATTR",
996 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
998 message_with_line (attr
->lineno
,
999 "non-constant attribute `%s' referenced from `%s'",
1000 XSTR (exp
, 0), attr
->name
);
1004 && attr
->is_numeric
!= attr2
->is_numeric
)
1006 message_with_line (attr
->lineno
,
1007 "numeric attribute mismatch calling `%s' from `%s'",
1008 XSTR (exp
, 0), attr
->name
);
1015 /* A constant SYMBOL_REF is valid as a constant attribute test and
1016 is expanded later by make_canonical into a COND. In a non-constant
1017 attribute test, it is left be. */
1018 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1021 message_with_line (attr
? attr
->lineno
: 0,
1022 "invalid operation `%s' for attribute value",
1023 GET_RTX_NAME (GET_CODE (exp
)));
1031 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1032 It becomes a COND with each test being (eq_attr "alternative" "n") */
1035 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1037 int num_alt
= id
->num_alternatives
;
1041 if (XVECLEN (exp
, 1) != num_alt
)
1043 message_with_line (id
->lineno
,
1044 "bad number of entries in SET_ATTR_ALTERNATIVE");
1049 /* Make a COND with all tests but the last. Select the last value via the
1051 condexp
= rtx_alloc (COND
);
1052 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1054 for (i
= 0; i
< num_alt
- 1; i
++)
1057 p
= attr_numeral (i
);
1059 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1060 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1063 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1065 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1068 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1069 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1072 convert_set_attr (rtx exp
, struct insn_def
*id
)
1075 const char *name_ptr
;
1079 /* See how many alternative specified. */
1080 n
= n_comma_elts (XSTR (exp
, 1));
1082 return attr_rtx (SET
,
1083 attr_rtx (ATTR
, XSTR (exp
, 0)),
1084 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1086 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1087 XSTR (newexp
, 0) = XSTR (exp
, 0);
1088 XVEC (newexp
, 1) = rtvec_alloc (n
);
1090 /* Process each comma-separated name. */
1091 name_ptr
= XSTR (exp
, 1);
1093 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1094 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1096 return convert_set_attr_alternative (newexp
, id
);
1099 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1100 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1106 struct insn_def
*id
;
1107 struct attr_desc
*attr
;
1111 for (id
= defs
; id
; id
= id
->next
)
1113 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1116 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1118 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1119 switch (GET_CODE (value
))
1122 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1124 message_with_line (id
->lineno
, "bad attribute set");
1130 case SET_ATTR_ALTERNATIVE
:
1131 value
= convert_set_attr_alternative (value
, id
);
1135 value
= convert_set_attr (value
, id
);
1139 message_with_line (id
->lineno
, "invalid attribute code %s",
1140 GET_RTX_NAME (GET_CODE (value
)));
1144 if (value
== NULL_RTX
)
1147 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1149 message_with_line (id
->lineno
, "unknown attribute %s",
1150 XSTR (XEXP (value
, 0), 0));
1155 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1156 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1161 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1162 expressions by converting them into a COND. This removes cases from this
1163 program. Also, replace an attribute value of "*" with the default attribute
1167 make_canonical (struct attr_desc
*attr
, rtx exp
)
1172 switch (GET_CODE (exp
))
1175 exp
= make_numeric_value (INTVAL (exp
));
1179 if (! strcmp (XSTR (exp
, 0), "*"))
1181 if (attr
== 0 || attr
->default_val
== 0)
1182 fatal ("(attr_value \"*\") used in invalid context");
1183 exp
= attr
->default_val
->value
;
1186 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1191 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1193 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1194 This makes the COND something that won't be considered an arbitrary
1195 expression by walk_attr_value. */
1196 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1197 exp
= check_attr_value (exp
, attr
);
1201 newexp
= rtx_alloc (COND
);
1202 XVEC (newexp
, 0) = rtvec_alloc (2);
1203 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1204 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1206 XEXP (newexp
, 1) = XEXP (exp
, 2);
1209 /* Fall through to COND case since this is now a COND. */
1216 /* First, check for degenerate COND. */
1217 if (XVECLEN (exp
, 0) == 0)
1218 return make_canonical (attr
, XEXP (exp
, 1));
1219 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1221 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1223 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1224 XVECEXP (exp
, 0, i
+ 1)
1225 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1226 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1242 copy_boolean (rtx exp
)
1244 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1245 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1246 copy_boolean (XEXP (exp
, 1)));
1247 if (GET_CODE (exp
) == MATCH_OPERAND
)
1249 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1250 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1252 else if (GET_CODE (exp
) == EQ_ATTR
)
1254 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1255 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1261 /* Given a value and an attribute description, return a `struct attr_value *'
1262 that represents that value. This is either an existing structure, if the
1263 value has been previously encountered, or a newly-created structure.
1265 `insn_code' is the code of an insn whose attribute has the specified
1266 value (-2 if not processing an insn). We ensure that all insns for
1267 a given value have the same number of alternatives if the value checks
1270 static struct attr_value
*
1271 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1273 struct attr_value
*av
;
1276 value
= make_canonical (attr
, value
);
1277 if (compares_alternatives_p (value
))
1279 if (insn_code
< 0 || insn_alternatives
== NULL
)
1280 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1282 num_alt
= insn_alternatives
[insn_code
];
1285 for (av
= attr
->first_value
; av
; av
= av
->next
)
1286 if (rtx_equal_p (value
, av
->value
)
1287 && (num_alt
== 0 || av
->first_insn
== NULL
1288 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1291 av
= oballoc (sizeof (struct attr_value
));
1293 av
->next
= attr
->first_value
;
1294 attr
->first_value
= av
;
1295 av
->first_insn
= NULL
;
1297 av
->has_asm_insn
= 0;
1302 /* After all DEFINE_DELAYs have been read in, create internal attributes
1303 to generate the required routines.
1305 First, we compute the number of delay slots for each insn (as a COND of
1306 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1307 delay type is specified, we compute a similar function giving the
1308 DEFINE_DELAY ordinal for each insn.
1310 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1311 tells whether a given insn can be in that delay slot.
1313 Normal attribute filling and optimization expands these to contain the
1314 information needed to handle delay slots. */
1317 expand_delays (void)
1319 struct delay_desc
*delay
;
1325 /* First, generate data for `num_delay_slots' function. */
1327 condexp
= rtx_alloc (COND
);
1328 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1329 XEXP (condexp
, 1) = make_numeric_value (0);
1331 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1333 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1334 XVECEXP (condexp
, 0, i
+ 1)
1335 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1338 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1340 /* If more than one delay type, do the same for computing the delay type. */
1343 condexp
= rtx_alloc (COND
);
1344 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1345 XEXP (condexp
, 1) = make_numeric_value (0);
1347 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1349 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1350 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1353 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1356 /* For each delay possibility and delay slot, compute an eligibility
1357 attribute for non-annulled insns and for each type of annulled (annul
1358 if true and annul if false). */
1359 for (delay
= delays
; delay
; delay
= delay
->next
)
1361 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1363 condexp
= XVECEXP (delay
->def
, 1, i
);
1365 condexp
= false_rtx
;
1366 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1367 make_numeric_value (1), make_numeric_value (0));
1369 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1370 "*delay_%d_%d", delay
->num
, i
/ 3);
1371 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1373 if (have_annul_true
)
1375 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1376 if (condexp
== 0) condexp
= false_rtx
;
1377 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1378 make_numeric_value (1),
1379 make_numeric_value (0));
1380 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1381 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1382 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1385 if (have_annul_false
)
1387 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1388 if (condexp
== 0) condexp
= false_rtx
;
1389 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1390 make_numeric_value (1),
1391 make_numeric_value (0));
1392 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1393 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1394 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1400 /* Once all attributes and insns have been read and checked, we construct for
1401 each attribute value a list of all the insns that have that value for
1405 fill_attr (struct attr_desc
*attr
)
1407 struct attr_value
*av
;
1408 struct insn_ent
*ie
;
1409 struct insn_def
*id
;
1413 /* Don't fill constant attributes. The value is independent of
1414 any particular insn. */
1418 for (id
= defs
; id
; id
= id
->next
)
1420 /* If no value is specified for this insn for this attribute, use the
1423 if (XVEC (id
->def
, id
->vec_idx
))
1424 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1425 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1427 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1430 av
= attr
->default_val
;
1432 av
= get_attr_value (value
, attr
, id
->insn_code
);
1434 ie
= oballoc (sizeof (struct insn_ent
));
1436 insert_insn_ent (av
, ie
);
1440 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1441 test that checks relative positions of insns (uses MATCH_DUP or PC).
1442 If so, replace it with what is obtained by passing the expression to
1443 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1444 recursively on each value (including the default value). Otherwise,
1445 return the value returned by NO_ADDRESS_FN applied to EXP. */
1448 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1449 rtx (*address_fn
) (rtx
))
1454 if (GET_CODE (exp
) == COND
)
1456 /* See if any tests use addresses. */
1458 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1459 walk_attr_value (XVECEXP (exp
, 0, i
));
1462 return (*address_fn
) (exp
);
1464 /* Make a new copy of this COND, replacing each element. */
1465 newexp
= rtx_alloc (COND
);
1466 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1467 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1469 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1470 XVECEXP (newexp
, 0, i
+ 1)
1471 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1472 no_address_fn
, address_fn
);
1475 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1476 no_address_fn
, address_fn
);
1481 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1484 walk_attr_value (XEXP (exp
, 0));
1486 return (*address_fn
) (exp
);
1488 return attr_rtx (IF_THEN_ELSE
,
1489 substitute_address (XEXP (exp
, 0),
1490 no_address_fn
, address_fn
),
1491 substitute_address (XEXP (exp
, 1),
1492 no_address_fn
, address_fn
),
1493 substitute_address (XEXP (exp
, 2),
1494 no_address_fn
, address_fn
));
1497 return (*no_address_fn
) (exp
);
1500 /* Make new attributes from the `length' attribute. The following are made,
1501 each corresponding to a function called from `shorten_branches' or
1504 *insn_default_length This is the length of the insn to be returned
1505 by `get_attr_length' before `shorten_branches'
1506 has been called. In each case where the length
1507 depends on relative addresses, the largest
1508 possible is used. This routine is also used
1509 to compute the initial size of the insn.
1511 *insn_variable_length_p This returns 1 if the insn's length depends
1512 on relative addresses, zero otherwise.
1514 *insn_current_length This is only called when it is known that the
1515 insn has a variable length and returns the
1516 current length, based on relative addresses.
1520 make_length_attrs (void)
1522 static const char *new_names
[] =
1524 "*insn_default_length",
1526 "*insn_variable_length_p",
1527 "*insn_current_length"
1529 static rtx (*const no_address_fn
[]) (rtx
)
1530 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1531 static rtx (*const address_fn
[]) (rtx
)
1532 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1534 struct attr_desc
*length_attr
, *new_attr
;
1535 struct attr_value
*av
, *new_av
;
1536 struct insn_ent
*ie
, *new_ie
;
1538 /* See if length attribute is defined. If so, it must be numeric. Make
1539 it special so we don't output anything for it. */
1540 length_attr
= find_attr (&length_str
, 0);
1541 if (length_attr
== 0)
1544 if (! length_attr
->is_numeric
)
1545 fatal ("length attribute must be numeric");
1547 length_attr
->is_const
= 0;
1548 length_attr
->is_special
= 1;
1550 /* Make each new attribute, in turn. */
1551 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1553 make_internal_attr (new_names
[i
],
1554 substitute_address (length_attr
->default_val
->value
,
1555 no_address_fn
[i
], address_fn
[i
]),
1557 new_attr
= find_attr (&new_names
[i
], 0);
1558 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1559 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1561 new_av
= get_attr_value (substitute_address (av
->value
,
1564 new_attr
, ie
->def
->insn_code
);
1565 new_ie
= oballoc (sizeof (struct insn_ent
));
1566 new_ie
->def
= ie
->def
;
1567 insert_insn_ent (new_av
, new_ie
);
1572 /* Utility functions called from above routine. */
1575 identity_fn (rtx exp
)
1581 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1583 return make_numeric_value (0);
1587 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1589 return make_numeric_value (1);
1596 return make_numeric_value (max_attr_value (exp
, &unknown
));
1603 return make_numeric_value (min_attr_value (exp
, &unknown
));
1607 write_length_unit_log (void)
1609 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1610 struct attr_value
*av
;
1611 struct insn_ent
*ie
;
1612 unsigned int length_unit_log
, length_or
;
1615 if (length_attr
== 0)
1617 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1618 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1619 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1620 length_or
|= or_attr_value (av
->value
, &unknown
);
1623 length_unit_log
= 0;
1626 length_or
= ~length_or
;
1627 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1630 printf ("const int length_unit_log = %u;\n", length_unit_log
);
1633 /* Take a COND expression and see if any of the conditions in it can be
1634 simplified. If any are known true or known false for the particular insn
1635 code, the COND can be further simplified.
1637 Also call ourselves on any COND operations that are values of this COND.
1639 We do not modify EXP; rather, we make and return a new rtx. */
1642 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1645 /* We store the desired contents here,
1646 then build a new expression if they don't match EXP. */
1647 rtx defval
= XEXP (exp
, 1);
1648 rtx new_defval
= XEXP (exp
, 1);
1649 int len
= XVECLEN (exp
, 0);
1650 rtx
*tests
= XNEWVEC (rtx
, len
);
1654 /* This lets us free all storage allocated below, if appropriate. */
1655 obstack_finish (rtl_obstack
);
1657 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1659 /* See if default value needs simplification. */
1660 if (GET_CODE (defval
) == COND
)
1661 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1663 /* Simplify the subexpressions, and see what tests we can get rid of. */
1665 for (i
= 0; i
< len
; i
+= 2)
1667 rtx newtest
, newval
;
1669 /* Simplify this test. */
1670 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1673 newval
= tests
[i
+ 1];
1674 /* See if this value may need simplification. */
1675 if (GET_CODE (newval
) == COND
)
1676 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1678 /* Look for ways to delete or combine this test. */
1679 if (newtest
== true_rtx
)
1681 /* If test is true, make this value the default
1682 and discard this + any following tests. */
1684 defval
= tests
[i
+ 1];
1685 new_defval
= newval
;
1688 else if (newtest
== false_rtx
)
1690 /* If test is false, discard it and its value. */
1691 for (j
= i
; j
< len
- 2; j
++)
1692 tests
[j
] = tests
[j
+ 2];
1697 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1699 /* If this value and the value for the prev test are the same,
1703 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1704 insn_code
, insn_index
);
1706 /* Delete this test/value. */
1707 for (j
= i
; j
< len
- 2; j
++)
1708 tests
[j
] = tests
[j
+ 2];
1714 tests
[i
+ 1] = newval
;
1717 /* If the last test in a COND has the same value
1718 as the default value, that test isn't needed. */
1720 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1723 /* See if we changed anything. */
1724 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1727 for (i
= 0; i
< len
; i
++)
1728 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1736 if (GET_CODE (defval
) == COND
)
1737 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1745 rtx newexp
= rtx_alloc (COND
);
1747 XVEC (newexp
, 0) = rtvec_alloc (len
);
1748 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1749 XEXP (newexp
, 1) = new_defval
;
1756 /* Remove an insn entry from an attribute value. */
1759 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1761 struct insn_ent
*previe
;
1763 if (av
->first_insn
== ie
)
1764 av
->first_insn
= ie
->next
;
1767 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1769 previe
->next
= ie
->next
;
1773 if (ie
->def
->insn_code
== -1)
1774 av
->has_asm_insn
= 0;
1779 /* Insert an insn entry in an attribute value list. */
1782 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1784 ie
->next
= av
->first_insn
;
1785 av
->first_insn
= ie
;
1787 if (ie
->def
->insn_code
== -1)
1788 av
->has_asm_insn
= 1;
1793 /* This is a utility routine to take an expression that is a tree of either
1794 AND or IOR expressions and insert a new term. The new term will be
1795 inserted at the right side of the first node whose code does not match
1796 the root. A new node will be created with the root's code. Its left
1797 side will be the old right side and its right side will be the new
1800 If the `term' is itself a tree, all its leaves will be inserted. */
1803 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1807 /* Avoid consing in some special cases. */
1808 if (code
== AND
&& term
== true_rtx
)
1810 if (code
== AND
&& term
== false_rtx
)
1812 if (code
== AND
&& exp
== true_rtx
)
1814 if (code
== AND
&& exp
== false_rtx
)
1816 if (code
== IOR
&& term
== true_rtx
)
1818 if (code
== IOR
&& term
== false_rtx
)
1820 if (code
== IOR
&& exp
== true_rtx
)
1822 if (code
== IOR
&& exp
== false_rtx
)
1824 if (attr_equal_p (exp
, term
))
1827 if (GET_CODE (term
) == code
)
1829 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1830 insn_code
, insn_index
);
1831 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1832 insn_code
, insn_index
);
1837 if (GET_CODE (exp
) == code
)
1839 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1840 term
, insn_code
, insn_index
);
1841 if (new != XEXP (exp
, 1))
1842 /* Make a copy of this expression and call recursively. */
1843 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1849 /* Insert the new term. */
1850 newexp
= attr_rtx (code
, exp
, term
);
1853 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1856 /* If we have an expression which AND's a bunch of
1857 (not (eq_attrq "alternative" "n"))
1858 terms, we may have covered all or all but one of the possible alternatives.
1859 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1861 This routine is passed an expression and either AND or IOR. It returns a
1862 bitmask indicating which alternatives are mentioned within EXP. */
1865 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1868 if (GET_CODE (exp
) == code
)
1869 return compute_alternative_mask (XEXP (exp
, 0), code
)
1870 | compute_alternative_mask (XEXP (exp
, 1), code
);
1872 else if (code
== AND
&& GET_CODE (exp
) == NOT
1873 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1874 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1875 string
= XSTR (XEXP (exp
, 0), 1);
1877 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1878 && XSTR (exp
, 0) == alternative_name
)
1879 string
= XSTR (exp
, 1);
1881 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1883 if (code
== AND
&& XINT (exp
, 1))
1884 return XINT (exp
, 0);
1886 if (code
== IOR
&& !XINT (exp
, 1))
1887 return XINT (exp
, 0);
1895 return 1 << (string
[0] - '0');
1896 return 1 << atoi (string
);
1899 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1900 attribute with the value represented by that bit. */
1903 make_alternative_compare (int mask
)
1905 return mk_attr_alt (mask
);
1908 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1909 of "attr" for this insn code. From that value, we can compute a test
1910 showing when the EQ_ATTR will be true. This routine performs that
1911 computation. If a test condition involves an address, we leave the EQ_ATTR
1912 intact because addresses are only valid for the `length' attribute.
1914 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1915 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1918 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
1925 switch (GET_CODE (value
))
1928 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
1939 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
1940 gcc_assert (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2
1943 strcpy (string
, XSTR (exp
, 0));
1944 strcat (string
, "_");
1945 strcat (string
, XSTR (exp
, 1));
1946 for (p
= string
; *p
; p
++)
1949 newexp
= attr_rtx (EQ
, value
,
1950 attr_rtx (SYMBOL_REF
,
1951 DEF_ATTR_STRING (string
)));
1956 /* We construct an IOR of all the cases for which the
1957 requested attribute value is present. Since we start with
1958 FALSE, if it is not present, FALSE will be returned.
1960 Each case is the AND of the NOT's of the previous conditions with the
1961 current condition; in the default case the current condition is TRUE.
1963 For each possible COND value, call ourselves recursively.
1965 The extra TRUE and FALSE expressions will be eliminated by another
1966 call to the simplification routine. */
1971 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
1973 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
1974 insn_code
, insn_index
);
1976 right
= insert_right_side (AND
, andexp
, this,
1977 insn_code
, insn_index
);
1978 right
= insert_right_side (AND
, right
,
1979 evaluate_eq_attr (exp
,
1982 insn_code
, insn_index
),
1983 insn_code
, insn_index
);
1984 orexp
= insert_right_side (IOR
, orexp
, right
,
1985 insn_code
, insn_index
);
1987 /* Add this condition into the AND expression. */
1988 newexp
= attr_rtx (NOT
, this);
1989 andexp
= insert_right_side (AND
, andexp
, newexp
,
1990 insn_code
, insn_index
);
1993 /* Handle the default case. */
1994 right
= insert_right_side (AND
, andexp
,
1995 evaluate_eq_attr (exp
, XEXP (value
, 1),
1996 insn_code
, insn_index
),
1997 insn_code
, insn_index
);
1998 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2005 /* If uses an address, must return original expression. But set the
2006 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2009 walk_attr_value (newexp
);
2013 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2014 return copy_rtx_unchanging (exp
);
2021 /* This routine is called when an AND of a term with a tree of AND's is
2022 encountered. If the term or its complement is present in the tree, it
2023 can be replaced with TRUE or FALSE, respectively.
2025 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2026 be true and hence are complementary.
2028 There is one special case: If we see
2029 (and (not (eq_attr "att" "v1"))
2030 (eq_attr "att" "v2"))
2031 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2032 replace the term, not anything in the AND tree. So we pass a pointer to
2036 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2041 int left_eliminates_term
, right_eliminates_term
;
2043 if (GET_CODE (exp
) == AND
)
2045 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2046 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2047 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2049 newexp
= attr_rtx (AND
, left
, right
);
2051 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2055 else if (GET_CODE (exp
) == IOR
)
2057 /* For the IOR case, we do the same as above, except that we can
2058 only eliminate `term' if both sides of the IOR would do so. */
2060 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2061 left_eliminates_term
= (temp
== true_rtx
);
2064 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2065 right_eliminates_term
= (temp
== true_rtx
);
2067 if (left_eliminates_term
&& right_eliminates_term
)
2070 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2072 newexp
= attr_rtx (IOR
, left
, right
);
2074 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2078 /* Check for simplifications. Do some extra checking here since this
2079 routine is called so many times. */
2084 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2087 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2090 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2092 if (attr_alt_subset_p (*pterm
, exp
))
2095 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2098 if (attr_alt_subset_p (exp
, *pterm
))
2104 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2106 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2109 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2115 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2116 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2118 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2121 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2127 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2128 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2130 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2133 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2139 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2141 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2145 else if (GET_CODE (exp
) == NOT
)
2147 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2151 else if (GET_CODE (*pterm
) == NOT
)
2153 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2157 else if (attr_equal_p (exp
, *pterm
))
2163 /* Similar to `simplify_and_tree', but for IOR trees. */
2166 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2171 int left_eliminates_term
, right_eliminates_term
;
2173 if (GET_CODE (exp
) == IOR
)
2175 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2176 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2177 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2179 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2181 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2185 else if (GET_CODE (exp
) == AND
)
2187 /* For the AND case, we do the same as above, except that we can
2188 only eliminate `term' if both sides of the AND would do so. */
2190 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2191 left_eliminates_term
= (temp
== false_rtx
);
2194 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2195 right_eliminates_term
= (temp
== false_rtx
);
2197 if (left_eliminates_term
&& right_eliminates_term
)
2200 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2202 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2204 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2208 if (attr_equal_p (exp
, *pterm
))
2211 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2214 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2217 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2218 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2219 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2222 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2223 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2224 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2230 /* Compute approximate cost of the expression. Used to decide whether
2231 expression is cheap enough for inline. */
2233 attr_rtx_cost (rtx x
)
2239 code
= GET_CODE (x
);
2252 /* Alternatives don't result into function call. */
2253 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2260 const char *fmt
= GET_RTX_FORMAT (code
);
2261 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2267 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2268 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2271 cost
+= attr_rtx_cost (XEXP (x
, i
));
2281 /* Simplify test expression and use temporary obstack in order to avoid
2282 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2283 and avoid unnecessary copying if possible. */
2286 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2289 struct obstack
*old
;
2290 if (ATTR_IND_SIMPLIFIED_P (exp
))
2293 rtl_obstack
= temp_obstack
;
2294 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2296 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2298 return attr_copy_rtx (x
);
2301 /* Returns true if S1 is a subset of S2. */
2304 attr_alt_subset_p (rtx s1
, rtx s2
)
2306 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2309 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2312 return !(XINT (s1
, 0) & XINT (s2
, 0));
2318 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2325 /* Returns true if S1 is a subset of complement of S2. */
2328 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2330 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2333 return !(XINT (s1
, 0) & XINT (s2
, 0));
2336 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2339 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2349 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2352 attr_alt_intersection (rtx s1
, rtx s2
)
2354 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2356 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2359 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2362 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2365 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2368 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2373 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2378 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2381 attr_alt_union (rtx s1
, rtx s2
)
2383 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2385 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2388 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2391 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2394 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2397 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2403 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2407 /* Return EQ_ATTR_ALT expression representing complement of S. */
2410 attr_alt_complement (rtx s
)
2412 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2414 XINT (result
, 0) = XINT (s
, 0);
2415 XINT (result
, 1) = 1 - XINT (s
, 1);
2420 /* Return EQ_ATTR_ALT expression representing set containing elements set
2426 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2428 XINT (result
, 0) = e
;
2429 XINT (result
, 1) = 0;
2434 /* Given an expression, see if it can be simplified for a particular insn
2435 code based on the values of other attributes being tested. This can
2436 eliminate nested get_attr_... calls.
2438 Note that if an endless recursion is specified in the patterns, the
2439 optimization will loop. However, it will do so in precisely the cases where
2440 an infinite recursion loop could occur during compilation. It's better that
2444 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2447 struct attr_desc
*attr
;
2448 struct attr_value
*av
;
2449 struct insn_ent
*ie
;
2452 bool left_alt
, right_alt
;
2454 /* Don't re-simplify something we already simplified. */
2455 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2458 switch (GET_CODE (exp
))
2461 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2462 if (left
== false_rtx
)
2464 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2465 if (right
== false_rtx
)
2468 if (GET_CODE (left
) == EQ_ATTR_ALT
2469 && GET_CODE (right
) == EQ_ATTR_ALT
)
2471 exp
= attr_alt_intersection (left
, right
);
2472 return simplify_test_exp (exp
, insn_code
, insn_index
);
2475 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2476 present on both sides, apply the distributive law since this will
2477 yield simplifications. */
2478 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2479 && compute_alternative_mask (left
, IOR
)
2480 && compute_alternative_mask (right
, IOR
))
2482 if (GET_CODE (left
) == IOR
)
2489 newexp
= attr_rtx (IOR
,
2490 attr_rtx (AND
, left
, XEXP (right
, 0)),
2491 attr_rtx (AND
, left
, XEXP (right
, 1)));
2493 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2496 /* Try with the term on both sides. */
2497 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2498 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2499 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2501 if (left
== false_rtx
|| right
== false_rtx
)
2503 else if (left
== true_rtx
)
2507 else if (right
== true_rtx
)
2511 /* See if all or all but one of the insn's alternatives are specified
2512 in this tree. Optimize if so. */
2514 if (GET_CODE (left
) == NOT
)
2515 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2516 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2518 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2521 if (GET_CODE (right
) == NOT
)
2522 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2523 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2525 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2526 && XINT (right
, 1));
2529 && (GET_CODE (left
) == AND
2531 || GET_CODE (right
) == AND
2534 i
= compute_alternative_mask (exp
, AND
);
2535 if (i
& ~insn_alternatives
[insn_code
])
2536 fatal ("invalid alternative specified for pattern number %d",
2539 /* If all alternatives are excluded, this is false. */
2540 i
^= insn_alternatives
[insn_code
];
2543 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2545 /* If just one excluded, AND a comparison with that one to the
2546 front of the tree. The others will be eliminated by
2547 optimization. We do not want to do this if the insn has one
2548 alternative and we have tested none of them! */
2549 left
= make_alternative_compare (i
);
2550 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2551 newexp
= attr_rtx (AND
, left
, right
);
2553 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2557 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2559 newexp
= attr_rtx (AND
, left
, right
);
2560 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2565 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2566 if (left
== true_rtx
)
2568 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2569 if (right
== true_rtx
)
2572 if (GET_CODE (left
) == EQ_ATTR_ALT
2573 && GET_CODE (right
) == EQ_ATTR_ALT
)
2575 exp
= attr_alt_union (left
, right
);
2576 return simplify_test_exp (exp
, insn_code
, insn_index
);
2579 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2580 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2581 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2583 if (right
== true_rtx
|| left
== true_rtx
)
2585 else if (left
== false_rtx
)
2589 else if (right
== false_rtx
)
2594 /* Test for simple cases where the distributive law is useful. I.e.,
2595 convert (ior (and (x) (y))
2601 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2602 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2604 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2606 left
= XEXP (left
, 0);
2608 newexp
= attr_rtx (AND
, left
, right
);
2609 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2612 /* See if all or all but one of the insn's alternatives are specified
2613 in this tree. Optimize if so. */
2615 else if (insn_code
>= 0
2616 && (GET_CODE (left
) == IOR
2617 || (GET_CODE (left
) == EQ_ATTR_ALT
2619 || (GET_CODE (left
) == EQ_ATTR
2620 && XSTR (left
, 0) == alternative_name
)
2621 || GET_CODE (right
) == IOR
2622 || (GET_CODE (right
) == EQ_ATTR_ALT
2623 && !XINT (right
, 1))
2624 || (GET_CODE (right
) == EQ_ATTR
2625 && XSTR (right
, 0) == alternative_name
)))
2627 i
= compute_alternative_mask (exp
, IOR
);
2628 if (i
& ~insn_alternatives
[insn_code
])
2629 fatal ("invalid alternative specified for pattern number %d",
2632 /* If all alternatives are included, this is true. */
2633 i
^= insn_alternatives
[insn_code
];
2636 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2638 /* If just one excluded, IOR a comparison with that one to the
2639 front of the tree. The others will be eliminated by
2640 optimization. We do not want to do this if the insn has one
2641 alternative and we have tested none of them! */
2642 left
= make_alternative_compare (i
);
2643 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2644 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2646 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2650 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2652 newexp
= attr_rtx (IOR
, left
, right
);
2653 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2658 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2660 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2661 insn_code
, insn_index
);
2665 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2666 if (GET_CODE (left
) == NOT
)
2667 return XEXP (left
, 0);
2669 if (left
== false_rtx
)
2671 if (left
== true_rtx
)
2674 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2676 exp
= attr_alt_complement (left
);
2677 return simplify_test_exp (exp
, insn_code
, insn_index
);
2680 /* Try to apply De`Morgan's laws. */
2681 if (GET_CODE (left
) == IOR
)
2683 newexp
= attr_rtx (AND
,
2684 attr_rtx (NOT
, XEXP (left
, 0)),
2685 attr_rtx (NOT
, XEXP (left
, 1)));
2687 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2689 else if (GET_CODE (left
) == AND
)
2691 newexp
= attr_rtx (IOR
,
2692 attr_rtx (NOT
, XEXP (left
, 0)),
2693 attr_rtx (NOT
, XEXP (left
, 1)));
2695 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2697 else if (left
!= XEXP (exp
, 0))
2699 newexp
= attr_rtx (NOT
, left
);
2705 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2709 if (XSTR (exp
, 0) == alternative_name
)
2711 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2715 /* Look at the value for this insn code in the specified attribute.
2716 We normally can replace this comparison with the condition that
2717 would give this insn the values being tested for. */
2719 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2720 for (av
= attr
->first_value
; av
; av
= av
->next
)
2721 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2722 if (ie
->def
->insn_code
== insn_code
)
2725 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2726 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2727 if (attr_rtx_cost(x
) < 20)
2736 /* We have already simplified this expression. Simplifying it again
2737 won't buy anything unless we weren't given a valid insn code
2738 to process (i.e., we are canonicalizing something.). */
2740 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2741 return copy_rtx_unchanging (newexp
);
2746 /* Optimize the attribute lists by seeing if we can determine conditional
2747 values from the known values of other attributes. This will save subroutine
2748 calls during the compilation. */
2751 optimize_attrs (void)
2753 struct attr_desc
*attr
;
2754 struct attr_value
*av
;
2755 struct insn_ent
*ie
;
2758 struct attr_value_list
2760 struct attr_value
*av
;
2761 struct insn_ent
*ie
;
2762 struct attr_desc
*attr
;
2763 struct attr_value_list
*next
;
2765 struct attr_value_list
**insn_code_values
;
2766 struct attr_value_list
*ivbuf
;
2767 struct attr_value_list
*iv
;
2769 /* For each insn code, make a list of all the insn_ent's for it,
2770 for all values for all attributes. */
2772 if (num_insn_ents
== 0)
2775 /* Make 2 extra elements, for "code" values -2 and -1. */
2776 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2778 /* Offset the table address so we can index by -2 or -1. */
2779 insn_code_values
+= 2;
2781 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2783 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2784 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2785 for (av
= attr
->first_value
; av
; av
= av
->next
)
2786 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2791 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2792 insn_code_values
[ie
->def
->insn_code
] = iv
;
2796 /* Sanity check on num_insn_ents. */
2797 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2799 /* Process one insn code at a time. */
2800 for (i
= -2; i
< insn_code_number
; i
++)
2802 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2803 We use it to mean "already simplified for this insn". */
2804 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2805 clear_struct_flag (iv
->av
->value
);
2807 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2809 struct obstack
*old
= rtl_obstack
;
2814 if (GET_CODE (av
->value
) != COND
)
2817 rtl_obstack
= temp_obstack
;
2819 while (GET_CODE (newexp
) == COND
)
2821 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2822 ie
->def
->insn_index
);
2823 if (newexp2
== newexp
)
2829 if (newexp
!= av
->value
)
2831 newexp
= attr_copy_rtx (newexp
);
2832 remove_insn_ent (av
, ie
);
2833 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2835 insert_insn_ent (av
, ie
);
2841 free (insn_code_values
- 2);
2844 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2847 clear_struct_flag (rtx x
)
2854 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2855 if (ATTR_IND_SIMPLIFIED_P (x
))
2858 code
= GET_CODE (x
);
2878 /* Compare the elements. If any pair of corresponding elements
2879 fail to match, return 0 for the whole things. */
2881 fmt
= GET_RTX_FORMAT (code
);
2882 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2888 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2889 clear_struct_flag (XVECEXP (x
, i
, j
));
2893 clear_struct_flag (XEXP (x
, i
));
2899 /* Create table entries for DEFINE_ATTR. */
2902 gen_attr (rtx exp
, int lineno
)
2904 struct attr_desc
*attr
;
2905 struct attr_value
*av
;
2906 const char *name_ptr
;
2909 /* Make a new attribute structure. Check for duplicate by looking at
2910 attr->default_val, since it is initialized by this routine. */
2911 attr
= find_attr (&XSTR (exp
, 0), 1);
2912 if (attr
->default_val
)
2914 message_with_line (lineno
, "duplicate definition for attribute %s",
2916 message_with_line (attr
->lineno
, "previous definition");
2920 attr
->lineno
= lineno
;
2922 if (*XSTR (exp
, 1) == '\0')
2923 attr
->is_numeric
= 1;
2926 name_ptr
= XSTR (exp
, 1);
2927 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
2929 av
= oballoc (sizeof (struct attr_value
));
2930 av
->value
= attr_rtx (CONST_STRING
, p
);
2931 av
->next
= attr
->first_value
;
2932 attr
->first_value
= av
;
2933 av
->first_insn
= NULL
;
2935 av
->has_asm_insn
= 0;
2939 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
2942 if (attr
->is_numeric
)
2944 message_with_line (lineno
,
2945 "constant attributes may not take numeric values");
2949 /* Get rid of the CONST node. It is allowed only at top-level. */
2950 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
2953 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
2955 message_with_line (lineno
,
2956 "`length' attribute must take numeric values");
2960 /* Set up the default value. */
2961 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
2962 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
2965 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2966 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2967 number of alternatives as this should be checked elsewhere. */
2970 count_alternatives (rtx exp
)
2975 if (GET_CODE (exp
) == MATCH_OPERAND
)
2976 return n_comma_elts (XSTR (exp
, 2));
2978 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
2979 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
2984 n
= count_alternatives (XEXP (exp
, i
));
2991 if (XVEC (exp
, i
) != NULL
)
2992 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
2994 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3003 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3004 `alternative' attribute. */
3007 compares_alternatives_p (rtx exp
)
3012 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3015 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3016 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3021 if (compares_alternatives_p (XEXP (exp
, i
)))
3026 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3027 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3035 /* Returns nonzero is INNER is contained in EXP. */
3038 contained_in_p (rtx inner
, rtx exp
)
3043 if (rtx_equal_p (inner
, exp
))
3046 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3047 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3052 if (contained_in_p (inner
, XEXP (exp
, i
)))
3057 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3058 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
3066 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3069 gen_insn (rtx exp
, int lineno
)
3071 struct insn_def
*id
;
3073 id
= oballoc (sizeof (struct insn_def
));
3077 id
->lineno
= lineno
;
3079 switch (GET_CODE (exp
))
3082 id
->insn_code
= insn_code_number
;
3083 id
->insn_index
= insn_index_number
;
3084 id
->num_alternatives
= count_alternatives (exp
);
3085 if (id
->num_alternatives
== 0)
3086 id
->num_alternatives
= 1;
3090 case DEFINE_PEEPHOLE
:
3091 id
->insn_code
= insn_code_number
;
3092 id
->insn_index
= insn_index_number
;
3093 id
->num_alternatives
= count_alternatives (exp
);
3094 if (id
->num_alternatives
== 0)
3095 id
->num_alternatives
= 1;
3099 case DEFINE_ASM_ATTRIBUTES
:
3101 id
->insn_index
= -1;
3102 id
->num_alternatives
= 1;
3104 got_define_asm_attributes
= 1;
3112 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3113 true or annul false is specified, and make a `struct delay_desc'. */
3116 gen_delay (rtx def
, int lineno
)
3118 struct delay_desc
*delay
;
3121 if (XVECLEN (def
, 1) % 3 != 0)
3123 message_with_line (lineno
,
3124 "number of elements in DEFINE_DELAY must be multiple of three");
3129 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3131 if (XVECEXP (def
, 1, i
+ 1))
3132 have_annul_true
= 1;
3133 if (XVECEXP (def
, 1, i
+ 2))
3134 have_annul_false
= 1;
3137 delay
= oballoc (sizeof (struct delay_desc
));
3139 delay
->num
= ++num_delays
;
3140 delay
->next
= delays
;
3141 delay
->lineno
= lineno
;
3145 /* Given a piece of RTX, print a C expression to test its truth value.
3146 We use AND and IOR both for logical and bit-wise operations, so
3147 interpret them as logical unless they are inside a comparison expression.
3148 The first bit of FLAGS will be nonzero in that case.
3150 Set the second bit of FLAGS to make references to attribute values use
3151 a cached local variable instead of calling a function. */
3154 write_test_expr (rtx exp
, int flags
)
3156 int comparison_operator
= 0;
3158 struct attr_desc
*attr
;
3160 /* In order not to worry about operator precedence, surround our part of
3161 the expression with parentheses. */
3164 code
= GET_CODE (exp
);
3167 /* Binary operators. */
3170 printf ("(unsigned) ");
3176 comparison_operator
= 1;
3178 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3179 case AND
: case IOR
: case XOR
:
3180 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3181 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3197 printf (" >= (unsigned) ");
3200 printf (" > (unsigned) ");
3209 printf (" <= (unsigned) ");
3212 printf (" < (unsigned) ");
3255 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3259 /* Special-case (not (eq_attrq "alternative" "x")) */
3260 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3261 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3263 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3267 /* Otherwise, fall through to normal unary operator. */
3269 /* Unary operators. */
3289 write_test_expr (XEXP (exp
, 0), flags
);
3294 int set
= XINT (exp
, 0), bit
= 0;
3297 fatal ("EQ_ATTR_ALT not valid inside comparison");
3300 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3302 if (!(set
& (set
- 1)))
3304 if (!(set
& 0xffff))
3327 printf ("which_alternative %s= %d",
3328 XINT (exp
, 1) ? "!" : "=", bit
);
3332 printf ("%s((1 << which_alternative) & 0x%x)",
3333 XINT (exp
, 1) ? "!" : "", set
);
3338 /* Comparison test of an attribute with a value. Most of these will
3339 have been removed by optimization. Handle "alternative"
3340 specially and give error if EQ_ATTR present inside a comparison. */
3343 fatal ("EQ_ATTR not valid inside comparison");
3345 if (XSTR (exp
, 0) == alternative_name
)
3347 printf ("which_alternative == %s", XSTR (exp
, 1));
3351 attr
= find_attr (&XSTR (exp
, 0), 0);
3354 /* Now is the time to expand the value of a constant attribute. */
3357 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3364 printf ("attr_%s", attr
->name
);
3366 printf ("get_attr_%s (insn)", attr
->name
);
3368 write_attr_valueq (attr
, XSTR (exp
, 1));
3372 /* Comparison test of flags for define_delays. */
3375 fatal ("ATTR_FLAG not valid inside comparison");
3376 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3379 /* See if an operand matches a predicate. */
3381 /* If only a mode is given, just ensure the mode matches the operand.
3382 If neither a mode nor predicate is given, error. */
3383 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3385 if (GET_MODE (exp
) == VOIDmode
)
3386 fatal ("null MATCH_OPERAND specified as test");
3388 printf ("GET_MODE (operands[%d]) == %smode",
3389 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3392 printf ("%s (operands[%d], %smode)",
3393 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3396 /* Constant integer. */
3398 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3401 /* A random C expression. */
3403 print_c_condition (XSTR (exp
, 0));
3406 /* The address of the branch target. */
3408 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3409 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3413 /* The address of the current insn. We implement this actually as the
3414 address of the current insn for backward branches, but the last
3415 address of the next insn for forward branches, and both with
3416 adjustments that account for the worst-case possible stretching of
3417 intervening alignments between this insn and its destination. */
3418 printf ("insn_current_reference_address (insn)");
3422 printf ("%s", XSTR (exp
, 0));
3426 write_test_expr (XEXP (exp
, 0), flags
& 2);
3428 write_test_expr (XEXP (exp
, 1), flags
| 1);
3430 write_test_expr (XEXP (exp
, 2), flags
| 1);
3434 fatal ("bad RTX code `%s' in attribute calculation\n",
3435 GET_RTX_NAME (code
));
3441 /* Given an attribute value, return the maximum CONST_STRING argument
3442 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3445 max_attr_value (rtx exp
, int *unknownp
)
3450 switch (GET_CODE (exp
))
3453 current_max
= atoi (XSTR (exp
, 0));
3457 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3458 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3460 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3461 if (n
> current_max
)
3467 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3468 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3469 if (n
> current_max
)
3475 current_max
= INT_MAX
;
3482 /* Given an attribute value, return the minimum CONST_STRING argument
3483 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3486 min_attr_value (rtx exp
, int *unknownp
)
3491 switch (GET_CODE (exp
))
3494 current_min
= atoi (XSTR (exp
, 0));
3498 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3499 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3501 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3502 if (n
< current_min
)
3508 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3509 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3510 if (n
< current_min
)
3516 current_min
= INT_MAX
;
3523 /* Given an attribute value, return the result of ORing together all
3524 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3525 if the numeric value is not known. */
3528 or_attr_value (rtx exp
, int *unknownp
)
3533 switch (GET_CODE (exp
))
3536 current_or
= atoi (XSTR (exp
, 0));
3540 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3541 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3542 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3546 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3547 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3559 /* Scan an attribute value, possibly a conditional, and record what actions
3560 will be required to do any conditional tests in it.
3563 `must_extract' if we need to extract the insn operands
3564 `must_constrain' if we must compute `which_alternative'
3565 `address_used' if an address expression was used
3566 `length_used' if an (eq_attr "length" ...) was used
3570 walk_attr_value (rtx exp
)
3579 code
= GET_CODE (exp
);
3583 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3584 /* Since this is an arbitrary expression, it can look at anything.
3585 However, constant expressions do not depend on any particular
3587 must_extract
= must_constrain
= 1;
3595 must_extract
= must_constrain
= 1;
3599 if (XSTR (exp
, 0) == alternative_name
)
3600 must_extract
= must_constrain
= 1;
3601 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3621 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3626 walk_attr_value (XEXP (exp
, i
));
3630 if (XVEC (exp
, i
) != NULL
)
3631 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3632 walk_attr_value (XVECEXP (exp
, i
, j
));
3637 /* Write out a function to obtain the attribute for a given INSN. */
3640 write_attr_get (struct attr_desc
*attr
)
3642 struct attr_value
*av
, *common_av
;
3644 /* Find the most used attribute value. Handle that as the `default' of the
3645 switch we will generate. */
3646 common_av
= find_most_used (attr
);
3648 /* Write out start of function, then all values with explicit `case' lines,
3649 then a `default', then the value with the most uses. */
3650 if (!attr
->is_numeric
)
3651 printf ("enum attr_%s\n", attr
->name
);
3655 /* If the attribute name starts with a star, the remainder is the name of
3656 the subroutine to use, instead of `get_attr_...'. */
3657 if (attr
->name
[0] == '*')
3658 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3659 else if (attr
->is_const
== 0)
3660 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3663 printf ("get_attr_%s (void)\n", attr
->name
);
3666 for (av
= attr
->first_value
; av
; av
= av
->next
)
3667 if (av
->num_insns
== 1)
3668 write_attr_set (attr
, 2, av
->value
, "return", ";",
3669 true_rtx
, av
->first_insn
->def
->insn_code
,
3670 av
->first_insn
->def
->insn_index
);
3671 else if (av
->num_insns
!= 0)
3672 write_attr_set (attr
, 2, av
->value
, "return", ";",
3680 printf (" switch (recog_memoized (insn))\n");
3683 for (av
= attr
->first_value
; av
; av
= av
->next
)
3684 if (av
!= common_av
)
3685 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3687 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3688 printf (" }\n}\n\n");
3691 /* Given an AND tree of known true terms (because we are inside an `if' with
3692 that as the condition or are in an `else' clause) and an expression,
3693 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3694 the bulk of the work. */
3697 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3701 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3703 if (GET_CODE (known_true
) == AND
)
3705 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3706 insn_code
, insn_index
);
3707 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3708 insn_code
, insn_index
);
3713 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3719 /* Write out a series of tests and assignment statements to perform tests and
3720 sets of an attribute value. We are passed an indentation amount and prefix
3721 and suffix strings to write around each attribute value (e.g., "return"
3725 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3726 const char *prefix
, const char *suffix
, rtx known_true
,
3727 int insn_code
, int insn_index
)
3729 if (GET_CODE (value
) == COND
)
3731 /* Assume the default value will be the default of the COND unless we
3732 find an always true expression. */
3733 rtx default_val
= XEXP (value
, 1);
3734 rtx our_known_true
= known_true
;
3739 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3744 testexp
= eliminate_known_true (our_known_true
,
3745 XVECEXP (value
, 0, i
),
3746 insn_code
, insn_index
);
3747 newexp
= attr_rtx (NOT
, testexp
);
3748 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3749 insn_code
, insn_index
);
3751 /* If the test expression is always true or if the next `known_true'
3752 expression is always false, this is the last case, so break
3753 out and let this value be the `else' case. */
3754 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3756 default_val
= XVECEXP (value
, 0, i
+ 1);
3760 /* Compute the expression to pass to our recursive call as being
3762 inner_true
= insert_right_side (AND
, our_known_true
,
3763 testexp
, insn_code
, insn_index
);
3765 /* If this is always false, skip it. */
3766 if (inner_true
== false_rtx
)
3769 write_indent (indent
);
3770 printf ("%sif ", first_if
? "" : "else ");
3772 write_test_expr (testexp
, 0);
3774 write_indent (indent
+ 2);
3777 write_attr_set (attr
, indent
+ 4,
3778 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3779 inner_true
, insn_code
, insn_index
);
3780 write_indent (indent
+ 2);
3782 our_known_true
= newexp
;
3787 write_indent (indent
);
3789 write_indent (indent
+ 2);
3793 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
3794 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
3798 write_indent (indent
+ 2);
3804 write_indent (indent
);
3805 printf ("%s ", prefix
);
3806 write_attr_value (attr
, value
);
3807 printf ("%s\n", suffix
);
3811 /* Write a series of case statements for every instruction in list IE.
3812 INDENT is the amount of indentation to write before each case. */
3815 write_insn_cases (struct insn_ent
*ie
, int indent
)
3817 for (; ie
!= 0; ie
= ie
->next
)
3818 if (ie
->def
->insn_code
!= -1)
3820 write_indent (indent
);
3821 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
3822 printf ("case %d: /* define_peephole, line %d */\n",
3823 ie
->def
->insn_code
, ie
->def
->lineno
);
3825 printf ("case %d: /* %s */\n",
3826 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
3830 /* Write out the computation for one attribute value. */
3833 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
3834 int write_case_lines
, const char *prefix
, const char *suffix
,
3835 int indent
, rtx known_true
)
3837 if (av
->num_insns
== 0)
3840 if (av
->has_asm_insn
)
3842 write_indent (indent
);
3843 printf ("case -1:\n");
3844 write_indent (indent
+ 2);
3845 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3846 write_indent (indent
+ 2);
3847 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3848 write_indent (indent
+ 2);
3849 printf (" fatal_insn_not_found (insn);\n");
3852 if (write_case_lines
)
3853 write_insn_cases (av
->first_insn
, indent
);
3856 write_indent (indent
);
3857 printf ("default:\n");
3860 /* See what we have to do to output this value. */
3861 must_extract
= must_constrain
= address_used
= 0;
3862 walk_attr_value (av
->value
);
3866 write_indent (indent
+ 2);
3867 printf ("extract_constrain_insn_cached (insn);\n");
3869 else if (must_extract
)
3871 write_indent (indent
+ 2);
3872 printf ("extract_insn_cached (insn);\n");
3875 if (av
->num_insns
== 1)
3876 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3877 known_true
, av
->first_insn
->def
->insn_code
,
3878 av
->first_insn
->def
->insn_index
);
3880 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3883 if (strncmp (prefix
, "return", 6))
3885 write_indent (indent
+ 2);
3886 printf ("break;\n");
3891 /* Search for uses of non-const attributes and write code to cache them. */
3894 write_expr_attr_cache (rtx p
, struct attr_desc
*attr
)
3899 if (GET_CODE (p
) == EQ_ATTR
)
3901 if (XSTR (p
, 0) != attr
->name
)
3904 if (!attr
->is_numeric
)
3905 printf (" enum attr_%s ", attr
->name
);
3909 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
3913 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
3914 ie
= GET_RTX_LENGTH (GET_CODE (p
));
3915 for (i
= 0; i
< ie
; i
++)
3920 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
3925 je
= XVECLEN (p
, i
);
3926 for (j
= 0; j
< je
; ++j
)
3927 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
3936 /* Utilities to write in various forms. */
3939 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
3941 if (attr
->is_numeric
)
3947 if (num
> 9 || num
< 0)
3948 printf (" /* 0x%x */", num
);
3952 write_upcase (attr
->name
);
3959 write_attr_value (struct attr_desc
*attr
, rtx value
)
3963 switch (GET_CODE (value
))
3966 write_attr_valueq (attr
, XSTR (value
, 0));
3970 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
3974 print_c_condition (XSTR (value
, 0));
3979 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
3980 printf ("get_attr_%s (%s)", attr2
->name
,
3981 (attr2
->is_const
? "" : "insn"));
4002 write_attr_value (attr
, XEXP (value
, 0));
4006 write_attr_value (attr
, XEXP (value
, 1));
4015 write_upcase (const char *str
)
4019 /* The argument of TOUPPER should not have side effects. */
4020 putchar (TOUPPER(*str
));
4026 write_indent (int indent
)
4028 for (; indent
> 8; indent
-= 8)
4031 for (; indent
; indent
--)
4035 /* Write a subroutine that is given an insn that requires a delay slot, a
4036 delay slot ordinal, and a candidate insn. It returns nonzero if the
4037 candidate can be placed in the specified delay slot of the insn.
4039 We can write as many as three subroutines. `eligible_for_delay'
4040 handles normal delay slots, `eligible_for_annul_true' indicates that
4041 the specified insn can be annulled if the branch is true, and likewise
4042 for `eligible_for_annul_false'.
4044 KIND is a string distinguishing these three cases ("delay", "annul_true",
4045 or "annul_false"). */
4048 write_eligible_delay (const char *kind
)
4050 struct delay_desc
*delay
;
4054 struct attr_desc
*attr
;
4055 struct attr_value
*av
, *common_av
;
4058 /* Compute the maximum number of delay slots required. We use the delay
4059 ordinal times this number plus one, plus the slot number as an index into
4060 the appropriate predicate to test. */
4062 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4063 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4064 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4066 /* Write function prelude. */
4069 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4072 printf (" rtx insn;\n");
4074 printf (" gcc_assert (slot < %d);\n", max_slots
);
4076 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4077 converts a compound instruction into a loop. */
4078 printf (" if (!INSN_P (candidate_insn))\n");
4079 printf (" return 0;\n");
4082 /* If more than one delay type, find out which type the delay insn is. */
4086 attr
= find_attr (&delay_type_str
, 0);
4088 common_av
= find_most_used (attr
);
4090 printf (" insn = delay_insn;\n");
4091 printf (" switch (recog_memoized (insn))\n");
4094 sprintf (str
, " * %d;\n break;", max_slots
);
4095 for (av
= attr
->first_value
; av
; av
= av
->next
)
4096 if (av
!= common_av
)
4097 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4099 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4102 /* Ensure matched. Otherwise, shouldn't have been called. */
4103 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4106 /* If just one type of delay slot, write simple switch. */
4107 if (num_delays
== 1 && max_slots
== 1)
4109 printf (" insn = candidate_insn;\n");
4110 printf (" switch (recog_memoized (insn))\n");
4113 attr
= find_attr (&delay_1_0_str
, 0);
4115 common_av
= find_most_used (attr
);
4117 for (av
= attr
->first_value
; av
; av
= av
->next
)
4118 if (av
!= common_av
)
4119 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4121 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4127 /* Write a nested CASE. The first indicates which condition we need to
4128 test, and the inner CASE tests the condition. */
4129 printf (" insn = candidate_insn;\n");
4130 printf (" switch (slot)\n");
4133 for (delay
= delays
; delay
; delay
= delay
->next
)
4134 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4136 printf (" case %d:\n",
4137 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4138 printf (" switch (recog_memoized (insn))\n");
4141 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4143 attr
= find_attr (&pstr
, 0);
4145 common_av
= find_most_used (attr
);
4147 for (av
= attr
->first_value
; av
; av
= av
->next
)
4148 if (av
!= common_av
)
4149 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4151 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4155 printf (" default:\n");
4156 printf (" gcc_unreachable ();\n");
4163 /* This page contains miscellaneous utility routines. */
4165 /* Given a pointer to a (char *), return a malloc'ed string containing the
4166 next comma-separated element. Advance the pointer to after the string
4167 scanned, or the end-of-string. Return NULL if at end of string. */
4170 next_comma_elt (const char **pstr
)
4174 start
= scan_comma_elt (pstr
);
4179 return attr_string (start
, *pstr
- start
);
4182 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4183 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4184 replaced by a pointer to a canonical copy of the string. */
4186 static struct attr_desc
*
4187 find_attr (const char **name_p
, int create
)
4189 struct attr_desc
*attr
;
4191 const char *name
= *name_p
;
4193 /* Before we resort to using `strcmp', see if the string address matches
4194 anywhere. In most cases, it should have been canonicalized to do so. */
4195 if (name
== alternative_name
)
4198 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4199 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4200 if (name
== attr
->name
)
4203 /* Otherwise, do it the slow way. */
4204 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4205 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4207 *name_p
= attr
->name
;
4214 attr
= oballoc (sizeof (struct attr_desc
));
4215 attr
->name
= DEF_ATTR_STRING (name
);
4216 attr
->first_value
= attr
->default_val
= NULL
;
4217 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4218 attr
->next
= attrs
[index
];
4219 attrs
[index
] = attr
;
4221 *name_p
= attr
->name
;
4226 /* Create internal attribute with the given default value. */
4229 make_internal_attr (const char *name
, rtx value
, int special
)
4231 struct attr_desc
*attr
;
4233 attr
= find_attr (&name
, 1);
4234 gcc_assert (!attr
->default_val
);
4236 attr
->is_numeric
= 1;
4238 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4239 attr
->default_val
= get_attr_value (value
, attr
, -2);
4242 /* Find the most used value of an attribute. */
4244 static struct attr_value
*
4245 find_most_used (struct attr_desc
*attr
)
4247 struct attr_value
*av
;
4248 struct attr_value
*most_used
;
4254 for (av
= attr
->first_value
; av
; av
= av
->next
)
4255 if (av
->num_insns
> nuses
)
4256 nuses
= av
->num_insns
, most_used
= av
;
4261 /* Return (attr_value "n") */
4264 make_numeric_value (int n
)
4266 static rtx int_values
[20];
4270 gcc_assert (n
>= 0);
4272 if (n
< 20 && int_values
[n
])
4273 return int_values
[n
];
4275 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4276 exp
= attr_rtx (CONST_STRING
, p
);
4279 int_values
[n
] = exp
;
4285 copy_rtx_unchanging (rtx orig
)
4287 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4290 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4294 /* Determine if an insn has a constant number of delay slots, i.e., the
4295 number of delay slots is not a function of the length of the insn. */
4298 write_const_num_delay_slots (void)
4300 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4301 struct attr_value
*av
;
4305 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4307 printf (" switch (recog_memoized (insn))\n");
4310 for (av
= attr
->first_value
; av
; av
= av
->next
)
4313 walk_attr_value (av
->value
);
4315 write_insn_cases (av
->first_insn
, 4);
4318 printf (" default:\n");
4319 printf (" return 1;\n");
4320 printf (" }\n}\n\n");
4324 /* Synthetic attributes used by insn-automata.c and the scheduler.
4325 These are primarily concerned with (define_insn_reservation)
4330 struct insn_reserv
*next
;
4333 int default_latency
;
4336 /* Sequence number of this insn. */
4339 /* Whether a (define_bypass) construct names this insn in its
4344 static struct insn_reserv
*all_insn_reservs
= 0;
4345 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4346 static size_t n_insn_reservs
;
4348 /* Store information from a DEFINE_INSN_RESERVATION for future
4349 attribute generation. */
4351 gen_insn_reserv (rtx def
)
4353 struct insn_reserv
*decl
= oballoc (sizeof (struct insn_reserv
));
4355 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4356 decl
->default_latency
= XINT (def
, 1);
4357 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4358 decl
->insn_num
= n_insn_reservs
;
4359 decl
->bypassed
= false;
4362 *last_insn_reserv_p
= decl
;
4363 last_insn_reserv_p
= &decl
->next
;
4367 /* Store information from a DEFINE_BYPASS for future attribute
4368 generation. The only thing we care about is the list of output
4369 insns, which will later be used to tag reservation structures with
4370 a 'bypassed' bit. */
4374 struct bypass_list
*next
;
4378 static struct bypass_list
*all_bypasses
;
4379 static size_t n_bypasses
;
4382 gen_bypass_1 (const char *s
, size_t len
)
4384 struct bypass_list
*b
;
4389 s
= attr_string (s
, len
);
4390 for (b
= all_bypasses
; b
; b
= b
->next
)
4392 return; /* already got that one */
4394 b
= oballoc (sizeof (struct bypass_list
));
4396 b
->next
= all_bypasses
;
4402 gen_bypass (rtx def
)
4404 const char *p
, *base
;
4406 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4409 gen_bypass_1 (base
, p
- base
);
4412 while (ISSPACE (*p
));
4415 gen_bypass_1 (base
, p
- base
);
4418 /* Find and mark all of the bypassed insns. */
4420 process_bypasses (void)
4422 struct bypass_list
*b
;
4423 struct insn_reserv
*r
;
4425 /* The reservation list is likely to be much longer than the bypass
4427 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4428 for (b
= all_bypasses
; b
; b
= b
->next
)
4429 if (r
->name
== b
->insn
)
4433 /* Create all of the attributes that describe automaton properties. */
4435 make_automaton_attrs (void)
4438 struct insn_reserv
*decl
;
4439 rtx code_exp
, lats_exp
, byps_exp
;
4441 if (n_insn_reservs
== 0)
4444 code_exp
= rtx_alloc (COND
);
4445 lats_exp
= rtx_alloc (COND
);
4447 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4448 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4450 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4451 XEXP (lats_exp
, 1) = make_numeric_value (0);
4453 for (decl
= all_insn_reservs
, i
= 0;
4455 decl
= decl
->next
, i
+= 2)
4457 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
4458 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
4460 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
4461 XVECEXP (lats_exp
, 0, i
+1) = make_numeric_value (decl
->default_latency
);
4464 if (n_bypasses
== 0)
4465 byps_exp
= make_numeric_value (0);
4468 process_bypasses ();
4470 byps_exp
= rtx_alloc (COND
);
4471 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypasses
* 2);
4472 XEXP (byps_exp
, 1) = make_numeric_value (0);
4473 for (decl
= all_insn_reservs
, i
= 0;
4478 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
4479 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
4484 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
4485 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
4486 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
4490 main (int argc
, char **argv
)
4493 struct attr_desc
*attr
;
4494 struct insn_def
*id
;
4498 progname
= "genattrtab";
4500 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
4501 return (FATAL_EXIT_CODE
);
4503 obstack_init (hash_obstack
);
4504 obstack_init (temp_obstack
);
4506 /* Set up true and false rtx's */
4507 true_rtx
= rtx_alloc (CONST_INT
);
4508 XWINT (true_rtx
, 0) = 1;
4509 false_rtx
= rtx_alloc (CONST_INT
);
4510 XWINT (false_rtx
, 0) = 0;
4511 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4512 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4514 alternative_name
= DEF_ATTR_STRING ("alternative");
4515 length_str
= DEF_ATTR_STRING ("length");
4516 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4517 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4518 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4520 printf ("/* Generated automatically by the program `genattrtab'\n\
4521 from the machine description file `md'. */\n\n");
4523 /* Read the machine description. */
4529 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4533 switch (GET_CODE (desc
))
4536 case DEFINE_PEEPHOLE
:
4537 case DEFINE_ASM_ATTRIBUTES
:
4538 gen_insn (desc
, lineno
);
4542 gen_attr (desc
, lineno
);
4546 gen_delay (desc
, lineno
);
4549 case DEFINE_INSN_RESERVATION
:
4550 gen_insn_reserv (desc
);
4560 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4561 insn_index_number
++;
4565 return FATAL_EXIT_CODE
;
4569 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4570 if (! got_define_asm_attributes
)
4572 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4573 XVEC (tem
, 0) = rtvec_alloc (0);
4577 /* Expand DEFINE_DELAY information into new attribute. */
4581 printf ("#include \"config.h\"\n");
4582 printf ("#include \"system.h\"\n");
4583 printf ("#include \"coretypes.h\"\n");
4584 printf ("#include \"tm.h\"\n");
4585 printf ("#include \"rtl.h\"\n");
4586 printf ("#include \"tm_p.h\"\n");
4587 printf ("#include \"insn-config.h\"\n");
4588 printf ("#include \"recog.h\"\n");
4589 printf ("#include \"regs.h\"\n");
4590 printf ("#include \"real.h\"\n");
4591 printf ("#include \"output.h\"\n");
4592 printf ("#include \"insn-attr.h\"\n");
4593 printf ("#include \"toplev.h\"\n");
4594 printf ("#include \"flags.h\"\n");
4595 printf ("#include \"function.h\"\n");
4597 printf ("#define operands recog_data.operand\n\n");
4599 /* Make `insn_alternatives'. */
4600 insn_alternatives
= oballoc (insn_code_number
* sizeof (int));
4601 for (id
= defs
; id
; id
= id
->next
)
4602 if (id
->insn_code
>= 0)
4603 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4605 /* Make `insn_n_alternatives'. */
4606 insn_n_alternatives
= oballoc (insn_code_number
* sizeof (int));
4607 for (id
= defs
; id
; id
= id
->next
)
4608 if (id
->insn_code
>= 0)
4609 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4611 /* Construct extra attributes for automata. */
4612 make_automaton_attrs ();
4614 /* Prepare to write out attribute subroutines by checking everything stored
4615 away and building the attribute cases. */
4619 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4620 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4621 attr
->default_val
->value
4622 = check_attr_value (attr
->default_val
->value
, attr
);
4625 return FATAL_EXIT_CODE
;
4627 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4628 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4631 /* Construct extra attributes for `length'. */
4632 make_length_attrs ();
4634 /* Perform any possible optimizations to speed up compilation. */
4637 /* Now write out all the `gen_attr_...' routines. Do these before the
4638 special routines so that they get defined before they are used. */
4640 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4641 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4643 if (! attr
->is_special
&& ! attr
->is_const
)
4644 write_attr_get (attr
);
4647 /* Write out delay eligibility information, if DEFINE_DELAY present.
4648 (The function to compute the number of delay slots will be written
4652 write_eligible_delay ("delay");
4653 if (have_annul_true
)
4654 write_eligible_delay ("annul_true");
4655 if (have_annul_false
)
4656 write_eligible_delay ("annul_false");
4659 /* Write out constant delay slot info. */
4660 write_const_num_delay_slots ();
4662 write_length_unit_log ();
4665 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);