1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
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"
115 #include "gensupport.h"
118 /* Flags for make_internal_attr's `special' parameter. */
120 #define ATTR_SPECIAL (1 << 0)
122 static struct obstack obstack1
, obstack2
;
123 static struct obstack
*hash_obstack
= &obstack1
;
124 static struct obstack
*temp_obstack
= &obstack2
;
126 /* enough space to reserve for printing out ints */
127 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
129 /* Define structures used to record attributes and values. */
131 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
132 encountered, we store all the relevant information into a
133 `struct insn_def'. This is done to allow attribute definitions to occur
134 anywhere in the file. */
138 struct insn_def
*next
; /* Next insn in chain. */
139 rtx def
; /* The DEFINE_... */
140 int insn_code
; /* Instruction number. */
141 int insn_index
; /* Expression number in file, for errors. */
142 int lineno
; /* Line number. */
143 int num_alternatives
; /* Number of alternatives. */
144 int vec_idx
; /* Index of attribute vector in `def'. */
147 /* Once everything has been read in, we store in each attribute value a list
148 of insn codes that have that value. Here is the structure used for the
153 struct insn_ent
*next
; /* Next in chain. */
154 struct insn_def
*def
; /* Instruction definition. */
157 /* Each value of an attribute (either constant or computed) is assigned a
158 structure which is used as the listhead of the insns that have that
163 rtx value
; /* Value of attribute. */
164 struct attr_value
*next
; /* Next attribute value in chain. */
165 struct insn_ent
*first_insn
; /* First insn with this value. */
166 int num_insns
; /* Number of insns with this value. */
167 int has_asm_insn
; /* True if this value used for `asm' insns */
170 /* Structure for each attribute. */
174 char *name
; /* Name of attribute. */
175 const char *enum_name
; /* Enum name for DEFINE_ENUM_NAME. */
176 struct attr_desc
*next
; /* Next attribute. */
177 struct attr_value
*first_value
; /* First value of this attribute. */
178 struct attr_value
*default_val
; /* Default value for this attribute. */
179 int lineno
: 24; /* Line number. */
180 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
181 unsigned is_const
: 1; /* Attribute value constant for each run. */
182 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
185 /* Structure for each DEFINE_DELAY. */
189 rtx def
; /* DEFINE_DELAY expression. */
190 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
191 int num
; /* Number of DEFINE_DELAY, starting at 1. */
192 int lineno
; /* Line number. */
195 struct attr_value_list
197 struct attr_value
*av
;
199 struct attr_desc
*attr
;
200 struct attr_value_list
*next
;
203 /* Listheads of above structures. */
205 /* This one is indexed by the first character of the attribute name. */
206 #define MAX_ATTRS_INDEX 256
207 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
208 static struct insn_def
*defs
;
209 static struct delay_desc
*delays
;
210 struct attr_value_list
**insn_code_values
;
212 /* Other variables. */
214 static int insn_code_number
;
215 static int insn_index_number
;
216 static int got_define_asm_attributes
;
217 static int must_extract
;
218 static int must_constrain
;
219 static int address_used
;
220 static int length_used
;
221 static int num_delays
;
222 static int have_annul_true
, have_annul_false
;
223 static int num_insn_ents
;
225 /* Stores, for each insn code, the number of constraint alternatives. */
227 static int *insn_n_alternatives
;
229 /* Stores, for each insn code, a bitmap that has bits on for each possible
232 static int *insn_alternatives
;
234 /* Used to simplify expressions. */
236 static rtx true_rtx
, false_rtx
;
238 /* Used to reduce calls to `strcmp' */
240 static const char *alternative_name
;
241 static const char *length_str
;
242 static const char *delay_type_str
;
243 static const char *delay_1_0_str
;
244 static const char *num_delay_slots_str
;
246 /* Simplify an expression. Only call the routine if there is something to
248 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
249 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
250 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
252 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
254 /* Forward declarations of functions used before their definitions, only. */
255 static char *attr_string (const char *, int);
256 static char *attr_printf (unsigned int, const char *, ...)
258 static rtx
make_numeric_value (int);
259 static struct attr_desc
*find_attr (const char **, int);
260 static rtx
mk_attr_alt (int);
261 static char *next_comma_elt (const char **);
262 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
263 static rtx
copy_boolean (rtx
);
264 static int compares_alternatives_p (rtx
);
265 static void make_internal_attr (const char *, rtx
, int);
266 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
267 static void walk_attr_value (rtx
);
268 static int max_attr_value (rtx
, int*);
269 static int min_attr_value (rtx
, int*);
270 static int or_attr_value (rtx
, int*);
271 static rtx
simplify_test_exp (rtx
, int, int);
272 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
273 static rtx
copy_rtx_unchanging (rtx
);
274 static bool attr_alt_subset_p (rtx
, rtx
);
275 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
276 static void clear_struct_flag (rtx
);
277 static void write_attr_valueq (struct attr_desc
*, const char *);
278 static struct attr_value
*find_most_used (struct attr_desc
*);
279 static void write_attr_set (struct attr_desc
*, int, rtx
,
280 const char *, const char *, rtx
,
281 int, int, unsigned int);
282 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
283 int, const char *, const char *, int, rtx
);
284 static void write_attr_value (struct attr_desc
*, rtx
);
285 static void write_upcase (const char *);
286 static void write_indent (int);
287 static rtx
identity_fn (rtx
);
288 static rtx
zero_fn (rtx
);
289 static rtx
one_fn (rtx
);
290 static rtx
max_fn (rtx
);
291 static rtx
min_fn (rtx
);
293 #define oballoc(T) XOBNEW (hash_obstack, T)
294 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
296 /* Hash table for sharing RTL and strings. */
298 /* Each hash table slot is a bucket containing a chain of these structures.
299 Strings are given negative hash codes; RTL expressions are given positive
304 struct attr_hash
*next
; /* Next structure in the bucket. */
305 int hashcode
; /* Hash code of this rtx or string. */
308 char *str
; /* The string (negative hash codes) */
309 rtx rtl
; /* or the RTL recorded here. */
313 /* Now here is the hash table. When recording an RTL, it is added to
314 the slot whose index is the hash code mod the table size. Note
315 that the hash table is used for several kinds of RTL (see attr_rtx)
316 and for strings. While all these live in the same table, they are
317 completely independent, and the hash code is computed differently
320 #define RTL_HASH_SIZE 4093
321 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
323 /* Here is how primitive or already-shared RTL's hash
325 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
327 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
330 attr_hash_add_rtx (int hashcode
, rtx rtl
)
334 h
= XOBNEW (hash_obstack
, struct attr_hash
);
335 h
->hashcode
= hashcode
;
337 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
338 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
341 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
344 attr_hash_add_string (int hashcode
, char *str
)
348 h
= XOBNEW (hash_obstack
, struct attr_hash
);
349 h
->hashcode
= -hashcode
;
351 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
352 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
355 /* Generate an RTL expression, but avoid duplicates.
356 Set the ATTR_PERMANENT_P flag for these permanent objects.
358 In some cases we cannot uniquify; then we return an ordinary
359 impermanent rtx with ATTR_PERMANENT_P clear.
363 rtx attr_rtx (code, [element1, ..., elementn]) */
366 attr_rtx_1 (enum rtx_code code
, va_list p
)
368 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
371 struct obstack
*old_obstack
= rtl_obstack
;
373 /* For each of several cases, search the hash table for an existing entry.
374 Use that entry if one is found; otherwise create a new RTL and add it
377 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
379 rtx arg0
= va_arg (p
, rtx
);
381 /* A permanent object cannot point to impermanent ones. */
382 if (! ATTR_PERMANENT_P (arg0
))
384 rt_val
= rtx_alloc (code
);
385 XEXP (rt_val
, 0) = arg0
;
389 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
390 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
391 if (h
->hashcode
== hashcode
392 && GET_CODE (h
->u
.rtl
) == code
393 && XEXP (h
->u
.rtl
, 0) == arg0
)
398 rtl_obstack
= hash_obstack
;
399 rt_val
= rtx_alloc (code
);
400 XEXP (rt_val
, 0) = arg0
;
403 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
404 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
405 || GET_RTX_CLASS (code
) == RTX_COMPARE
406 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
408 rtx arg0
= va_arg (p
, rtx
);
409 rtx arg1
= va_arg (p
, rtx
);
411 /* A permanent object cannot point to impermanent ones. */
412 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
414 rt_val
= rtx_alloc (code
);
415 XEXP (rt_val
, 0) = arg0
;
416 XEXP (rt_val
, 1) = arg1
;
420 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
421 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
422 if (h
->hashcode
== hashcode
423 && GET_CODE (h
->u
.rtl
) == code
424 && XEXP (h
->u
.rtl
, 0) == arg0
425 && XEXP (h
->u
.rtl
, 1) == arg1
)
430 rtl_obstack
= hash_obstack
;
431 rt_val
= rtx_alloc (code
);
432 XEXP (rt_val
, 0) = arg0
;
433 XEXP (rt_val
, 1) = arg1
;
436 else if (GET_RTX_LENGTH (code
) == 1
437 && GET_RTX_FORMAT (code
)[0] == 's')
439 char *arg0
= va_arg (p
, char *);
441 arg0
= DEF_ATTR_STRING (arg0
);
443 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
444 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
445 if (h
->hashcode
== hashcode
446 && GET_CODE (h
->u
.rtl
) == code
447 && XSTR (h
->u
.rtl
, 0) == arg0
)
452 rtl_obstack
= hash_obstack
;
453 rt_val
= rtx_alloc (code
);
454 XSTR (rt_val
, 0) = arg0
;
457 else if (GET_RTX_LENGTH (code
) == 2
458 && GET_RTX_FORMAT (code
)[0] == 's'
459 && GET_RTX_FORMAT (code
)[1] == 's')
461 char *arg0
= va_arg (p
, char *);
462 char *arg1
= va_arg (p
, char *);
464 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
465 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
466 if (h
->hashcode
== hashcode
467 && GET_CODE (h
->u
.rtl
) == code
468 && XSTR (h
->u
.rtl
, 0) == arg0
469 && XSTR (h
->u
.rtl
, 1) == arg1
)
474 rtl_obstack
= hash_obstack
;
475 rt_val
= rtx_alloc (code
);
476 XSTR (rt_val
, 0) = arg0
;
477 XSTR (rt_val
, 1) = arg1
;
480 else if (code
== CONST_INT
)
482 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
492 int i
; /* Array indices... */
493 const char *fmt
; /* Current rtx's format... */
495 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
497 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
498 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
502 case '0': /* Unused field. */
505 case 'i': /* An integer? */
506 XINT (rt_val
, i
) = va_arg (p
, int);
509 case 'w': /* A wide integer? */
510 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
513 case 's': /* A string? */
514 XSTR (rt_val
, i
) = va_arg (p
, char *);
517 case 'e': /* An expression? */
518 case 'u': /* An insn? Same except when printing. */
519 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
522 case 'E': /* An RTX vector? */
523 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
533 rtl_obstack
= old_obstack
;
534 attr_hash_add_rtx (hashcode
, rt_val
);
535 ATTR_PERMANENT_P (rt_val
) = 1;
540 attr_rtx (enum rtx_code code
, ...)
546 result
= attr_rtx_1 (code
, p
);
551 /* Create a new string printed with the printf line arguments into a space
552 of at most LEN bytes:
554 rtx attr_printf (len, format, [arg1, ..., argn]) */
557 attr_printf (unsigned int len
, const char *fmt
, ...)
564 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
566 vsprintf (str
, fmt
, p
);
569 return DEF_ATTR_STRING (str
);
573 attr_eq (const char *name
, const char *value
)
575 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
581 return XSTR (make_numeric_value (n
), 0);
584 /* Return a permanent (possibly shared) copy of a string STR (not assumed
585 to be null terminated) with LEN bytes. */
588 attr_string (const char *str
, int len
)
595 /* Compute the hash code. */
596 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
597 for (i
= 1; i
< len
; i
+= 2)
598 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
600 hashcode
= -hashcode
;
602 /* Search the table for the string. */
603 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
604 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
605 && !strncmp (h
->u
.str
, str
, len
))
606 return h
->u
.str
; /* <-- return if found. */
608 /* Not found; create a permanent copy and add it to the hash table. */
609 new_str
= XOBNEWVAR (hash_obstack
, char, len
+ 1);
610 memcpy (new_str
, str
, len
);
612 attr_hash_add_string (hashcode
, new_str
);
614 return new_str
; /* Return the new string. */
617 /* Check two rtx's for equality of contents,
618 taking advantage of the fact that if both are hashed
619 then they can't be equal unless they are the same object. */
622 attr_equal_p (rtx x
, rtx y
)
624 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
625 && rtx_equal_p (x
, y
)));
628 /* Copy an attribute value expression,
629 descending to all depths, but not copying any
630 permanent hashed subexpressions. */
633 attr_copy_rtx (rtx orig
)
638 const char *format_ptr
;
640 /* No need to copy a permanent object. */
641 if (ATTR_PERMANENT_P (orig
))
644 code
= GET_CODE (orig
);
662 copy
= rtx_alloc (code
);
663 PUT_MODE (copy
, GET_MODE (orig
));
664 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
665 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
666 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
668 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
670 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
672 switch (*format_ptr
++)
675 XEXP (copy
, i
) = XEXP (orig
, i
);
676 if (XEXP (orig
, i
) != NULL
)
677 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
682 XVEC (copy
, i
) = XVEC (orig
, i
);
683 if (XVEC (orig
, i
) != NULL
)
685 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
686 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
687 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
693 XINT (copy
, i
) = XINT (orig
, i
);
697 XWINT (copy
, i
) = XWINT (orig
, i
);
702 XSTR (copy
, i
) = XSTR (orig
, i
);
712 /* Given a test expression for an attribute, ensure it is validly formed.
713 IS_CONST indicates whether the expression is constant for each compiler
714 run (a constant expression may not test any particular insn).
716 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
717 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
718 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
720 Update the string address in EQ_ATTR expression to be the same used
721 in the attribute (or `alternative_name') to speed up subsequent
722 `find_attr' calls and eliminate most `strcmp' calls.
724 Return the new expression, if any. */
727 check_attr_test (rtx exp
, int is_const
, int lineno
)
729 struct attr_desc
*attr
;
730 struct attr_value
*av
;
731 const char *name_ptr
, *p
;
734 switch (GET_CODE (exp
))
737 /* Handle negation test. */
738 if (XSTR (exp
, 1)[0] == '!')
739 return check_attr_test (attr_rtx (NOT
,
740 attr_eq (XSTR (exp
, 0),
744 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
746 attr
= find_attr (&XSTR (exp
, 0), 0);
749 if (! strcmp (XSTR (exp
, 0), "alternative"))
750 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
752 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
755 if (is_const
&& ! attr
->is_const
)
756 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
759 /* Copy this just to make it permanent,
760 so expressions using it can be permanent too. */
761 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
763 /* It shouldn't be possible to simplify the value given to a
764 constant attribute, so don't expand this until it's time to
765 write the test expression. */
767 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
769 if (attr
->is_numeric
)
771 for (p
= XSTR (exp
, 1); *p
; p
++)
773 fatal ("attribute `%s' takes only numeric values",
778 for (av
= attr
->first_value
; av
; av
= av
->next
)
779 if (GET_CODE (av
->value
) == CONST_STRING
780 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
784 fatal ("unknown value `%s' for `%s' attribute",
785 XSTR (exp
, 1), XSTR (exp
, 0));
790 if (! strcmp (XSTR (exp
, 0), "alternative"))
794 name_ptr
= XSTR (exp
, 1);
795 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
796 set
|= 1 << atoi (p
);
798 return mk_attr_alt (set
);
802 /* Make an IOR tree of the possible values. */
804 name_ptr
= XSTR (exp
, 1);
805 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
807 newexp
= attr_eq (XSTR (exp
, 0), p
);
808 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
811 return check_attr_test (orexp
, is_const
, lineno
);
820 /* Either TRUE or FALSE. */
828 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
829 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
833 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
838 fatal ("RTL operator \"%s\" not valid in constant attribute test",
839 GET_RTX_NAME (GET_CODE (exp
)));
840 /* These cases can't be simplified. */
841 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
844 case LE
: case LT
: case GT
: case GE
:
845 case LEU
: case LTU
: case GTU
: case GEU
:
847 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
848 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
849 exp
= attr_rtx (GET_CODE (exp
),
850 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
851 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
852 /* These cases can't be simplified. */
853 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
859 /* These cases are valid for constant attributes, but can't be
861 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
862 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
866 fatal ("RTL operator \"%s\" not valid in attribute test",
867 GET_RTX_NAME (GET_CODE (exp
)));
873 /* Given an expression, ensure that it is validly formed and that all named
874 attribute values are valid for the given attribute. Issue a fatal error
875 if not. If no attribute is specified, assume a numeric attribute.
877 Return a perhaps modified replacement expression for the value. */
880 check_attr_value (rtx exp
, struct attr_desc
*attr
)
882 struct attr_value
*av
;
886 switch (GET_CODE (exp
))
889 if (attr
&& ! attr
->is_numeric
)
891 error_with_line (attr
->lineno
,
892 "CONST_INT not valid for non-numeric attribute %s",
897 if (INTVAL (exp
) < 0)
899 error_with_line (attr
->lineno
,
900 "negative numeric value specified for attribute %s",
907 if (! strcmp (XSTR (exp
, 0), "*"))
910 if (attr
== 0 || attr
->is_numeric
)
916 error_with_line (attr
? attr
->lineno
: 0,
917 "non-numeric value for numeric attribute %s",
918 attr
? attr
->name
: "internal");
924 for (av
= attr
->first_value
; av
; av
= av
->next
)
925 if (GET_CODE (av
->value
) == CONST_STRING
926 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
930 error_with_line (attr
->lineno
,
931 "unknown value `%s' for `%s' attribute",
932 XSTR (exp
, 0), attr
? attr
->name
: "internal");
936 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
937 attr
? attr
->is_const
: 0,
938 attr
? attr
->lineno
: 0);
939 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
940 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
948 if (attr
&& !attr
->is_numeric
)
950 error_with_line (attr
->lineno
,
951 "invalid operation `%s' for non-numeric"
952 " attribute value", GET_RTX_NAME (GET_CODE (exp
)));
959 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
960 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
969 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
973 if (XVECLEN (exp
, 0) % 2 != 0)
975 error_with_line (attr
->lineno
,
976 "first operand of COND must have even length");
980 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
982 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
983 attr
? attr
->is_const
: 0,
984 attr
? attr
->lineno
: 0);
985 XVECEXP (exp
, 0, i
+ 1)
986 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
989 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
994 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
996 error_with_line (attr
? attr
->lineno
: 0,
997 "unknown attribute `%s' in ATTR",
999 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1000 error_with_line (attr
->lineno
,
1001 "non-constant attribute `%s' referenced from `%s'",
1002 XSTR (exp
, 0), attr
->name
);
1004 && attr
->is_numeric
!= attr2
->is_numeric
)
1005 error_with_line (attr
->lineno
,
1006 "numeric attribute mismatch calling `%s' from `%s'",
1007 XSTR (exp
, 0), attr
->name
);
1012 /* A constant SYMBOL_REF is valid as a constant attribute test and
1013 is expanded later by make_canonical into a COND. In a non-constant
1014 attribute test, it is left be. */
1015 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1018 error_with_line (attr
? attr
->lineno
: 0,
1019 "invalid operation `%s' for attribute value",
1020 GET_RTX_NAME (GET_CODE (exp
)));
1027 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1028 It becomes a COND with each test being (eq_attr "alternative" "n") */
1031 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1033 int num_alt
= id
->num_alternatives
;
1037 if (XVECLEN (exp
, 1) != num_alt
)
1039 error_with_line (id
->lineno
,
1040 "bad number of entries in SET_ATTR_ALTERNATIVE");
1044 /* Make a COND with all tests but the last. Select the last value via the
1046 condexp
= rtx_alloc (COND
);
1047 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1049 for (i
= 0; i
< num_alt
- 1; i
++)
1052 p
= attr_numeral (i
);
1054 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1055 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1058 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1060 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1063 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1064 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1067 convert_set_attr (rtx exp
, struct insn_def
*id
)
1070 const char *name_ptr
;
1074 /* See how many alternative specified. */
1075 n
= n_comma_elts (XSTR (exp
, 1));
1077 return attr_rtx (SET
,
1078 attr_rtx (ATTR
, XSTR (exp
, 0)),
1079 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1081 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1082 XSTR (newexp
, 0) = XSTR (exp
, 0);
1083 XVEC (newexp
, 1) = rtvec_alloc (n
);
1085 /* Process each comma-separated name. */
1086 name_ptr
= XSTR (exp
, 1);
1088 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1089 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1091 return convert_set_attr_alternative (newexp
, id
);
1094 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1095 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1101 struct insn_def
*id
;
1102 struct attr_desc
*attr
;
1106 for (id
= defs
; id
; id
= id
->next
)
1108 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1111 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1113 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1114 switch (GET_CODE (value
))
1117 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1119 error_with_line (id
->lineno
, "bad attribute set");
1124 case SET_ATTR_ALTERNATIVE
:
1125 value
= convert_set_attr_alternative (value
, id
);
1129 value
= convert_set_attr (value
, id
);
1133 error_with_line (id
->lineno
, "invalid attribute code %s",
1134 GET_RTX_NAME (GET_CODE (value
)));
1137 if (value
== NULL_RTX
)
1140 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1142 error_with_line (id
->lineno
, "unknown attribute %s",
1143 XSTR (XEXP (value
, 0), 0));
1147 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1148 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1153 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1154 expressions by converting them into a COND. This removes cases from this
1155 program. Also, replace an attribute value of "*" with the default attribute
1159 make_canonical (struct attr_desc
*attr
, rtx exp
)
1164 switch (GET_CODE (exp
))
1167 exp
= make_numeric_value (INTVAL (exp
));
1171 if (! strcmp (XSTR (exp
, 0), "*"))
1173 if (attr
== 0 || attr
->default_val
== 0)
1174 fatal ("(attr_value \"*\") used in invalid context");
1175 exp
= attr
->default_val
->value
;
1178 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1183 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1185 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1186 This makes the COND something that won't be considered an arbitrary
1187 expression by walk_attr_value. */
1188 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1189 exp
= check_attr_value (exp
, attr
);
1193 newexp
= rtx_alloc (COND
);
1194 XVEC (newexp
, 0) = rtvec_alloc (2);
1195 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1196 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1198 XEXP (newexp
, 1) = XEXP (exp
, 2);
1201 /* Fall through to COND case since this is now a COND. */
1208 /* First, check for degenerate COND. */
1209 if (XVECLEN (exp
, 0) == 0)
1210 return make_canonical (attr
, XEXP (exp
, 1));
1211 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1213 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1215 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1216 XVECEXP (exp
, 0, i
+ 1)
1217 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1218 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1234 copy_boolean (rtx exp
)
1236 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1237 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1238 copy_boolean (XEXP (exp
, 1)));
1239 if (GET_CODE (exp
) == MATCH_OPERAND
)
1241 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1242 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1244 else if (GET_CODE (exp
) == EQ_ATTR
)
1246 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1247 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1253 /* Given a value and an attribute description, return a `struct attr_value *'
1254 that represents that value. This is either an existing structure, if the
1255 value has been previously encountered, or a newly-created structure.
1257 `insn_code' is the code of an insn whose attribute has the specified
1258 value (-2 if not processing an insn). We ensure that all insns for
1259 a given value have the same number of alternatives if the value checks
1262 static struct attr_value
*
1263 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1265 struct attr_value
*av
;
1268 value
= make_canonical (attr
, value
);
1269 if (compares_alternatives_p (value
))
1271 if (insn_code
< 0 || insn_alternatives
== NULL
)
1272 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1274 num_alt
= insn_alternatives
[insn_code
];
1277 for (av
= attr
->first_value
; av
; av
= av
->next
)
1278 if (rtx_equal_p (value
, av
->value
)
1279 && (num_alt
== 0 || av
->first_insn
== NULL
1280 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1283 av
= oballoc (struct attr_value
);
1285 av
->next
= attr
->first_value
;
1286 attr
->first_value
= av
;
1287 av
->first_insn
= NULL
;
1289 av
->has_asm_insn
= 0;
1294 /* After all DEFINE_DELAYs have been read in, create internal attributes
1295 to generate the required routines.
1297 First, we compute the number of delay slots for each insn (as a COND of
1298 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1299 delay type is specified, we compute a similar function giving the
1300 DEFINE_DELAY ordinal for each insn.
1302 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1303 tells whether a given insn can be in that delay slot.
1305 Normal attribute filling and optimization expands these to contain the
1306 information needed to handle delay slots. */
1309 expand_delays (void)
1311 struct delay_desc
*delay
;
1317 /* First, generate data for `num_delay_slots' function. */
1319 condexp
= rtx_alloc (COND
);
1320 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1321 XEXP (condexp
, 1) = make_numeric_value (0);
1323 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1325 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1326 XVECEXP (condexp
, 0, i
+ 1)
1327 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1330 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1332 /* If more than one delay type, do the same for computing the delay type. */
1335 condexp
= rtx_alloc (COND
);
1336 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1337 XEXP (condexp
, 1) = make_numeric_value (0);
1339 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1341 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1342 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1345 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1348 /* For each delay possibility and delay slot, compute an eligibility
1349 attribute for non-annulled insns and for each type of annulled (annul
1350 if true and annul if false). */
1351 for (delay
= delays
; delay
; delay
= delay
->next
)
1353 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1355 condexp
= XVECEXP (delay
->def
, 1, i
);
1357 condexp
= false_rtx
;
1358 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1359 make_numeric_value (1), make_numeric_value (0));
1361 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1362 "*delay_%d_%d", delay
->num
, i
/ 3);
1363 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1365 if (have_annul_true
)
1367 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1368 if (condexp
== 0) condexp
= false_rtx
;
1369 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1370 make_numeric_value (1),
1371 make_numeric_value (0));
1372 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1373 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1374 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1377 if (have_annul_false
)
1379 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1380 if (condexp
== 0) condexp
= false_rtx
;
1381 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1382 make_numeric_value (1),
1383 make_numeric_value (0));
1384 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1385 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1386 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1392 /* Once all attributes and insns have been read and checked, we construct for
1393 each attribute value a list of all the insns that have that value for
1397 fill_attr (struct attr_desc
*attr
)
1399 struct attr_value
*av
;
1400 struct insn_ent
*ie
;
1401 struct insn_def
*id
;
1405 /* Don't fill constant attributes. The value is independent of
1406 any particular insn. */
1410 for (id
= defs
; id
; id
= id
->next
)
1412 /* If no value is specified for this insn for this attribute, use the
1415 if (XVEC (id
->def
, id
->vec_idx
))
1416 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1417 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1419 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1422 av
= attr
->default_val
;
1424 av
= get_attr_value (value
, attr
, id
->insn_code
);
1426 ie
= oballoc (struct insn_ent
);
1428 insert_insn_ent (av
, ie
);
1432 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1433 test that checks relative positions of insns (uses MATCH_DUP or PC).
1434 If so, replace it with what is obtained by passing the expression to
1435 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1436 recursively on each value (including the default value). Otherwise,
1437 return the value returned by NO_ADDRESS_FN applied to EXP. */
1440 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1441 rtx (*address_fn
) (rtx
))
1446 if (GET_CODE (exp
) == COND
)
1448 /* See if any tests use addresses. */
1450 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1451 walk_attr_value (XVECEXP (exp
, 0, i
));
1454 return (*address_fn
) (exp
);
1456 /* Make a new copy of this COND, replacing each element. */
1457 newexp
= rtx_alloc (COND
);
1458 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1459 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1461 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1462 XVECEXP (newexp
, 0, i
+ 1)
1463 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1464 no_address_fn
, address_fn
);
1467 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1468 no_address_fn
, address_fn
);
1473 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1476 walk_attr_value (XEXP (exp
, 0));
1478 return (*address_fn
) (exp
);
1480 return attr_rtx (IF_THEN_ELSE
,
1481 substitute_address (XEXP (exp
, 0),
1482 no_address_fn
, address_fn
),
1483 substitute_address (XEXP (exp
, 1),
1484 no_address_fn
, address_fn
),
1485 substitute_address (XEXP (exp
, 2),
1486 no_address_fn
, address_fn
));
1489 return (*no_address_fn
) (exp
);
1492 /* Make new attributes from the `length' attribute. The following are made,
1493 each corresponding to a function called from `shorten_branches' or
1496 *insn_default_length This is the length of the insn to be returned
1497 by `get_attr_length' before `shorten_branches'
1498 has been called. In each case where the length
1499 depends on relative addresses, the largest
1500 possible is used. This routine is also used
1501 to compute the initial size of the insn.
1503 *insn_variable_length_p This returns 1 if the insn's length depends
1504 on relative addresses, zero otherwise.
1506 *insn_current_length This is only called when it is known that the
1507 insn has a variable length and returns the
1508 current length, based on relative addresses.
1512 make_length_attrs (void)
1514 static const char *new_names
[] =
1516 "*insn_default_length",
1518 "*insn_variable_length_p",
1519 "*insn_current_length"
1521 static rtx (*const no_address_fn
[]) (rtx
)
1522 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1523 static rtx (*const address_fn
[]) (rtx
)
1524 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1526 struct attr_desc
*length_attr
, *new_attr
;
1527 struct attr_value
*av
, *new_av
;
1528 struct insn_ent
*ie
, *new_ie
;
1530 /* See if length attribute is defined. If so, it must be numeric. Make
1531 it special so we don't output anything for it. */
1532 length_attr
= find_attr (&length_str
, 0);
1533 if (length_attr
== 0)
1536 if (! length_attr
->is_numeric
)
1537 fatal ("length attribute must be numeric");
1539 length_attr
->is_const
= 0;
1540 length_attr
->is_special
= 1;
1542 /* Make each new attribute, in turn. */
1543 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1545 make_internal_attr (new_names
[i
],
1546 substitute_address (length_attr
->default_val
->value
,
1547 no_address_fn
[i
], address_fn
[i
]),
1549 new_attr
= find_attr (&new_names
[i
], 0);
1550 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1551 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1553 new_av
= get_attr_value (substitute_address (av
->value
,
1556 new_attr
, ie
->def
->insn_code
);
1557 new_ie
= oballoc (struct insn_ent
);
1558 new_ie
->def
= ie
->def
;
1559 insert_insn_ent (new_av
, new_ie
);
1564 /* Utility functions called from above routine. */
1567 identity_fn (rtx exp
)
1573 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1575 return make_numeric_value (0);
1579 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1581 return make_numeric_value (1);
1588 return make_numeric_value (max_attr_value (exp
, &unknown
));
1595 return make_numeric_value (min_attr_value (exp
, &unknown
));
1599 write_length_unit_log (void)
1601 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1602 struct attr_value
*av
;
1603 struct insn_ent
*ie
;
1604 unsigned int length_unit_log
, length_or
;
1607 if (length_attr
== 0)
1609 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1610 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1611 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1612 length_or
|= or_attr_value (av
->value
, &unknown
);
1615 length_unit_log
= 0;
1618 length_or
= ~length_or
;
1619 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1622 printf ("EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1625 /* Take a COND expression and see if any of the conditions in it can be
1626 simplified. If any are known true or known false for the particular insn
1627 code, the COND can be further simplified.
1629 Also call ourselves on any COND operations that are values of this COND.
1631 We do not modify EXP; rather, we make and return a new rtx. */
1634 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1637 /* We store the desired contents here,
1638 then build a new expression if they don't match EXP. */
1639 rtx defval
= XEXP (exp
, 1);
1640 rtx new_defval
= XEXP (exp
, 1);
1641 int len
= XVECLEN (exp
, 0);
1642 rtx
*tests
= XNEWVEC (rtx
, len
);
1646 /* This lets us free all storage allocated below, if appropriate. */
1647 obstack_finish (rtl_obstack
);
1649 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1651 /* See if default value needs simplification. */
1652 if (GET_CODE (defval
) == COND
)
1653 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1655 /* Simplify the subexpressions, and see what tests we can get rid of. */
1657 for (i
= 0; i
< len
; i
+= 2)
1659 rtx newtest
, newval
;
1661 /* Simplify this test. */
1662 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1665 newval
= tests
[i
+ 1];
1666 /* See if this value may need simplification. */
1667 if (GET_CODE (newval
) == COND
)
1668 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1670 /* Look for ways to delete or combine this test. */
1671 if (newtest
== true_rtx
)
1673 /* If test is true, make this value the default
1674 and discard this + any following tests. */
1676 defval
= tests
[i
+ 1];
1677 new_defval
= newval
;
1680 else if (newtest
== false_rtx
)
1682 /* If test is false, discard it and its value. */
1683 for (j
= i
; j
< len
- 2; j
++)
1684 tests
[j
] = tests
[j
+ 2];
1689 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1691 /* If this value and the value for the prev test are the same,
1695 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1696 insn_code
, insn_index
);
1698 /* Delete this test/value. */
1699 for (j
= i
; j
< len
- 2; j
++)
1700 tests
[j
] = tests
[j
+ 2];
1706 tests
[i
+ 1] = newval
;
1709 /* If the last test in a COND has the same value
1710 as the default value, that test isn't needed. */
1712 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1715 /* See if we changed anything. */
1716 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1719 for (i
= 0; i
< len
; i
++)
1720 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1728 if (GET_CODE (defval
) == COND
)
1729 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1737 rtx newexp
= rtx_alloc (COND
);
1739 XVEC (newexp
, 0) = rtvec_alloc (len
);
1740 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1741 XEXP (newexp
, 1) = new_defval
;
1748 /* Remove an insn entry from an attribute value. */
1751 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1753 struct insn_ent
*previe
;
1755 if (av
->first_insn
== ie
)
1756 av
->first_insn
= ie
->next
;
1759 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1761 previe
->next
= ie
->next
;
1765 if (ie
->def
->insn_code
== -1)
1766 av
->has_asm_insn
= 0;
1771 /* Insert an insn entry in an attribute value list. */
1774 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1776 ie
->next
= av
->first_insn
;
1777 av
->first_insn
= ie
;
1779 if (ie
->def
->insn_code
== -1)
1780 av
->has_asm_insn
= 1;
1785 /* This is a utility routine to take an expression that is a tree of either
1786 AND or IOR expressions and insert a new term. The new term will be
1787 inserted at the right side of the first node whose code does not match
1788 the root. A new node will be created with the root's code. Its left
1789 side will be the old right side and its right side will be the new
1792 If the `term' is itself a tree, all its leaves will be inserted. */
1795 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1799 /* Avoid consing in some special cases. */
1800 if (code
== AND
&& term
== true_rtx
)
1802 if (code
== AND
&& term
== false_rtx
)
1804 if (code
== AND
&& exp
== true_rtx
)
1806 if (code
== AND
&& exp
== false_rtx
)
1808 if (code
== IOR
&& term
== true_rtx
)
1810 if (code
== IOR
&& term
== false_rtx
)
1812 if (code
== IOR
&& exp
== true_rtx
)
1814 if (code
== IOR
&& exp
== false_rtx
)
1816 if (attr_equal_p (exp
, term
))
1819 if (GET_CODE (term
) == code
)
1821 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1822 insn_code
, insn_index
);
1823 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1824 insn_code
, insn_index
);
1829 if (GET_CODE (exp
) == code
)
1831 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1832 term
, insn_code
, insn_index
);
1833 if (new_rtx
!= XEXP (exp
, 1))
1834 /* Make a copy of this expression and call recursively. */
1835 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1841 /* Insert the new term. */
1842 newexp
= attr_rtx (code
, exp
, term
);
1845 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1848 /* If we have an expression which AND's a bunch of
1849 (not (eq_attrq "alternative" "n"))
1850 terms, we may have covered all or all but one of the possible alternatives.
1851 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1853 This routine is passed an expression and either AND or IOR. It returns a
1854 bitmask indicating which alternatives are mentioned within EXP. */
1857 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1860 if (GET_CODE (exp
) == code
)
1861 return compute_alternative_mask (XEXP (exp
, 0), code
)
1862 | compute_alternative_mask (XEXP (exp
, 1), code
);
1864 else if (code
== AND
&& GET_CODE (exp
) == NOT
1865 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1866 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1867 string
= XSTR (XEXP (exp
, 0), 1);
1869 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1870 && XSTR (exp
, 0) == alternative_name
)
1871 string
= XSTR (exp
, 1);
1873 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1875 if (code
== AND
&& XINT (exp
, 1))
1876 return XINT (exp
, 0);
1878 if (code
== IOR
&& !XINT (exp
, 1))
1879 return XINT (exp
, 0);
1887 return 1 << (string
[0] - '0');
1888 return 1 << atoi (string
);
1891 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1892 attribute with the value represented by that bit. */
1895 make_alternative_compare (int mask
)
1897 return mk_attr_alt (mask
);
1900 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1901 of "attr" for this insn code. From that value, we can compute a test
1902 showing when the EQ_ATTR will be true. This routine performs that
1903 computation. If a test condition involves an address, we leave the EQ_ATTR
1904 intact because addresses are only valid for the `length' attribute.
1906 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1907 it refers. VALUE is the value of that attribute for the insn
1908 corresponding to INSN_CODE and INSN_INDEX. */
1911 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1912 int insn_code
, int insn_index
)
1919 while (GET_CODE (value
) == ATTR
)
1921 struct attr_value
*av
= NULL
;
1923 attr
= find_attr (&XSTR (value
, 0), 0);
1925 if (insn_code_values
)
1927 struct attr_value_list
*iv
;
1928 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
1929 if (iv
->attr
== attr
)
1937 struct insn_ent
*ie
;
1938 for (av
= attr
->first_value
; av
; av
= av
->next
)
1939 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1940 if (ie
->def
->insn_code
== insn_code
)
1950 switch (GET_CODE (value
))
1953 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
1964 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
1965 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
1966 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
1967 for (p
= string
; *p
; p
++)
1970 newexp
= attr_rtx (EQ
, value
,
1971 attr_rtx (SYMBOL_REF
,
1972 DEF_ATTR_STRING (string
)));
1977 /* We construct an IOR of all the cases for which the
1978 requested attribute value is present. Since we start with
1979 FALSE, if it is not present, FALSE will be returned.
1981 Each case is the AND of the NOT's of the previous conditions with the
1982 current condition; in the default case the current condition is TRUE.
1984 For each possible COND value, call ourselves recursively.
1986 The extra TRUE and FALSE expressions will be eliminated by another
1987 call to the simplification routine. */
1992 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
1994 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
1995 insn_code
, insn_index
);
1997 right
= insert_right_side (AND
, andexp
, this_cond
,
1998 insn_code
, insn_index
);
1999 right
= insert_right_side (AND
, right
,
2000 evaluate_eq_attr (exp
, attr
,
2003 insn_code
, insn_index
),
2004 insn_code
, insn_index
);
2005 orexp
= insert_right_side (IOR
, orexp
, right
,
2006 insn_code
, insn_index
);
2008 /* Add this condition into the AND expression. */
2009 newexp
= attr_rtx (NOT
, this_cond
);
2010 andexp
= insert_right_side (AND
, andexp
, newexp
,
2011 insn_code
, insn_index
);
2014 /* Handle the default case. */
2015 right
= insert_right_side (AND
, andexp
,
2016 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2017 insn_code
, insn_index
),
2018 insn_code
, insn_index
);
2019 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2026 /* If uses an address, must return original expression. But set the
2027 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2030 walk_attr_value (newexp
);
2034 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2035 return copy_rtx_unchanging (exp
);
2042 /* This routine is called when an AND of a term with a tree of AND's is
2043 encountered. If the term or its complement is present in the tree, it
2044 can be replaced with TRUE or FALSE, respectively.
2046 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2047 be true and hence are complementary.
2049 There is one special case: If we see
2050 (and (not (eq_attr "att" "v1"))
2051 (eq_attr "att" "v2"))
2052 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2053 replace the term, not anything in the AND tree. So we pass a pointer to
2057 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2062 int left_eliminates_term
, right_eliminates_term
;
2064 if (GET_CODE (exp
) == AND
)
2066 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2067 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2068 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2070 newexp
= attr_rtx (AND
, left
, right
);
2072 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2076 else if (GET_CODE (exp
) == IOR
)
2078 /* For the IOR case, we do the same as above, except that we can
2079 only eliminate `term' if both sides of the IOR would do so. */
2081 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2082 left_eliminates_term
= (temp
== true_rtx
);
2085 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2086 right_eliminates_term
= (temp
== true_rtx
);
2088 if (left_eliminates_term
&& right_eliminates_term
)
2091 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2093 newexp
= attr_rtx (IOR
, left
, right
);
2095 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2099 /* Check for simplifications. Do some extra checking here since this
2100 routine is called so many times. */
2105 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2108 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2111 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2113 if (attr_alt_subset_p (*pterm
, exp
))
2116 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2119 if (attr_alt_subset_p (exp
, *pterm
))
2125 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2127 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2130 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2136 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2137 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2139 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2142 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2148 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2149 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2151 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2154 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2160 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2162 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2166 else if (GET_CODE (exp
) == NOT
)
2168 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2172 else if (GET_CODE (*pterm
) == NOT
)
2174 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2178 else if (attr_equal_p (exp
, *pterm
))
2184 /* Similar to `simplify_and_tree', but for IOR trees. */
2187 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2192 int left_eliminates_term
, right_eliminates_term
;
2194 if (GET_CODE (exp
) == IOR
)
2196 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2197 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2198 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2200 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2202 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2206 else if (GET_CODE (exp
) == AND
)
2208 /* For the AND case, we do the same as above, except that we can
2209 only eliminate `term' if both sides of the AND would do so. */
2211 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2212 left_eliminates_term
= (temp
== false_rtx
);
2215 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2216 right_eliminates_term
= (temp
== false_rtx
);
2218 if (left_eliminates_term
&& right_eliminates_term
)
2221 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2223 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2225 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2229 if (attr_equal_p (exp
, *pterm
))
2232 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2235 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2238 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2239 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2240 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2243 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2244 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2245 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2251 /* Compute approximate cost of the expression. Used to decide whether
2252 expression is cheap enough for inline. */
2254 attr_rtx_cost (rtx x
)
2260 code
= GET_CODE (x
);
2273 /* Alternatives don't result into function call. */
2274 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2281 const char *fmt
= GET_RTX_FORMAT (code
);
2282 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2288 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2289 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2292 cost
+= attr_rtx_cost (XEXP (x
, i
));
2302 /* Simplify test expression and use temporary obstack in order to avoid
2303 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2304 and avoid unnecessary copying if possible. */
2307 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2310 struct obstack
*old
;
2311 if (ATTR_IND_SIMPLIFIED_P (exp
))
2314 rtl_obstack
= temp_obstack
;
2315 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2317 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2319 return attr_copy_rtx (x
);
2322 /* Returns true if S1 is a subset of S2. */
2325 attr_alt_subset_p (rtx s1
, rtx s2
)
2327 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2330 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2333 return !(XINT (s1
, 0) & XINT (s2
, 0));
2339 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2346 /* Returns true if S1 is a subset of complement of S2. */
2349 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2351 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2354 return !(XINT (s1
, 0) & XINT (s2
, 0));
2357 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2360 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2370 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2373 attr_alt_intersection (rtx s1
, rtx s2
)
2375 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2377 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2380 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2383 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2386 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2389 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2394 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2399 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2402 attr_alt_union (rtx s1
, rtx s2
)
2404 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2406 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2409 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2412 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2415 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2418 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2424 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2428 /* Return EQ_ATTR_ALT expression representing complement of S. */
2431 attr_alt_complement (rtx s
)
2433 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2435 XINT (result
, 0) = XINT (s
, 0);
2436 XINT (result
, 1) = 1 - XINT (s
, 1);
2441 /* Return EQ_ATTR_ALT expression representing set containing elements set
2447 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2449 XINT (result
, 0) = e
;
2450 XINT (result
, 1) = 0;
2455 /* Given an expression, see if it can be simplified for a particular insn
2456 code based on the values of other attributes being tested. This can
2457 eliminate nested get_attr_... calls.
2459 Note that if an endless recursion is specified in the patterns, the
2460 optimization will loop. However, it will do so in precisely the cases where
2461 an infinite recursion loop could occur during compilation. It's better that
2465 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2468 struct attr_desc
*attr
;
2469 struct attr_value
*av
;
2470 struct insn_ent
*ie
;
2471 struct attr_value_list
*iv
;
2474 bool left_alt
, right_alt
;
2476 /* Don't re-simplify something we already simplified. */
2477 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2480 switch (GET_CODE (exp
))
2483 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2484 if (left
== false_rtx
)
2486 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2487 if (right
== false_rtx
)
2490 if (GET_CODE (left
) == EQ_ATTR_ALT
2491 && GET_CODE (right
) == EQ_ATTR_ALT
)
2493 exp
= attr_alt_intersection (left
, right
);
2494 return simplify_test_exp (exp
, insn_code
, insn_index
);
2497 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2498 present on both sides, apply the distributive law since this will
2499 yield simplifications. */
2500 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2501 && compute_alternative_mask (left
, IOR
)
2502 && compute_alternative_mask (right
, IOR
))
2504 if (GET_CODE (left
) == IOR
)
2511 newexp
= attr_rtx (IOR
,
2512 attr_rtx (AND
, left
, XEXP (right
, 0)),
2513 attr_rtx (AND
, left
, XEXP (right
, 1)));
2515 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2518 /* Try with the term on both sides. */
2519 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2520 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2521 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2523 if (left
== false_rtx
|| right
== false_rtx
)
2525 else if (left
== true_rtx
)
2529 else if (right
== true_rtx
)
2533 /* See if all or all but one of the insn's alternatives are specified
2534 in this tree. Optimize if so. */
2536 if (GET_CODE (left
) == NOT
)
2537 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2538 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2540 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2543 if (GET_CODE (right
) == NOT
)
2544 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2545 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2547 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2548 && XINT (right
, 1));
2551 && (GET_CODE (left
) == AND
2553 || GET_CODE (right
) == AND
2556 i
= compute_alternative_mask (exp
, AND
);
2557 if (i
& ~insn_alternatives
[insn_code
])
2558 fatal ("invalid alternative specified for pattern number %d",
2561 /* If all alternatives are excluded, this is false. */
2562 i
^= insn_alternatives
[insn_code
];
2565 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2567 /* If just one excluded, AND a comparison with that one to the
2568 front of the tree. The others will be eliminated by
2569 optimization. We do not want to do this if the insn has one
2570 alternative and we have tested none of them! */
2571 left
= make_alternative_compare (i
);
2572 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2573 newexp
= attr_rtx (AND
, left
, right
);
2575 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2579 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2581 newexp
= attr_rtx (AND
, left
, right
);
2582 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2587 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2588 if (left
== true_rtx
)
2590 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2591 if (right
== true_rtx
)
2594 if (GET_CODE (left
) == EQ_ATTR_ALT
2595 && GET_CODE (right
) == EQ_ATTR_ALT
)
2597 exp
= attr_alt_union (left
, right
);
2598 return simplify_test_exp (exp
, insn_code
, insn_index
);
2601 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2602 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2603 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2605 if (right
== true_rtx
|| left
== true_rtx
)
2607 else if (left
== false_rtx
)
2611 else if (right
== false_rtx
)
2616 /* Test for simple cases where the distributive law is useful. I.e.,
2617 convert (ior (and (x) (y))
2623 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2624 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2626 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2628 left
= XEXP (left
, 0);
2630 newexp
= attr_rtx (AND
, left
, right
);
2631 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2634 /* See if all or all but one of the insn's alternatives are specified
2635 in this tree. Optimize if so. */
2637 else if (insn_code
>= 0
2638 && (GET_CODE (left
) == IOR
2639 || (GET_CODE (left
) == EQ_ATTR_ALT
2641 || (GET_CODE (left
) == EQ_ATTR
2642 && XSTR (left
, 0) == alternative_name
)
2643 || GET_CODE (right
) == IOR
2644 || (GET_CODE (right
) == EQ_ATTR_ALT
2645 && !XINT (right
, 1))
2646 || (GET_CODE (right
) == EQ_ATTR
2647 && XSTR (right
, 0) == alternative_name
)))
2649 i
= compute_alternative_mask (exp
, IOR
);
2650 if (i
& ~insn_alternatives
[insn_code
])
2651 fatal ("invalid alternative specified for pattern number %d",
2654 /* If all alternatives are included, this is true. */
2655 i
^= insn_alternatives
[insn_code
];
2658 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2660 /* If just one excluded, IOR a comparison with that one to the
2661 front of the tree. The others will be eliminated by
2662 optimization. We do not want to do this if the insn has one
2663 alternative and we have tested none of them! */
2664 left
= make_alternative_compare (i
);
2665 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2666 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2668 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2672 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2674 newexp
= attr_rtx (IOR
, left
, right
);
2675 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2680 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2682 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2683 insn_code
, insn_index
);
2687 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2688 if (GET_CODE (left
) == NOT
)
2689 return XEXP (left
, 0);
2691 if (left
== false_rtx
)
2693 if (left
== true_rtx
)
2696 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2698 exp
= attr_alt_complement (left
);
2699 return simplify_test_exp (exp
, insn_code
, insn_index
);
2702 /* Try to apply De`Morgan's laws. */
2703 if (GET_CODE (left
) == IOR
)
2705 newexp
= attr_rtx (AND
,
2706 attr_rtx (NOT
, XEXP (left
, 0)),
2707 attr_rtx (NOT
, XEXP (left
, 1)));
2709 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2711 else if (GET_CODE (left
) == AND
)
2713 newexp
= attr_rtx (IOR
,
2714 attr_rtx (NOT
, XEXP (left
, 0)),
2715 attr_rtx (NOT
, XEXP (left
, 1)));
2717 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2719 else if (left
!= XEXP (exp
, 0))
2721 newexp
= attr_rtx (NOT
, left
);
2727 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2731 if (XSTR (exp
, 0) == alternative_name
)
2733 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2737 /* Look at the value for this insn code in the specified attribute.
2738 We normally can replace this comparison with the condition that
2739 would give this insn the values being tested for. */
2741 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2746 if (insn_code_values
)
2748 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2749 if (iv
->attr
== attr
)
2757 for (av
= attr
->first_value
; av
; av
= av
->next
)
2758 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2759 if (ie
->def
->insn_code
== insn_code
)
2766 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2767 insn_code
, insn_index
);
2768 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2769 if (attr_rtx_cost(x
) < 20)
2779 /* We have already simplified this expression. Simplifying it again
2780 won't buy anything unless we weren't given a valid insn code
2781 to process (i.e., we are canonicalizing something.). */
2783 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2784 return copy_rtx_unchanging (newexp
);
2789 /* Optimize the attribute lists by seeing if we can determine conditional
2790 values from the known values of other attributes. This will save subroutine
2791 calls during the compilation. */
2794 optimize_attrs (void)
2796 struct attr_desc
*attr
;
2797 struct attr_value
*av
;
2798 struct insn_ent
*ie
;
2801 struct attr_value_list
*ivbuf
;
2802 struct attr_value_list
*iv
;
2804 /* For each insn code, make a list of all the insn_ent's for it,
2805 for all values for all attributes. */
2807 if (num_insn_ents
== 0)
2810 /* Make 2 extra elements, for "code" values -2 and -1. */
2811 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2813 /* Offset the table address so we can index by -2 or -1. */
2814 insn_code_values
+= 2;
2816 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2818 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2819 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2820 for (av
= attr
->first_value
; av
; av
= av
->next
)
2821 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2826 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2827 insn_code_values
[ie
->def
->insn_code
] = iv
;
2831 /* Sanity check on num_insn_ents. */
2832 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2834 /* Process one insn code at a time. */
2835 for (i
= -2; i
< insn_code_number
; i
++)
2837 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2838 We use it to mean "already simplified for this insn". */
2839 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2840 clear_struct_flag (iv
->av
->value
);
2842 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2844 struct obstack
*old
= rtl_obstack
;
2849 if (GET_CODE (av
->value
) != COND
)
2852 rtl_obstack
= temp_obstack
;
2854 while (GET_CODE (newexp
) == COND
)
2856 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2857 ie
->def
->insn_index
);
2858 if (newexp2
== newexp
)
2864 if (newexp
!= av
->value
)
2866 newexp
= attr_copy_rtx (newexp
);
2867 remove_insn_ent (av
, ie
);
2868 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2870 insert_insn_ent (av
, ie
);
2876 free (insn_code_values
- 2);
2877 insn_code_values
= NULL
;
2880 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2883 clear_struct_flag (rtx x
)
2890 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2891 if (ATTR_IND_SIMPLIFIED_P (x
))
2894 code
= GET_CODE (x
);
2914 /* Compare the elements. If any pair of corresponding elements
2915 fail to match, return 0 for the whole things. */
2917 fmt
= GET_RTX_FORMAT (code
);
2918 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2924 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2925 clear_struct_flag (XVECEXP (x
, i
, j
));
2929 clear_struct_flag (XEXP (x
, i
));
2935 /* Add attribute value NAME to the beginning of ATTR's list. */
2938 add_attr_value (struct attr_desc
*attr
, const char *name
)
2940 struct attr_value
*av
;
2942 av
= oballoc (struct attr_value
);
2943 av
->value
= attr_rtx (CONST_STRING
, name
);
2944 av
->next
= attr
->first_value
;
2945 attr
->first_value
= av
;
2946 av
->first_insn
= NULL
;
2948 av
->has_asm_insn
= 0;
2951 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
2954 gen_attr (rtx exp
, int lineno
)
2956 struct enum_type
*et
;
2957 struct enum_value
*ev
;
2958 struct attr_desc
*attr
;
2959 const char *name_ptr
;
2962 /* Make a new attribute structure. Check for duplicate by looking at
2963 attr->default_val, since it is initialized by this routine. */
2964 attr
= find_attr (&XSTR (exp
, 0), 1);
2965 if (attr
->default_val
)
2967 error_with_line (lineno
, "duplicate definition for attribute %s",
2969 message_with_line (attr
->lineno
, "previous definition");
2972 attr
->lineno
= lineno
;
2974 if (GET_CODE (exp
) == DEFINE_ENUM_ATTR
)
2976 attr
->enum_name
= XSTR (exp
, 1);
2977 et
= lookup_enum_type (XSTR (exp
, 1));
2978 if (!et
|| !et
->md_p
)
2979 error_with_line (lineno
, "No define_enum called `%s' defined",
2981 for (ev
= et
->values
; ev
; ev
= ev
->next
)
2982 add_attr_value (attr
, ev
->name
);
2984 else if (*XSTR (exp
, 1) == '\0')
2985 attr
->is_numeric
= 1;
2988 name_ptr
= XSTR (exp
, 1);
2989 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
2990 add_attr_value (attr
, p
);
2993 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
2996 if (attr
->is_numeric
)
2997 error_with_line (lineno
,
2998 "constant attributes may not take numeric values");
3000 /* Get rid of the CONST node. It is allowed only at top-level. */
3001 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3004 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3005 error_with_line (lineno
, "`length' attribute must take numeric values");
3007 /* Set up the default value. */
3008 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3009 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3012 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3013 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3014 number of alternatives as this should be checked elsewhere. */
3017 count_alternatives (rtx exp
)
3022 if (GET_CODE (exp
) == MATCH_OPERAND
)
3023 return n_comma_elts (XSTR (exp
, 2));
3025 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3026 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3031 n
= count_alternatives (XEXP (exp
, i
));
3038 if (XVEC (exp
, i
) != NULL
)
3039 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3041 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3050 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3051 `alternative' attribute. */
3054 compares_alternatives_p (rtx exp
)
3059 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3062 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3063 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3068 if (compares_alternatives_p (XEXP (exp
, i
)))
3073 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3074 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3082 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3085 gen_insn (rtx exp
, int lineno
)
3087 struct insn_def
*id
;
3089 id
= oballoc (struct insn_def
);
3093 id
->lineno
= lineno
;
3095 switch (GET_CODE (exp
))
3098 id
->insn_code
= insn_code_number
;
3099 id
->insn_index
= insn_index_number
;
3100 id
->num_alternatives
= count_alternatives (exp
);
3101 if (id
->num_alternatives
== 0)
3102 id
->num_alternatives
= 1;
3106 case DEFINE_PEEPHOLE
:
3107 id
->insn_code
= insn_code_number
;
3108 id
->insn_index
= insn_index_number
;
3109 id
->num_alternatives
= count_alternatives (exp
);
3110 if (id
->num_alternatives
== 0)
3111 id
->num_alternatives
= 1;
3115 case DEFINE_ASM_ATTRIBUTES
:
3117 id
->insn_index
= -1;
3118 id
->num_alternatives
= 1;
3120 got_define_asm_attributes
= 1;
3128 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3129 true or annul false is specified, and make a `struct delay_desc'. */
3132 gen_delay (rtx def
, int lineno
)
3134 struct delay_desc
*delay
;
3137 if (XVECLEN (def
, 1) % 3 != 0)
3139 error_with_line (lineno
,
3140 "number of elements in DEFINE_DELAY must"
3141 " be multiple of three");
3145 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3147 if (XVECEXP (def
, 1, i
+ 1))
3148 have_annul_true
= 1;
3149 if (XVECEXP (def
, 1, i
+ 2))
3150 have_annul_false
= 1;
3153 delay
= oballoc (struct delay_desc
);
3155 delay
->num
= ++num_delays
;
3156 delay
->next
= delays
;
3157 delay
->lineno
= lineno
;
3161 /* Names of attributes that could be possibly cached. */
3162 static const char *cached_attrs
[32];
3163 /* Number of such attributes. */
3164 static int cached_attr_count
;
3165 /* Bitmasks of possibly cached attributes. */
3166 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3167 static unsigned int attrs_to_cache
;
3168 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3170 /* Finds non-const attributes that could be possibly cached.
3171 When create is TRUE, fills in cached_attrs array.
3172 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3176 find_attrs_to_cache (rtx exp
, bool create
)
3180 struct attr_desc
*attr
;
3185 switch (GET_CODE (exp
))
3188 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3189 find_attrs_to_cache (XEXP (exp
, 0), create
);
3193 name
= XSTR (exp
, 0);
3194 if (name
== alternative_name
)
3196 for (i
= 0; i
< cached_attr_count
; i
++)
3197 if (name
== cached_attrs
[i
])
3199 if ((attrs_seen_once
& (1U << i
)) != 0)
3200 attrs_seen_more_than_once
|= (1U << i
);
3202 attrs_seen_once
|= (1U << i
);
3207 attr
= find_attr (&name
, 0);
3211 if (cached_attr_count
== 32)
3213 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3214 attrs_seen_once
|= (1U << cached_attr_count
);
3215 cached_attr_count
++;
3220 find_attrs_to_cache (XEXP (exp
, 0), create
);
3221 find_attrs_to_cache (XEXP (exp
, 1), create
);
3225 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3226 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3234 /* Given a piece of RTX, print a C expression to test its truth value.
3235 We use AND and IOR both for logical and bit-wise operations, so
3236 interpret them as logical unless they are inside a comparison expression. */
3238 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3239 #define FLG_BITWISE 1
3240 /* Set if cached attribute will be known initialized in else block after
3241 this condition. This is true for LHS of toplevel && and || and
3242 even for RHS of ||, but not for RHS of &&. */
3244 /* Set if cached attribute will be known initialized in then block after
3245 this condition. This is true for LHS of toplevel && and || and
3246 even for RHS of &&, but not for RHS of ||. */
3247 #define FLG_INSIDE 4
3248 /* Cleared when an operand of &&. */
3249 #define FLG_OUTSIDE_AND 8
3252 write_test_expr (rtx exp
, unsigned int attrs_cached
, int flags
)
3254 int comparison_operator
= 0;
3256 struct attr_desc
*attr
;
3258 /* In order not to worry about operator precedence, surround our part of
3259 the expression with parentheses. */
3262 code
= GET_CODE (exp
);
3265 /* Binary operators. */
3268 printf ("(unsigned) ");
3274 comparison_operator
= FLG_BITWISE
;
3276 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3277 case AND
: case IOR
: case XOR
:
3278 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3279 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3281 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3282 write_test_expr (XEXP (exp
, 0), attrs_cached
,
3283 flags
| comparison_operator
);
3288 flags
&= ~FLG_OUTSIDE_AND
;
3289 if (GET_CODE (XEXP (exp
, 0)) == code
3290 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3291 || (GET_CODE (XEXP (exp
, 0)) == NOT
3292 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3294 = write_test_expr (XEXP (exp
, 0), attrs_cached
, flags
);
3296 write_test_expr (XEXP (exp
, 0), attrs_cached
, flags
);
3313 printf (" >= (unsigned) ");
3316 printf (" > (unsigned) ");
3325 printf (" <= (unsigned) ");
3328 printf (" < (unsigned) ");
3346 if (flags
& FLG_BITWISE
)
3352 if (flags
& FLG_BITWISE
)
3373 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3374 cached_x is only known to be initialized in then block. */
3375 flags
&= ~FLG_AFTER
;
3377 else if (code
== IOR
)
3379 if (flags
& FLG_OUTSIDE_AND
)
3380 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3381 cached_x is only known to be initialized in else block
3382 and else if conditions. */
3383 flags
&= ~FLG_INSIDE
;
3385 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3387 cached_x is not know to be initialized anywhere. */
3388 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3390 if ((code
== AND
|| code
== IOR
)
3391 && (GET_CODE (XEXP (exp
, 1)) == code
3392 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3393 || (GET_CODE (XEXP (exp
, 1)) == NOT
3394 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3396 = write_test_expr (XEXP (exp
, 1), attrs_cached
, flags
);
3398 write_test_expr (XEXP (exp
, 1), attrs_cached
,
3399 flags
| comparison_operator
);
3403 /* Special-case (not (eq_attrq "alternative" "x")) */
3404 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3406 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3408 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3413 attrs_cached
= write_test_expr (XEXP (exp
, 0), attrs_cached
, flags
);
3417 /* Otherwise, fall through to normal unary operator. */
3419 /* Unary operators. */
3424 if (flags
& FLG_BITWISE
)
3439 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3440 write_test_expr (XEXP (exp
, 0), attrs_cached
, flags
);
3445 int set
= XINT (exp
, 0), bit
= 0;
3447 if (flags
& FLG_BITWISE
)
3448 fatal ("EQ_ATTR_ALT not valid inside comparison");
3451 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3453 if (!(set
& (set
- 1)))
3455 if (!(set
& 0xffff))
3478 printf ("which_alternative %s= %d",
3479 XINT (exp
, 1) ? "!" : "=", bit
);
3483 printf ("%s((1 << which_alternative) & %#x)",
3484 XINT (exp
, 1) ? "!" : "", set
);
3489 /* Comparison test of an attribute with a value. Most of these will
3490 have been removed by optimization. Handle "alternative"
3491 specially and give error if EQ_ATTR present inside a comparison. */
3493 if (flags
& FLG_BITWISE
)
3494 fatal ("EQ_ATTR not valid inside comparison");
3496 if (XSTR (exp
, 0) == alternative_name
)
3498 printf ("which_alternative == %s", XSTR (exp
, 1));
3502 attr
= find_attr (&XSTR (exp
, 0), 0);
3505 /* Now is the time to expand the value of a constant attribute. */
3508 write_test_expr (evaluate_eq_attr (exp
, attr
,
3509 attr
->default_val
->value
, -2, -2),
3515 for (i
= 0; i
< cached_attr_count
; i
++)
3516 if (attr
->name
== cached_attrs
[i
])
3518 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3519 printf ("cached_%s", attr
->name
);
3520 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3522 printf ("(cached_%s = get_attr_%s (insn))",
3523 attr
->name
, attr
->name
);
3524 if (flags
& FLG_AFTER
)
3525 attrs_cached_after
|= (1U << i
);
3526 if (flags
& FLG_INSIDE
)
3527 attrs_cached_inside
|= (1U << i
);
3528 attrs_cached
|= (1U << i
);
3531 printf ("get_attr_%s (insn)", attr
->name
);
3533 write_attr_valueq (attr
, XSTR (exp
, 1));
3537 /* Comparison test of flags for define_delays. */
3539 if (flags
& FLG_BITWISE
)
3540 fatal ("ATTR_FLAG not valid inside comparison");
3541 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3544 /* See if an operand matches a predicate. */
3546 /* If only a mode is given, just ensure the mode matches the operand.
3547 If neither a mode nor predicate is given, error. */
3548 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3550 if (GET_MODE (exp
) == VOIDmode
)
3551 fatal ("null MATCH_OPERAND specified as test");
3553 printf ("GET_MODE (operands[%d]) == %smode",
3554 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3557 printf ("%s (operands[%d], %smode)",
3558 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3561 /* Constant integer. */
3563 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3566 /* A random C expression. */
3568 print_c_condition (XSTR (exp
, 0));
3571 /* The address of the branch target. */
3573 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3574 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3578 /* The address of the current insn. We implement this actually as the
3579 address of the current insn for backward branches, but the last
3580 address of the next insn for forward branches, and both with
3581 adjustments that account for the worst-case possible stretching of
3582 intervening alignments between this insn and its destination. */
3583 printf ("insn_current_reference_address (insn)");
3587 printf ("%s", XSTR (exp
, 0));
3591 write_test_expr (XEXP (exp
, 0), attrs_cached
, 0);
3593 write_test_expr (XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3595 write_test_expr (XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3599 fatal ("bad RTX code `%s' in attribute calculation\n",
3600 GET_RTX_NAME (code
));
3604 return attrs_cached
;
3607 /* Given an attribute value, return the maximum CONST_STRING argument
3608 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3611 max_attr_value (rtx exp
, int *unknownp
)
3616 switch (GET_CODE (exp
))
3619 current_max
= atoi (XSTR (exp
, 0));
3623 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3624 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3626 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3627 if (n
> current_max
)
3633 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3634 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3635 if (n
> current_max
)
3641 current_max
= INT_MAX
;
3648 /* Given an attribute value, return the minimum CONST_STRING argument
3649 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3652 min_attr_value (rtx exp
, int *unknownp
)
3657 switch (GET_CODE (exp
))
3660 current_min
= atoi (XSTR (exp
, 0));
3664 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3665 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3667 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3668 if (n
< current_min
)
3674 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3675 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3676 if (n
< current_min
)
3682 current_min
= INT_MAX
;
3689 /* Given an attribute value, return the result of ORing together all
3690 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3691 if the numeric value is not known. */
3694 or_attr_value (rtx exp
, int *unknownp
)
3699 switch (GET_CODE (exp
))
3702 current_or
= atoi (XSTR (exp
, 0));
3706 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3707 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3708 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3712 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3713 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3725 /* Scan an attribute value, possibly a conditional, and record what actions
3726 will be required to do any conditional tests in it.
3729 `must_extract' if we need to extract the insn operands
3730 `must_constrain' if we must compute `which_alternative'
3731 `address_used' if an address expression was used
3732 `length_used' if an (eq_attr "length" ...) was used
3736 walk_attr_value (rtx exp
)
3745 code
= GET_CODE (exp
);
3749 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3750 /* Since this is an arbitrary expression, it can look at anything.
3751 However, constant expressions do not depend on any particular
3753 must_extract
= must_constrain
= 1;
3761 must_extract
= must_constrain
= 1;
3765 if (XSTR (exp
, 0) == alternative_name
)
3766 must_extract
= must_constrain
= 1;
3767 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3787 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3792 walk_attr_value (XEXP (exp
, i
));
3796 if (XVEC (exp
, i
) != NULL
)
3797 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3798 walk_attr_value (XVECEXP (exp
, i
, j
));
3803 /* Write out a function to obtain the attribute for a given INSN. */
3806 write_attr_get (struct attr_desc
*attr
)
3808 struct attr_value
*av
, *common_av
;
3811 /* Find the most used attribute value. Handle that as the `default' of the
3812 switch we will generate. */
3813 common_av
= find_most_used (attr
);
3815 /* Write out start of function, then all values with explicit `case' lines,
3816 then a `default', then the value with the most uses. */
3817 if (attr
->enum_name
)
3818 printf ("enum %s\n", attr
->enum_name
);
3819 else if (!attr
->is_numeric
)
3820 printf ("enum attr_%s\n", attr
->name
);
3824 /* If the attribute name starts with a star, the remainder is the name of
3825 the subroutine to use, instead of `get_attr_...'. */
3826 if (attr
->name
[0] == '*')
3827 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3828 else if (attr
->is_const
== 0)
3829 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3832 printf ("get_attr_%s (void)\n", attr
->name
);
3835 for (av
= attr
->first_value
; av
; av
= av
->next
)
3836 if (av
->num_insns
== 1)
3837 write_attr_set (attr
, 2, av
->value
, "return", ";",
3838 true_rtx
, av
->first_insn
->def
->insn_code
,
3839 av
->first_insn
->def
->insn_index
, 0);
3840 else if (av
->num_insns
!= 0)
3841 write_attr_set (attr
, 2, av
->value
, "return", ";",
3842 true_rtx
, -2, 0, 0);
3850 /* Find attributes that are worth caching in the conditions. */
3851 cached_attr_count
= 0;
3852 attrs_seen_more_than_once
= 0;
3853 for (av
= attr
->first_value
; av
; av
= av
->next
)
3855 attrs_seen_once
= 0;
3856 find_attrs_to_cache (av
->value
, true);
3858 /* Remove those that aren't worth caching from the array. */
3859 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
3860 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
3862 const char *name
= cached_attrs
[i
];
3863 struct attr_desc
*cached_attr
;
3865 cached_attrs
[j
] = name
;
3866 cached_attr
= find_attr (&name
, 0);
3867 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
3868 if (cached_attr
->enum_name
)
3869 printf (" enum %s", cached_attr
->enum_name
);
3870 else if (!cached_attr
->is_numeric
)
3871 printf (" enum attr_%s", cached_attr
->name
);
3874 printf (" cached_%s ATTRIBUTE_UNUSED;\n", name
);
3877 cached_attr_count
= j
;
3878 if (cached_attr_count
)
3881 printf (" switch (recog_memoized (insn))\n");
3884 for (av
= attr
->first_value
; av
; av
= av
->next
)
3885 if (av
!= common_av
)
3886 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3888 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3889 printf (" }\n}\n\n");
3890 cached_attr_count
= 0;
3893 /* Given an AND tree of known true terms (because we are inside an `if' with
3894 that as the condition or are in an `else' clause) and an expression,
3895 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3896 the bulk of the work. */
3899 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3903 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3905 if (GET_CODE (known_true
) == AND
)
3907 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3908 insn_code
, insn_index
);
3909 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3910 insn_code
, insn_index
);
3915 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3921 /* Write out a series of tests and assignment statements to perform tests and
3922 sets of an attribute value. We are passed an indentation amount and prefix
3923 and suffix strings to write around each attribute value (e.g., "return"
3927 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3928 const char *prefix
, const char *suffix
, rtx known_true
,
3929 int insn_code
, int insn_index
, unsigned int attrs_cached
)
3931 if (GET_CODE (value
) == COND
)
3933 /* Assume the default value will be the default of the COND unless we
3934 find an always true expression. */
3935 rtx default_val
= XEXP (value
, 1);
3936 rtx our_known_true
= known_true
;
3941 if (cached_attr_count
)
3943 attrs_seen_once
= 0;
3944 attrs_seen_more_than_once
= 0;
3945 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3946 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
3947 attrs_to_cache
|= attrs_seen_more_than_once
;
3950 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3955 testexp
= eliminate_known_true (our_known_true
,
3956 XVECEXP (value
, 0, i
),
3957 insn_code
, insn_index
);
3958 newexp
= attr_rtx (NOT
, testexp
);
3959 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3960 insn_code
, insn_index
);
3962 /* If the test expression is always true or if the next `known_true'
3963 expression is always false, this is the last case, so break
3964 out and let this value be the `else' case. */
3965 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3967 default_val
= XVECEXP (value
, 0, i
+ 1);
3971 /* Compute the expression to pass to our recursive call as being
3973 inner_true
= insert_right_side (AND
, our_known_true
,
3974 testexp
, insn_code
, insn_index
);
3976 /* If this is always false, skip it. */
3977 if (inner_true
== false_rtx
)
3980 attrs_cached_inside
= attrs_cached
;
3981 attrs_cached_after
= attrs_cached
;
3982 write_indent (indent
);
3983 printf ("%sif ", first_if
? "" : "else ");
3985 write_test_expr (testexp
, attrs_cached
,
3986 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
3987 attrs_cached
= attrs_cached_after
;
3989 write_indent (indent
+ 2);
3992 write_attr_set (attr
, indent
+ 4,
3993 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3994 inner_true
, insn_code
, insn_index
,
3995 attrs_cached_inside
);
3996 write_indent (indent
+ 2);
3998 our_known_true
= newexp
;
4003 write_indent (indent
);
4005 write_indent (indent
+ 2);
4009 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
4010 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4015 write_indent (indent
+ 2);
4021 write_indent (indent
);
4022 printf ("%s ", prefix
);
4023 write_attr_value (attr
, value
);
4024 printf ("%s\n", suffix
);
4028 /* Write a series of case statements for every instruction in list IE.
4029 INDENT is the amount of indentation to write before each case. */
4032 write_insn_cases (struct insn_ent
*ie
, int indent
)
4034 for (; ie
!= 0; ie
= ie
->next
)
4035 if (ie
->def
->insn_code
!= -1)
4037 write_indent (indent
);
4038 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4039 printf ("case %d: /* define_peephole, line %d */\n",
4040 ie
->def
->insn_code
, ie
->def
->lineno
);
4042 printf ("case %d: /* %s */\n",
4043 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4047 /* Write out the computation for one attribute value. */
4050 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
4051 int write_case_lines
, const char *prefix
, const char *suffix
,
4052 int indent
, rtx known_true
)
4054 if (av
->num_insns
== 0)
4057 if (av
->has_asm_insn
)
4059 write_indent (indent
);
4060 printf ("case -1:\n");
4061 write_indent (indent
+ 2);
4062 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4063 write_indent (indent
+ 2);
4064 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
4065 write_indent (indent
+ 2);
4066 printf (" fatal_insn_not_found (insn);\n");
4069 if (write_case_lines
)
4070 write_insn_cases (av
->first_insn
, indent
);
4073 write_indent (indent
);
4074 printf ("default:\n");
4077 /* See what we have to do to output this value. */
4078 must_extract
= must_constrain
= address_used
= 0;
4079 walk_attr_value (av
->value
);
4083 write_indent (indent
+ 2);
4084 printf ("extract_constrain_insn_cached (insn);\n");
4086 else if (must_extract
)
4088 write_indent (indent
+ 2);
4089 printf ("extract_insn_cached (insn);\n");
4093 if (av
->num_insns
== 1)
4094 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4095 known_true
, av
->first_insn
->def
->insn_code
,
4096 av
->first_insn
->def
->insn_index
, 0);
4098 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4099 known_true
, -2, 0, 0);
4101 if (strncmp (prefix
, "return", 6))
4103 write_indent (indent
+ 2);
4104 printf ("break;\n");
4109 /* Utilities to write in various forms. */
4112 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
4114 if (attr
->is_numeric
)
4120 if (num
> 9 || num
< 0)
4121 printf (" /* %#x */", num
);
4125 write_upcase (attr
->enum_name
? attr
->enum_name
: attr
->name
);
4132 write_attr_value (struct attr_desc
*attr
, rtx value
)
4136 switch (GET_CODE (value
))
4139 write_attr_valueq (attr
, XSTR (value
, 0));
4143 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4147 print_c_condition (XSTR (value
, 0));
4152 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4153 if (attr
->enum_name
)
4154 printf ("(enum %s)", attr
->enum_name
);
4155 else if (!attr
->is_numeric
)
4156 printf ("(enum attr_%s)", attr
->name
);
4157 else if (!attr2
->is_numeric
)
4160 printf ("get_attr_%s (%s)", attr2
->name
,
4161 (attr2
->is_const
? "" : "insn"));
4182 write_attr_value (attr
, XEXP (value
, 0));
4186 write_attr_value (attr
, XEXP (value
, 1));
4195 write_upcase (const char *str
)
4199 /* The argument of TOUPPER should not have side effects. */
4200 putchar (TOUPPER(*str
));
4206 write_indent (int indent
)
4208 for (; indent
> 8; indent
-= 8)
4211 for (; indent
; indent
--)
4215 /* Write a subroutine that is given an insn that requires a delay slot, a
4216 delay slot ordinal, and a candidate insn. It returns nonzero if the
4217 candidate can be placed in the specified delay slot of the insn.
4219 We can write as many as three subroutines. `eligible_for_delay'
4220 handles normal delay slots, `eligible_for_annul_true' indicates that
4221 the specified insn can be annulled if the branch is true, and likewise
4222 for `eligible_for_annul_false'.
4224 KIND is a string distinguishing these three cases ("delay", "annul_true",
4225 or "annul_false"). */
4228 write_eligible_delay (const char *kind
)
4230 struct delay_desc
*delay
;
4234 struct attr_desc
*attr
;
4235 struct attr_value
*av
, *common_av
;
4238 /* Compute the maximum number of delay slots required. We use the delay
4239 ordinal times this number plus one, plus the slot number as an index into
4240 the appropriate predicate to test. */
4242 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4243 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4244 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4246 /* Write function prelude. */
4249 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4252 printf (" rtx insn;\n");
4254 printf (" gcc_assert (slot < %d);\n", max_slots
);
4256 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4257 converts a compound instruction into a loop. */
4258 printf (" if (!INSN_P (candidate_insn))\n");
4259 printf (" return 0;\n");
4262 /* If more than one delay type, find out which type the delay insn is. */
4266 attr
= find_attr (&delay_type_str
, 0);
4268 common_av
= find_most_used (attr
);
4270 printf (" insn = delay_insn;\n");
4271 printf (" switch (recog_memoized (insn))\n");
4274 sprintf (str
, " * %d;\n break;", max_slots
);
4275 for (av
= attr
->first_value
; av
; av
= av
->next
)
4276 if (av
!= common_av
)
4277 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4279 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4282 /* Ensure matched. Otherwise, shouldn't have been called. */
4283 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4286 /* If just one type of delay slot, write simple switch. */
4287 if (num_delays
== 1 && max_slots
== 1)
4289 printf (" insn = candidate_insn;\n");
4290 printf (" switch (recog_memoized (insn))\n");
4293 attr
= find_attr (&delay_1_0_str
, 0);
4295 common_av
= find_most_used (attr
);
4297 for (av
= attr
->first_value
; av
; av
= av
->next
)
4298 if (av
!= common_av
)
4299 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4301 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4307 /* Write a nested CASE. The first indicates which condition we need to
4308 test, and the inner CASE tests the condition. */
4309 printf (" insn = candidate_insn;\n");
4310 printf (" switch (slot)\n");
4313 for (delay
= delays
; delay
; delay
= delay
->next
)
4314 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4316 printf (" case %d:\n",
4317 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4318 printf (" switch (recog_memoized (insn))\n");
4321 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4323 attr
= find_attr (&pstr
, 0);
4325 common_av
= find_most_used (attr
);
4327 for (av
= attr
->first_value
; av
; av
= av
->next
)
4328 if (av
!= common_av
)
4329 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4331 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4335 printf (" default:\n");
4336 printf (" gcc_unreachable ();\n");
4343 /* This page contains miscellaneous utility routines. */
4345 /* Given a pointer to a (char *), return a malloc'ed string containing the
4346 next comma-separated element. Advance the pointer to after the string
4347 scanned, or the end-of-string. Return NULL if at end of string. */
4350 next_comma_elt (const char **pstr
)
4354 start
= scan_comma_elt (pstr
);
4359 return attr_string (start
, *pstr
- start
);
4362 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4363 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4364 replaced by a pointer to a canonical copy of the string. */
4366 static struct attr_desc
*
4367 find_attr (const char **name_p
, int create
)
4369 struct attr_desc
*attr
;
4371 const char *name
= *name_p
;
4373 /* Before we resort to using `strcmp', see if the string address matches
4374 anywhere. In most cases, it should have been canonicalized to do so. */
4375 if (name
== alternative_name
)
4378 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4379 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4380 if (name
== attr
->name
)
4383 /* Otherwise, do it the slow way. */
4384 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4385 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4387 *name_p
= attr
->name
;
4394 attr
= oballoc (struct attr_desc
);
4395 attr
->name
= DEF_ATTR_STRING (name
);
4396 attr
->enum_name
= 0;
4397 attr
->first_value
= attr
->default_val
= NULL
;
4398 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4399 attr
->next
= attrs
[index
];
4400 attrs
[index
] = attr
;
4402 *name_p
= attr
->name
;
4407 /* Create internal attribute with the given default value. */
4410 make_internal_attr (const char *name
, rtx value
, int special
)
4412 struct attr_desc
*attr
;
4414 attr
= find_attr (&name
, 1);
4415 gcc_assert (!attr
->default_val
);
4417 attr
->is_numeric
= 1;
4419 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4420 attr
->default_val
= get_attr_value (value
, attr
, -2);
4423 /* Find the most used value of an attribute. */
4425 static struct attr_value
*
4426 find_most_used (struct attr_desc
*attr
)
4428 struct attr_value
*av
;
4429 struct attr_value
*most_used
;
4435 for (av
= attr
->first_value
; av
; av
= av
->next
)
4436 if (av
->num_insns
> nuses
)
4437 nuses
= av
->num_insns
, most_used
= av
;
4442 /* Return (attr_value "n") */
4445 make_numeric_value (int n
)
4447 static rtx int_values
[20];
4451 gcc_assert (n
>= 0);
4453 if (n
< 20 && int_values
[n
])
4454 return int_values
[n
];
4456 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4457 exp
= attr_rtx (CONST_STRING
, p
);
4460 int_values
[n
] = exp
;
4466 copy_rtx_unchanging (rtx orig
)
4468 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4471 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4475 /* Determine if an insn has a constant number of delay slots, i.e., the
4476 number of delay slots is not a function of the length of the insn. */
4479 write_const_num_delay_slots (void)
4481 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4482 struct attr_value
*av
;
4486 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4488 printf (" switch (recog_memoized (insn))\n");
4491 for (av
= attr
->first_value
; av
; av
= av
->next
)
4494 walk_attr_value (av
->value
);
4496 write_insn_cases (av
->first_insn
, 4);
4499 printf (" default:\n");
4500 printf (" return 1;\n");
4501 printf (" }\n}\n\n");
4505 /* Synthetic attributes used by insn-automata.c and the scheduler.
4506 These are primarily concerned with (define_insn_reservation)
4511 struct insn_reserv
*next
;
4514 int default_latency
;
4517 /* Sequence number of this insn. */
4520 /* Whether a (define_bypass) construct names this insn in its
4525 static struct insn_reserv
*all_insn_reservs
= 0;
4526 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4527 static size_t n_insn_reservs
;
4529 /* Store information from a DEFINE_INSN_RESERVATION for future
4530 attribute generation. */
4532 gen_insn_reserv (rtx def
)
4534 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4536 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4537 decl
->default_latency
= XINT (def
, 1);
4538 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4539 decl
->insn_num
= n_insn_reservs
;
4540 decl
->bypassed
= false;
4543 *last_insn_reserv_p
= decl
;
4544 last_insn_reserv_p
= &decl
->next
;
4548 /* Store information from a DEFINE_BYPASS for future attribute
4549 generation. The only thing we care about is the list of output
4550 insns, which will later be used to tag reservation structures with
4551 a 'bypassed' bit. */
4555 struct bypass_list
*next
;
4559 static struct bypass_list
*all_bypasses
;
4560 static size_t n_bypasses
;
4563 gen_bypass_1 (const char *s
, size_t len
)
4565 struct bypass_list
*b
;
4570 s
= attr_string (s
, len
);
4571 for (b
= all_bypasses
; b
; b
= b
->next
)
4573 return; /* already got that one */
4575 b
= oballoc (struct bypass_list
);
4577 b
->next
= all_bypasses
;
4583 gen_bypass (rtx def
)
4585 const char *p
, *base
;
4587 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4590 gen_bypass_1 (base
, p
- base
);
4593 while (ISSPACE (*p
));
4596 gen_bypass_1 (base
, p
- base
);
4599 /* Find and mark all of the bypassed insns. */
4601 process_bypasses (void)
4603 struct bypass_list
*b
;
4604 struct insn_reserv
*r
;
4606 /* The reservation list is likely to be much longer than the bypass
4608 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4609 for (b
= all_bypasses
; b
; b
= b
->next
)
4610 if (r
->name
== b
->insn
)
4614 /* Check that attribute NAME is used in define_insn_reservation condition
4615 EXP. Return true if it is. */
4617 check_tune_attr (const char *name
, rtx exp
)
4619 switch (GET_CODE (exp
))
4622 if (check_tune_attr (name
, XEXP (exp
, 0)))
4624 return check_tune_attr (name
, XEXP (exp
, 1));
4627 return (check_tune_attr (name
, XEXP (exp
, 0))
4628 && check_tune_attr (name
, XEXP (exp
, 1)));
4631 return XSTR (exp
, 0) == name
;
4638 /* Try to find a const attribute (usually cpu or tune) that is used
4639 in all define_insn_reservation conditions. */
4640 static struct attr_desc
*
4641 find_tune_attr (rtx exp
)
4643 struct attr_desc
*attr
;
4645 switch (GET_CODE (exp
))
4649 attr
= find_tune_attr (XEXP (exp
, 0));
4652 return find_tune_attr (XEXP (exp
, 1));
4655 if (XSTR (exp
, 0) == alternative_name
)
4658 attr
= find_attr (&XSTR (exp
, 0), 0);
4661 if (attr
->is_const
&& !attr
->is_special
)
4663 struct insn_reserv
*decl
;
4665 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4666 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4677 /* Create all of the attributes that describe automaton properties. */
4679 make_automaton_attrs (void)
4682 struct insn_reserv
*decl
;
4683 rtx code_exp
, lats_exp
, byps_exp
;
4684 struct attr_desc
*tune_attr
;
4686 if (n_insn_reservs
== 0)
4689 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4690 if (tune_attr
!= NULL
)
4692 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4693 struct attr_value
*val
;
4696 gcc_assert (tune_attr
->is_const
4697 && !tune_attr
->is_special
4698 && !tune_attr
->is_numeric
);
4699 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4701 if (val
== tune_attr
->default_val
)
4703 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4704 printf ("static int internal_dfa_insn_code_%s (rtx);\n"
4705 "static int insn_default_latency_%s (rtx);\n",
4706 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4710 printf ("int (*internal_dfa_insn_code) (rtx);\n");
4711 printf ("int (*insn_default_latency) (rtx);\n");
4714 printf ("init_sched_attrs (void)\n");
4717 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4721 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
4723 if (val
== tune_attr
->default_val
)
4725 for (decl
= all_insn_reservs
, i
= 0;
4731 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
4732 if (condexp
== false_rtx
)
4734 if (condexp
== true_rtx
)
4736 condexps
[i
] = condexp
;
4737 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
4738 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
4742 code_exp
= rtx_alloc (COND
);
4743 lats_exp
= rtx_alloc (COND
);
4746 XVEC (code_exp
, 0) = rtvec_alloc (j
);
4747 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
4751 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
4752 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
4756 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4757 XEXP (lats_exp
, 1) = make_numeric_value (0);
4764 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
4765 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
4767 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
4768 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
4771 name
= XNEWVEC (char,
4772 sizeof ("*internal_dfa_insn_code_")
4773 + strlen (XSTR (val
->value
, 0)));
4774 strcpy (name
, "*internal_dfa_insn_code_");
4775 strcat (name
, XSTR (val
->value
, 0));
4776 make_internal_attr (name
, code_exp
, ATTR_NONE
);
4777 strcpy (name
, "*insn_default_latency_");
4778 strcat (name
, XSTR (val
->value
, 0));
4779 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
4788 printf (" else if (");
4789 write_test_expr (test
, 0, 0);
4792 printf (" internal_dfa_insn_code\n");
4793 printf (" = internal_dfa_insn_code_%s;\n",
4794 XSTR (val
->value
, 0));
4795 printf (" insn_default_latency\n");
4796 printf (" = insn_default_latency_%s;\n",
4797 XSTR (val
->value
, 0));
4802 printf (" gcc_unreachable ();\n");
4806 XDELETEVEC (condexps
);
4810 code_exp
= rtx_alloc (COND
);
4811 lats_exp
= rtx_alloc (COND
);
4813 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4814 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4816 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4817 XEXP (lats_exp
, 1) = make_numeric_value (0);
4819 for (decl
= all_insn_reservs
, i
= 0;
4821 decl
= decl
->next
, i
+= 2)
4823 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
4824 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
4826 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
4827 XVECEXP (lats_exp
, 0, i
+1)
4828 = make_numeric_value (decl
->default_latency
);
4830 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
4831 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
4834 if (n_bypasses
== 0)
4835 byps_exp
= make_numeric_value (0);
4838 process_bypasses ();
4840 byps_exp
= rtx_alloc (COND
);
4841 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypasses
* 2);
4842 XEXP (byps_exp
, 1) = make_numeric_value (0);
4843 for (decl
= all_insn_reservs
, i
= 0;
4848 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
4849 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
4854 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
4858 main (int argc
, char **argv
)
4861 struct attr_desc
*attr
;
4862 struct insn_def
*id
;
4866 progname
= "genattrtab";
4868 if (!init_rtx_reader_args (argc
, argv
))
4869 return (FATAL_EXIT_CODE
);
4871 obstack_init (hash_obstack
);
4872 obstack_init (temp_obstack
);
4874 /* Set up true and false rtx's */
4875 true_rtx
= rtx_alloc (CONST_INT
);
4876 XWINT (true_rtx
, 0) = 1;
4877 false_rtx
= rtx_alloc (CONST_INT
);
4878 XWINT (false_rtx
, 0) = 0;
4879 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4880 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4882 alternative_name
= DEF_ATTR_STRING ("alternative");
4883 length_str
= DEF_ATTR_STRING ("length");
4884 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4885 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4886 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4888 printf ("/* Generated automatically by the program `genattrtab'\n\
4889 from the machine description file `md'. */\n\n");
4891 /* Read the machine description. */
4897 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4901 switch (GET_CODE (desc
))
4904 case DEFINE_PEEPHOLE
:
4905 case DEFINE_ASM_ATTRIBUTES
:
4906 gen_insn (desc
, lineno
);
4910 case DEFINE_ENUM_ATTR
:
4911 gen_attr (desc
, lineno
);
4915 gen_delay (desc
, lineno
);
4918 case DEFINE_INSN_RESERVATION
:
4919 gen_insn_reserv (desc
);
4929 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4930 insn_index_number
++;
4934 return FATAL_EXIT_CODE
;
4938 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4939 if (! got_define_asm_attributes
)
4941 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4942 XVEC (tem
, 0) = rtvec_alloc (0);
4946 /* Expand DEFINE_DELAY information into new attribute. */
4950 printf ("#include \"config.h\"\n");
4951 printf ("#include \"system.h\"\n");
4952 printf ("#include \"coretypes.h\"\n");
4953 printf ("#include \"tm.h\"\n");
4954 printf ("#include \"rtl.h\"\n");
4955 printf ("#include \"insn-attr.h\"\n");
4956 printf ("#include \"tm_p.h\"\n");
4957 printf ("#include \"insn-config.h\"\n");
4958 printf ("#include \"recog.h\"\n");
4959 printf ("#include \"regs.h\"\n");
4960 printf ("#include \"output.h\"\n");
4961 printf ("#include \"diagnostic-core.h\"\n");
4962 printf ("#include \"flags.h\"\n");
4963 printf ("#include \"function.h\"\n");
4965 printf ("#define operands recog_data.operand\n\n");
4967 /* Make `insn_alternatives'. */
4968 insn_alternatives
= oballocvec (int, insn_code_number
);
4969 for (id
= defs
; id
; id
= id
->next
)
4970 if (id
->insn_code
>= 0)
4971 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4973 /* Make `insn_n_alternatives'. */
4974 insn_n_alternatives
= oballocvec (int, insn_code_number
);
4975 for (id
= defs
; id
; id
= id
->next
)
4976 if (id
->insn_code
>= 0)
4977 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4979 /* Construct extra attributes for automata. */
4980 make_automaton_attrs ();
4982 /* Prepare to write out attribute subroutines by checking everything stored
4983 away and building the attribute cases. */
4987 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4988 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4989 attr
->default_val
->value
4990 = check_attr_value (attr
->default_val
->value
, attr
);
4993 return FATAL_EXIT_CODE
;
4995 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4996 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4999 /* Construct extra attributes for `length'. */
5000 make_length_attrs ();
5002 /* Perform any possible optimizations to speed up compilation. */
5005 /* Now write out all the `gen_attr_...' routines. Do these before the
5006 special routines so that they get defined before they are used. */
5008 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5009 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5011 if (! attr
->is_special
&& ! attr
->is_const
)
5012 write_attr_get (attr
);
5015 /* Write out delay eligibility information, if DEFINE_DELAY present.
5016 (The function to compute the number of delay slots will be written
5020 write_eligible_delay ("delay");
5021 if (have_annul_true
)
5022 write_eligible_delay ("annul_true");
5023 if (have_annul_false
)
5024 write_eligible_delay ("annul_false");
5027 /* Write out constant delay slot info. */
5028 write_const_num_delay_slots ();
5030 write_length_unit_log ();
5033 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);