1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991-2016 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This program handles insn attributes and the DEFINE_DELAY and
22 DEFINE_INSN_RESERVATION definitions.
24 It produces a series of functions named `get_attr_...', one for each insn
25 attribute. Each of these is given the rtx for an insn and returns a member
26 of the enum for the attribute.
28 These subroutines have the form of a `switch' on the INSN_CODE (via
29 `recog_memoized'). Each case either returns a constant attribute value
30 or a value that depends on tests on other attributes, the form of
31 operands, or some random C expression (encoded with a SYMBOL_REF
34 If the attribute `alternative', or a random C expression is present,
35 `constrain_operands' is called. If either of these cases of a reference to
36 an operand is found, `extract_insn' is called.
38 The special attribute `length' is also recognized. For this operand,
39 expressions involving the address of an operand or the current insn,
40 (address (pc)), are valid. In this case, an initial pass is made to
41 set all lengths that do not depend on address. Those that do are set to
42 the maximum length. Then each insn that depends on an address is checked
43 and possibly has its length changed. The process repeats until no further
44 changed are made. The resulting lengths are saved for use by
47 A special form of DEFINE_ATTR, where the expression for default value is a
48 CONST expression, indicates an attribute that is constant for a given run
49 of the compiler. The subroutine generated for these attributes has no
50 parameters as it does not depend on any particular insn. Constant
51 attributes are typically used to specify which variety of processor is
54 Internal attributes are defined to handle DEFINE_DELAY and
55 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
57 This program works by keeping a list of possible values for each attribute.
58 These include the basic attribute choices, default values for attribute, and
59 all derived quantities.
61 As the description file is read, the definition for each insn is saved in a
62 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
63 is created for each insn and chained to the corresponding attribute value,
64 either that specified, or the default.
66 An optimization phase is then run. This simplifies expressions for each
67 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
68 indicates when the attribute has the specified value for the insn. This
69 avoids recursive calls during compilation.
71 The strategy used when processing DEFINE_DELAY definitions is to create
72 arbitrarily complex expressions and have the optimization simplify them.
74 Once optimization is complete, any required routines and definitions
77 An optimization that is not yet implemented is to hoist the constant
78 expressions entirely out of the routines and definitions that are written.
79 A way to do this is to iterate over all possible combinations of values
80 for constant attributes and generate a set of functions for that given
81 combination. An initialization function would be written that evaluates
82 the attributes and installs the corresponding set of routines and
83 definitions (each would be accessed through a pointer).
85 We use the flags in an RTX as follows:
86 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
87 independent of the insn code.
88 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
89 for the insn code currently being processed (see optimize_attrs).
90 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
93 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), unchanging))
94 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), in_struct))
95 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG ((RTX), return_val))
98 #define strcmp_check(S1, S2) ((S1) == (S2) \
100 : (gcc_assert (strcmp ((S1), (S2))), 1))
102 #define strcmp_check(S1, S2) ((S1) != (S2))
107 #include "coretypes.h"
113 #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 file_location loc
; /* Where in the .md files it occurs. */
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 file_location loc
; /* Where in the .md files it occurs. */
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 file_location loc
; /* Where in the .md files it occurs. */
192 int num
; /* Number of DEFINE_DELAY, starting at 1. */
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_index_number
;
215 static int got_define_asm_attributes
;
216 static int must_extract
;
217 static int must_constrain
;
218 static int address_used
;
219 static int length_used
;
220 static int num_delays
;
221 static int have_annul_true
, have_annul_false
;
222 static int num_insn_ents
;
224 /* Stores, for each insn code, the number of constraint alternatives. */
226 static int *insn_n_alternatives
;
228 /* Stores, for each insn code, a bitmap that has bits on for each possible
231 static uint64_t *insn_alternatives
;
233 /* Used to simplify expressions. */
235 static rtx true_rtx
, false_rtx
;
237 /* Used to reduce calls to `strcmp' */
239 static const char *alternative_name
;
240 static const char *length_str
;
241 static const char *delay_type_str
;
242 static const char *delay_1_0_str
;
243 static const char *num_delay_slots_str
;
245 /* Simplify an expression. Only call the routine if there is something to
247 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
248 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
249 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
251 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
253 /* Forward declarations of functions used before their definitions, only. */
254 static char *attr_string (const char *, int);
255 static char *attr_printf (unsigned int, const char *, ...)
257 static rtx
make_numeric_value (int);
258 static struct attr_desc
*find_attr (const char **, int);
259 static rtx
mk_attr_alt (uint64_t);
260 static char *next_comma_elt (const char **);
261 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
262 static rtx
copy_boolean (rtx
);
263 static int compares_alternatives_p (rtx
);
264 static void make_internal_attr (const char *, rtx
, int);
265 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
266 static void walk_attr_value (rtx
);
267 static int max_attr_value (rtx
, int*);
268 static int min_attr_value (rtx
, int*);
269 static int or_attr_value (rtx
, int*);
270 static rtx
simplify_test_exp (rtx
, int, int);
271 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
272 static rtx
copy_rtx_unchanging (rtx
);
273 static bool attr_alt_subset_p (rtx
, rtx
);
274 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
275 static void clear_struct_flag (rtx
);
276 static void write_attr_valueq (FILE *, struct attr_desc
*, const char *);
277 static struct attr_value
*find_most_used (struct attr_desc
*);
278 static void write_attr_set (FILE *, struct attr_desc
*, int, rtx
,
279 const char *, const char *, rtx
,
280 int, int, unsigned int);
281 static void write_attr_case (FILE *, struct attr_desc
*,
283 int, const char *, const char *, int, rtx
);
284 static void write_attr_value (FILE *, struct attr_desc
*, rtx
);
285 static void write_upcase (FILE *, const char *);
286 static void write_indent (FILE *, 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 /* This gen* file is unique, in that it writes out multiple files.
298 Before GCC 4.8, insn-attrtab.c was written out containing many large
299 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
300 a parallel build, and even made it impossible to build GCC on machines
301 with relatively small RAM space (PR other/29442). Therefore, the
302 atrribute functions/tables are now written out to three separate
303 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
304 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
305 rest goes to ATTR_FILE_NAME. */
307 static const char *attr_file_name
= NULL
;
308 static const char *dfa_file_name
= NULL
;
309 static const char *latency_file_name
= NULL
;
311 static FILE *attr_file
, *dfa_file
, *latency_file
;
313 /* Hash table for sharing RTL and strings. */
315 /* Each hash table slot is a bucket containing a chain of these structures.
316 Strings are given negative hash codes; RTL expressions are given positive
321 struct attr_hash
*next
; /* Next structure in the bucket. */
322 unsigned int hashcode
; /* Hash code of this rtx or string. */
325 char *str
; /* The string (negative hash codes) */
326 rtx rtl
; /* or the RTL recorded here. */
330 /* Now here is the hash table. When recording an RTL, it is added to
331 the slot whose index is the hash code mod the table size. Note
332 that the hash table is used for several kinds of RTL (see attr_rtx)
333 and for strings. While all these live in the same table, they are
334 completely independent, and the hash code is computed differently
337 #define RTL_HASH_SIZE 4093
338 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
340 /* Here is how primitive or already-shared RTL's hash
342 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
344 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
347 attr_hash_add_rtx (unsigned int hashcode
, rtx rtl
)
351 h
= XOBNEW (hash_obstack
, struct attr_hash
);
352 h
->hashcode
= hashcode
;
354 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
355 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
358 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
361 attr_hash_add_string (unsigned int hashcode
, char *str
)
365 h
= XOBNEW (hash_obstack
, struct attr_hash
);
366 h
->hashcode
= -hashcode
;
368 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
369 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
372 /* Generate an RTL expression, but avoid duplicates.
373 Set the ATTR_PERMANENT_P flag for these permanent objects.
375 In some cases we cannot uniquify; then we return an ordinary
376 impermanent rtx with ATTR_PERMANENT_P clear.
380 rtx attr_rtx (code, [element1, ..., elementn]) */
383 attr_rtx_1 (enum rtx_code code
, va_list p
)
385 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
386 unsigned int hashcode
;
388 struct obstack
*old_obstack
= rtl_obstack
;
390 /* For each of several cases, search the hash table for an existing entry.
391 Use that entry if one is found; otherwise create a new RTL and add it
394 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
396 rtx arg0
= va_arg (p
, rtx
);
398 /* A permanent object cannot point to impermanent ones. */
399 if (! ATTR_PERMANENT_P (arg0
))
401 rt_val
= rtx_alloc (code
);
402 XEXP (rt_val
, 0) = arg0
;
406 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
407 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
408 if (h
->hashcode
== hashcode
409 && GET_CODE (h
->u
.rtl
) == code
410 && XEXP (h
->u
.rtl
, 0) == arg0
)
415 rtl_obstack
= hash_obstack
;
416 rt_val
= rtx_alloc (code
);
417 XEXP (rt_val
, 0) = arg0
;
420 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
421 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
422 || GET_RTX_CLASS (code
) == RTX_COMPARE
423 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
425 rtx arg0
= va_arg (p
, rtx
);
426 rtx arg1
= va_arg (p
, rtx
);
428 /* A permanent object cannot point to impermanent ones. */
429 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
431 rt_val
= rtx_alloc (code
);
432 XEXP (rt_val
, 0) = arg0
;
433 XEXP (rt_val
, 1) = arg1
;
437 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
438 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
439 if (h
->hashcode
== hashcode
440 && GET_CODE (h
->u
.rtl
) == code
441 && XEXP (h
->u
.rtl
, 0) == arg0
442 && XEXP (h
->u
.rtl
, 1) == arg1
)
447 rtl_obstack
= hash_obstack
;
448 rt_val
= rtx_alloc (code
);
449 XEXP (rt_val
, 0) = arg0
;
450 XEXP (rt_val
, 1) = arg1
;
453 else if (code
== SYMBOL_REF
454 || (GET_RTX_LENGTH (code
) == 1
455 && GET_RTX_FORMAT (code
)[0] == 's'))
457 char *arg0
= va_arg (p
, char *);
459 arg0
= DEF_ATTR_STRING (arg0
);
461 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
462 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
463 if (h
->hashcode
== hashcode
464 && GET_CODE (h
->u
.rtl
) == code
465 && XSTR (h
->u
.rtl
, 0) == arg0
)
470 rtl_obstack
= hash_obstack
;
471 rt_val
= rtx_alloc (code
);
472 XSTR (rt_val
, 0) = arg0
;
473 if (code
== SYMBOL_REF
)
474 X0EXP (rt_val
, 1) = NULL_RTX
;
477 else if (GET_RTX_LENGTH (code
) == 2
478 && GET_RTX_FORMAT (code
)[0] == 's'
479 && GET_RTX_FORMAT (code
)[1] == 's')
481 char *arg0
= va_arg (p
, char *);
482 char *arg1
= va_arg (p
, char *);
484 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
485 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
486 if (h
->hashcode
== hashcode
487 && GET_CODE (h
->u
.rtl
) == code
488 && XSTR (h
->u
.rtl
, 0) == arg0
489 && XSTR (h
->u
.rtl
, 1) == arg1
)
494 rtl_obstack
= hash_obstack
;
495 rt_val
= rtx_alloc (code
);
496 XSTR (rt_val
, 0) = arg0
;
497 XSTR (rt_val
, 1) = arg1
;
500 else if (code
== CONST_INT
)
502 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
512 int i
; /* Array indices... */
513 const char *fmt
; /* Current rtx's format... */
515 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
517 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
518 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
522 case '0': /* Unused field. */
525 case 'i': /* An integer? */
526 XINT (rt_val
, i
) = va_arg (p
, int);
529 case 'w': /* A wide integer? */
530 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
533 case 's': /* A string? */
534 XSTR (rt_val
, i
) = va_arg (p
, char *);
537 case 'e': /* An expression? */
538 case 'u': /* An insn? Same except when printing. */
539 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
542 case 'E': /* An RTX vector? */
543 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
553 rtl_obstack
= old_obstack
;
554 attr_hash_add_rtx (hashcode
, rt_val
);
555 ATTR_PERMANENT_P (rt_val
) = 1;
560 attr_rtx (enum rtx_code code
, ...)
566 result
= attr_rtx_1 (code
, p
);
571 /* Create a new string printed with the printf line arguments into a space
572 of at most LEN bytes:
574 rtx attr_printf (len, format, [arg1, ..., argn]) */
577 attr_printf (unsigned int len
, const char *fmt
, ...)
584 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
586 vsprintf (str
, fmt
, p
);
589 return DEF_ATTR_STRING (str
);
593 attr_eq (const char *name
, const char *value
)
595 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
601 return XSTR (make_numeric_value (n
), 0);
604 /* Return a permanent (possibly shared) copy of a string STR (not assumed
605 to be null terminated) with LEN bytes. */
608 attr_string (const char *str
, int len
)
611 unsigned int hashcode
;
615 /* Compute the hash code. */
616 hashcode
= (len
+ 1) * 613U + (unsigned) str
[0];
617 for (i
= 1; i
< len
; i
+= 2)
618 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
619 if ((int) hashcode
< 0)
620 hashcode
= -hashcode
;
622 /* Search the table for the string. */
623 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
624 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
625 && !strncmp (h
->u
.str
, str
, len
))
626 return h
->u
.str
; /* <-- return if found. */
628 /* Not found; create a permanent copy and add it to the hash table. */
629 new_str
= XOBNEWVAR (hash_obstack
, char, len
+ 1);
630 memcpy (new_str
, str
, len
);
632 attr_hash_add_string (hashcode
, new_str
);
633 copy_md_ptr_loc (new_str
, str
);
635 return new_str
; /* Return the new string. */
638 /* Check two rtx's for equality of contents,
639 taking advantage of the fact that if both are hashed
640 then they can't be equal unless they are the same object. */
643 attr_equal_p (rtx x
, rtx y
)
645 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
646 && rtx_equal_p (x
, y
)));
649 /* Copy an attribute value expression,
650 descending to all depths, but not copying any
651 permanent hashed subexpressions. */
654 attr_copy_rtx (rtx orig
)
659 const char *format_ptr
;
661 /* No need to copy a permanent object. */
662 if (ATTR_PERMANENT_P (orig
))
665 code
= GET_CODE (orig
);
682 copy
= rtx_alloc (code
);
683 PUT_MODE (copy
, GET_MODE (orig
));
684 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
685 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
686 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
688 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
690 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
692 switch (*format_ptr
++)
695 XEXP (copy
, i
) = XEXP (orig
, i
);
696 if (XEXP (orig
, i
) != NULL
)
697 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
702 XVEC (copy
, i
) = XVEC (orig
, i
);
703 if (XVEC (orig
, i
) != NULL
)
705 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
706 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
707 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
713 XINT (copy
, i
) = XINT (orig
, i
);
717 XWINT (copy
, i
) = XWINT (orig
, i
);
722 XSTR (copy
, i
) = XSTR (orig
, i
);
732 /* Given a test expression EXP for attribute ATTR, ensure it is validly
733 formed. LOC is the location of the .md construct that contains EXP.
735 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
736 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
737 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
739 Update the string address in EQ_ATTR expression to be the same used
740 in the attribute (or `alternative_name') to speed up subsequent
741 `find_attr' calls and eliminate most `strcmp' calls.
743 Return the new expression, if any. */
746 check_attr_test (file_location loc
, rtx exp
, attr_desc
*attr
)
748 struct attr_value
*av
;
749 const char *name_ptr
, *p
;
752 switch (GET_CODE (exp
))
755 /* Handle negation test. */
756 if (XSTR (exp
, 1)[0] == '!')
757 return check_attr_test (loc
,
759 attr_eq (XSTR (exp
, 0),
763 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
765 attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
768 if (! strcmp (XSTR (exp
, 0), "alternative"))
769 return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
771 fatal_at (loc
, "unknown attribute `%s' in definition of"
772 " attribute `%s'", XSTR (exp
, 0), attr
->name
);
775 if (attr
->is_const
&& ! attr2
->is_const
)
776 fatal_at (loc
, "constant attribute `%s' cannot test non-constant"
777 " attribute `%s'", attr
->name
, attr2
->name
);
779 /* Copy this just to make it permanent,
780 so expressions using it can be permanent too. */
781 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
783 /* It shouldn't be possible to simplify the value given to a
784 constant attribute, so don't expand this until it's time to
785 write the test expression. */
787 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
789 if (attr2
->is_numeric
)
791 for (p
= XSTR (exp
, 1); *p
; p
++)
793 fatal_at (loc
, "attribute `%s' takes only numeric values",
798 for (av
= attr2
->first_value
; av
; av
= av
->next
)
799 if (GET_CODE (av
->value
) == CONST_STRING
800 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
804 fatal_at (loc
, "unknown value `%s' for attribute `%s'",
805 XSTR (exp
, 1), attr2
->name
);
810 if (! strcmp (XSTR (exp
, 0), "alternative"))
814 name_ptr
= XSTR (exp
, 1);
815 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
816 set
|= ((uint64_t) 1) << atoi (p
);
818 return mk_attr_alt (set
);
822 /* Make an IOR tree of the possible values. */
824 name_ptr
= XSTR (exp
, 1);
825 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
827 newexp
= attr_eq (XSTR (exp
, 0), p
);
828 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
831 return check_attr_test (loc
, orexp
, attr
);
840 /* Either TRUE or FALSE. */
848 XEXP (exp
, 0) = check_attr_test (loc
, XEXP (exp
, 0), attr
);
849 XEXP (exp
, 1) = check_attr_test (loc
, XEXP (exp
, 1), attr
);
853 XEXP (exp
, 0) = check_attr_test (loc
, XEXP (exp
, 0), attr
);
857 exp
= attr_rtx (MATCH_TEST
, XSTR (exp
, 0));
858 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
863 fatal_at (loc
, "invalid operator `%s' in definition of constant"
864 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp
)),
866 /* These cases can't be simplified. */
867 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
870 case LE
: case LT
: case GT
: case GE
:
871 case LEU
: case LTU
: case GTU
: case GEU
:
873 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
874 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
875 exp
= attr_rtx (GET_CODE (exp
),
876 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
877 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
878 /* These cases can't be simplified. */
879 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
885 /* These cases are valid for constant attributes, but can't be
887 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
888 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
893 fatal_at (loc
, "invalid operator `%s' in definition of attribute"
894 " `%s'", GET_RTX_NAME (GET_CODE (exp
)), attr
->name
);
900 /* Given an expression EXP, ensure that it is validly formed and that
901 all named attribute values are valid for ATTR. Issue an error if not.
902 LOC is the location of the .md construct that contains EXP.
904 Return a perhaps modified replacement expression for the value. */
907 check_attr_value (file_location loc
, rtx exp
, struct attr_desc
*attr
)
909 struct attr_value
*av
;
913 switch (GET_CODE (exp
))
916 if (!attr
->is_numeric
)
919 "CONST_INT not valid for non-numeric attribute `%s'",
924 if (INTVAL (exp
) < 0)
927 "negative numeric value specified for attribute `%s'",
934 if (! strcmp (XSTR (exp
, 0), "*"))
937 if (attr
->is_numeric
)
944 "non-numeric value specified for numeric"
945 " attribute `%s'", attr
->name
);
951 for (av
= attr
->first_value
; av
; av
= av
->next
)
952 if (GET_CODE (av
->value
) == CONST_STRING
953 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
957 error_at (loc
, "unknown value `%s' for attribute `%s'",
958 XSTR (exp
, 0), attr
->name
);
962 XEXP (exp
, 0) = check_attr_test (loc
, XEXP (exp
, 0), attr
);
963 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
964 XEXP (exp
, 2) = check_attr_value (loc
, XEXP (exp
, 2), attr
);
972 if (!attr
->is_numeric
)
974 error_at (loc
, "invalid operation `%s' for non-numeric"
975 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp
)),
983 XEXP (exp
, 0) = check_attr_value (loc
, XEXP (exp
, 0), attr
);
984 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
993 XEXP (exp
, 0) = check_attr_value (loc
, XEXP (exp
, 0), attr
);
997 if (XVECLEN (exp
, 0) % 2 != 0)
999 error_at (loc
, "first operand of COND must have even length");
1003 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1005 XVECEXP (exp
, 0, i
) = check_attr_test (attr
->loc
,
1006 XVECEXP (exp
, 0, i
),
1008 XVECEXP (exp
, 0, i
+ 1)
1009 = check_attr_value (loc
, XVECEXP (exp
, 0, i
+ 1), attr
);
1012 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
1017 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1019 error_at (loc
, "unknown attribute `%s' in ATTR",
1021 else if (attr
->is_const
&& ! attr2
->is_const
)
1022 error_at (attr
->loc
,
1023 "constant attribute `%s' cannot refer to non-constant"
1024 " attribute `%s'", attr
->name
, attr2
->name
);
1025 else if (attr
->is_numeric
!= attr2
->is_numeric
)
1027 "numeric attribute mismatch calling `%s' from `%s'",
1028 attr2
->name
, attr
->name
);
1033 /* A constant SYMBOL_REF is valid as a constant attribute test and
1034 is expanded later by make_canonical into a COND. In a non-constant
1035 attribute test, it is left be. */
1036 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1039 error_at (loc
, "invalid operator `%s' in definition of attribute `%s'",
1040 GET_RTX_NAME (GET_CODE (exp
)), attr
->name
);
1047 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1048 It becomes a COND with each test being (eq_attr "alternative" "n") */
1051 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1053 int num_alt
= id
->num_alternatives
;
1057 if (XVECLEN (exp
, 1) != num_alt
)
1059 error_at (id
->loc
, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1060 " was %d expected %d", XVECLEN (exp
, 1), num_alt
);
1064 /* Make a COND with all tests but the last. Select the last value via the
1066 condexp
= rtx_alloc (COND
);
1067 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1069 for (i
= 0; i
< num_alt
- 1; i
++)
1072 p
= attr_numeral (i
);
1074 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1075 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1078 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1080 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1083 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1084 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1087 convert_set_attr (rtx exp
, struct insn_def
*id
)
1090 const char *name_ptr
;
1094 /* See how many alternative specified. */
1095 n
= n_comma_elts (XSTR (exp
, 1));
1097 return attr_rtx (SET
,
1098 attr_rtx (ATTR
, XSTR (exp
, 0)),
1099 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1101 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1102 XSTR (newexp
, 0) = XSTR (exp
, 0);
1103 XVEC (newexp
, 1) = rtvec_alloc (n
);
1105 /* Process each comma-separated name. */
1106 name_ptr
= XSTR (exp
, 1);
1108 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1109 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1111 return convert_set_attr_alternative (newexp
, id
);
1114 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1115 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1121 struct insn_def
*id
;
1122 struct attr_desc
*attr
;
1126 for (id
= defs
; id
; id
= id
->next
)
1128 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1131 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1133 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1134 switch (GET_CODE (value
))
1137 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1139 error_at (id
->loc
, "bad attribute set");
1144 case SET_ATTR_ALTERNATIVE
:
1145 value
= convert_set_attr_alternative (value
, id
);
1149 value
= convert_set_attr (value
, id
);
1153 error_at (id
->loc
, "invalid attribute code %s",
1154 GET_RTX_NAME (GET_CODE (value
)));
1157 if (value
== NULL_RTX
)
1160 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1162 error_at (id
->loc
, "unknown attribute %s",
1163 XSTR (XEXP (value
, 0), 0));
1167 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1168 XEXP (value
, 1) = check_attr_value (id
->loc
, XEXP (value
, 1), attr
);
1173 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1174 expressions by converting them into a COND. This removes cases from this
1175 program. Also, replace an attribute value of "*" with the default attribute
1176 value. LOC is the location to use for error reporting. */
1179 make_canonical (file_location loc
, struct attr_desc
*attr
, rtx exp
)
1184 switch (GET_CODE (exp
))
1187 exp
= make_numeric_value (INTVAL (exp
));
1191 if (! strcmp (XSTR (exp
, 0), "*"))
1193 if (attr
->default_val
== 0)
1194 fatal_at (loc
, "(attr_value \"*\") used in invalid context");
1195 exp
= attr
->default_val
->value
;
1198 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1203 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1205 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1206 This makes the COND something that won't be considered an arbitrary
1207 expression by walk_attr_value. */
1208 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1209 exp
= check_attr_value (loc
, exp
, attr
);
1213 newexp
= rtx_alloc (COND
);
1214 XVEC (newexp
, 0) = rtvec_alloc (2);
1215 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1216 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1218 XEXP (newexp
, 1) = XEXP (exp
, 2);
1221 /* Fall through to COND case since this is now a COND. */
1228 /* First, check for degenerate COND. */
1229 if (XVECLEN (exp
, 0) == 0)
1230 return make_canonical (loc
, attr
, XEXP (exp
, 1));
1231 defval
= XEXP (exp
, 1) = make_canonical (loc
, attr
, XEXP (exp
, 1));
1233 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1235 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1236 XVECEXP (exp
, 0, i
+ 1)
1237 = make_canonical (loc
, attr
, XVECEXP (exp
, 0, i
+ 1));
1238 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1254 copy_boolean (rtx exp
)
1256 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1257 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1258 copy_boolean (XEXP (exp
, 1)));
1259 if (GET_CODE (exp
) == MATCH_OPERAND
)
1261 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1262 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1264 else if (GET_CODE (exp
) == EQ_ATTR
)
1266 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1267 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1273 /* Given a value and an attribute description, return a `struct attr_value *'
1274 that represents that value. This is either an existing structure, if the
1275 value has been previously encountered, or a newly-created structure.
1277 `insn_code' is the code of an insn whose attribute has the specified
1278 value (-2 if not processing an insn). We ensure that all insns for
1279 a given value have the same number of alternatives if the value checks
1280 alternatives. LOC is the location to use for error reporting. */
1282 static struct attr_value
*
1283 get_attr_value (file_location loc
, rtx value
, struct attr_desc
*attr
,
1286 struct attr_value
*av
;
1287 uint64_t num_alt
= 0;
1289 value
= make_canonical (loc
, attr
, value
);
1290 if (compares_alternatives_p (value
))
1292 if (insn_code
< 0 || insn_alternatives
== NULL
)
1293 fatal_at (loc
, "(eq_attr \"alternatives\" ...) used in non-insn"
1296 num_alt
= insn_alternatives
[insn_code
];
1299 for (av
= attr
->first_value
; av
; av
= av
->next
)
1300 if (rtx_equal_p (value
, av
->value
)
1301 && (num_alt
== 0 || av
->first_insn
== NULL
1302 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1305 av
= oballoc (struct attr_value
);
1307 av
->next
= attr
->first_value
;
1308 attr
->first_value
= av
;
1309 av
->first_insn
= NULL
;
1311 av
->has_asm_insn
= 0;
1316 /* After all DEFINE_DELAYs have been read in, create internal attributes
1317 to generate the required routines.
1319 First, we compute the number of delay slots for each insn (as a COND of
1320 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1321 delay type is specified, we compute a similar function giving the
1322 DEFINE_DELAY ordinal for each insn.
1324 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1325 tells whether a given insn can be in that delay slot.
1327 Normal attribute filling and optimization expands these to contain the
1328 information needed to handle delay slots. */
1331 expand_delays (void)
1333 struct delay_desc
*delay
;
1339 /* First, generate data for `num_delay_slots' function. */
1341 condexp
= rtx_alloc (COND
);
1342 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1343 XEXP (condexp
, 1) = make_numeric_value (0);
1345 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1347 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1348 XVECEXP (condexp
, 0, i
+ 1)
1349 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1352 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1354 /* If more than one delay type, do the same for computing the delay type. */
1357 condexp
= rtx_alloc (COND
);
1358 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1359 XEXP (condexp
, 1) = make_numeric_value (0);
1361 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1363 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1364 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1367 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1370 /* For each delay possibility and delay slot, compute an eligibility
1371 attribute for non-annulled insns and for each type of annulled (annul
1372 if true and annul if false). */
1373 for (delay
= delays
; delay
; delay
= delay
->next
)
1375 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1377 condexp
= XVECEXP (delay
->def
, 1, i
);
1379 condexp
= false_rtx
;
1380 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1381 make_numeric_value (1), make_numeric_value (0));
1383 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1384 "*delay_%d_%d", delay
->num
, i
/ 3);
1385 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1387 if (have_annul_true
)
1389 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1390 if (condexp
== 0) condexp
= false_rtx
;
1391 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1392 make_numeric_value (1),
1393 make_numeric_value (0));
1394 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1395 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1396 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1399 if (have_annul_false
)
1401 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1402 if (condexp
== 0) condexp
= false_rtx
;
1403 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1404 make_numeric_value (1),
1405 make_numeric_value (0));
1406 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1407 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1408 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1414 /* Once all attributes and insns have been read and checked, we construct for
1415 each attribute value a list of all the insns that have that value for
1419 fill_attr (struct attr_desc
*attr
)
1421 struct attr_value
*av
;
1422 struct insn_ent
*ie
;
1423 struct insn_def
*id
;
1427 /* Don't fill constant attributes. The value is independent of
1428 any particular insn. */
1432 for (id
= defs
; id
; id
= id
->next
)
1434 /* If no value is specified for this insn for this attribute, use the
1437 if (XVEC (id
->def
, id
->vec_idx
))
1438 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1439 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1441 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1444 av
= attr
->default_val
;
1446 av
= get_attr_value (id
->loc
, value
, attr
, id
->insn_code
);
1448 ie
= oballoc (struct insn_ent
);
1450 insert_insn_ent (av
, ie
);
1454 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1455 test that checks relative positions of insns (uses MATCH_DUP or PC).
1456 If so, replace it with what is obtained by passing the expression to
1457 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1458 recursively on each value (including the default value). Otherwise,
1459 return the value returned by NO_ADDRESS_FN applied to EXP. */
1462 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1463 rtx (*address_fn
) (rtx
))
1468 if (GET_CODE (exp
) == COND
)
1470 /* See if any tests use addresses. */
1472 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1473 walk_attr_value (XVECEXP (exp
, 0, i
));
1476 return (*address_fn
) (exp
);
1478 /* Make a new copy of this COND, replacing each element. */
1479 newexp
= rtx_alloc (COND
);
1480 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1481 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1483 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1484 XVECEXP (newexp
, 0, i
+ 1)
1485 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1486 no_address_fn
, address_fn
);
1489 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1490 no_address_fn
, address_fn
);
1495 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1498 walk_attr_value (XEXP (exp
, 0));
1500 return (*address_fn
) (exp
);
1502 return attr_rtx (IF_THEN_ELSE
,
1503 substitute_address (XEXP (exp
, 0),
1504 no_address_fn
, address_fn
),
1505 substitute_address (XEXP (exp
, 1),
1506 no_address_fn
, address_fn
),
1507 substitute_address (XEXP (exp
, 2),
1508 no_address_fn
, address_fn
));
1511 return (*no_address_fn
) (exp
);
1514 /* Make new attributes from the `length' attribute. The following are made,
1515 each corresponding to a function called from `shorten_branches' or
1518 *insn_default_length This is the length of the insn to be returned
1519 by `get_attr_length' before `shorten_branches'
1520 has been called. In each case where the length
1521 depends on relative addresses, the largest
1522 possible is used. This routine is also used
1523 to compute the initial size of the insn.
1525 *insn_variable_length_p This returns 1 if the insn's length depends
1526 on relative addresses, zero otherwise.
1528 *insn_current_length This is only called when it is known that the
1529 insn has a variable length and returns the
1530 current length, based on relative addresses.
1534 make_length_attrs (void)
1536 static const char *new_names
[] =
1538 "*insn_default_length",
1540 "*insn_variable_length_p",
1541 "*insn_current_length"
1543 static rtx (*const no_address_fn
[]) (rtx
)
1544 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1545 static rtx (*const address_fn
[]) (rtx
)
1546 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1548 struct attr_desc
*length_attr
, *new_attr
;
1549 struct attr_value
*av
, *new_av
;
1550 struct insn_ent
*ie
, *new_ie
;
1552 /* See if length attribute is defined. If so, it must be numeric. Make
1553 it special so we don't output anything for it. */
1554 length_attr
= find_attr (&length_str
, 0);
1555 if (length_attr
== 0)
1558 if (! length_attr
->is_numeric
)
1559 fatal_at (length_attr
->loc
, "length attribute must be numeric");
1561 length_attr
->is_const
= 0;
1562 length_attr
->is_special
= 1;
1564 /* Make each new attribute, in turn. */
1565 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1567 make_internal_attr (new_names
[i
],
1568 substitute_address (length_attr
->default_val
->value
,
1569 no_address_fn
[i
], address_fn
[i
]),
1571 new_attr
= find_attr (&new_names
[i
], 0);
1572 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1573 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1575 new_av
= get_attr_value (ie
->def
->loc
,
1576 substitute_address (av
->value
,
1579 new_attr
, ie
->def
->insn_code
);
1580 new_ie
= oballoc (struct insn_ent
);
1581 new_ie
->def
= ie
->def
;
1582 insert_insn_ent (new_av
, new_ie
);
1587 /* Utility functions called from above routine. */
1590 identity_fn (rtx exp
)
1596 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1598 return make_numeric_value (0);
1602 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1604 return make_numeric_value (1);
1611 return make_numeric_value (max_attr_value (exp
, &unknown
));
1618 return make_numeric_value (min_attr_value (exp
, &unknown
));
1622 write_length_unit_log (FILE *outf
)
1624 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1625 struct attr_value
*av
;
1626 struct insn_ent
*ie
;
1627 unsigned int length_unit_log
, length_or
;
1632 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1633 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1634 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1635 length_or
|= or_attr_value (av
->value
, &unknown
);
1638 if (length_attr
== NULL
|| unknown
)
1639 length_unit_log
= 0;
1642 length_or
= ~length_or
;
1643 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1646 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1649 /* Compute approximate cost of the expression. Used to decide whether
1650 expression is cheap enough for inline. */
1652 attr_rtx_cost (rtx x
)
1658 code
= GET_CODE (x
);
1671 /* Alternatives don't result into function call. */
1672 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1679 const char *fmt
= GET_RTX_FORMAT (code
);
1680 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1686 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1687 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1690 cost
+= attr_rtx_cost (XEXP (x
, i
));
1700 /* Take a COND expression and see if any of the conditions in it can be
1701 simplified. If any are known true or known false for the particular insn
1702 code, the COND can be further simplified.
1704 Also call ourselves on any COND operations that are values of this COND.
1706 We do not modify EXP; rather, we make and return a new rtx. */
1709 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1712 /* We store the desired contents here,
1713 then build a new expression if they don't match EXP. */
1714 rtx defval
= XEXP (exp
, 1);
1715 rtx new_defval
= XEXP (exp
, 1);
1716 int len
= XVECLEN (exp
, 0);
1717 rtx
*tests
= XNEWVEC (rtx
, len
);
1721 /* This lets us free all storage allocated below, if appropriate. */
1722 obstack_finish (rtl_obstack
);
1724 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1726 /* See if default value needs simplification. */
1727 if (GET_CODE (defval
) == COND
)
1728 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1730 /* Simplify the subexpressions, and see what tests we can get rid of. */
1732 for (i
= 0; i
< len
; i
+= 2)
1734 rtx newtest
, newval
;
1736 /* Simplify this test. */
1737 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1740 newval
= tests
[i
+ 1];
1741 /* See if this value may need simplification. */
1742 if (GET_CODE (newval
) == COND
)
1743 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1745 /* Look for ways to delete or combine this test. */
1746 if (newtest
== true_rtx
)
1748 /* If test is true, make this value the default
1749 and discard this + any following tests. */
1751 defval
= tests
[i
+ 1];
1752 new_defval
= newval
;
1755 else if (newtest
== false_rtx
)
1757 /* If test is false, discard it and its value. */
1758 for (j
= i
; j
< len
- 2; j
++)
1759 tests
[j
] = tests
[j
+ 2];
1764 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1766 /* If this value and the value for the prev test are the same,
1770 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1771 insn_code
, insn_index
);
1773 /* Delete this test/value. */
1774 for (j
= i
; j
< len
- 2; j
++)
1775 tests
[j
] = tests
[j
+ 2];
1781 tests
[i
+ 1] = newval
;
1784 /* If the last test in a COND has the same value
1785 as the default value, that test isn't needed. */
1787 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1790 /* See if we changed anything. */
1791 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1794 for (i
= 0; i
< len
; i
++)
1795 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1803 if (GET_CODE (defval
) == COND
)
1804 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1812 rtx newexp
= rtx_alloc (COND
);
1814 XVEC (newexp
, 0) = rtvec_alloc (len
);
1815 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1816 XEXP (newexp
, 1) = new_defval
;
1823 /* Remove an insn entry from an attribute value. */
1826 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1828 struct insn_ent
*previe
;
1830 if (av
->first_insn
== ie
)
1831 av
->first_insn
= ie
->next
;
1834 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1836 previe
->next
= ie
->next
;
1840 if (ie
->def
->insn_code
== -1)
1841 av
->has_asm_insn
= 0;
1846 /* Insert an insn entry in an attribute value list. */
1849 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1851 ie
->next
= av
->first_insn
;
1852 av
->first_insn
= ie
;
1854 if (ie
->def
->insn_code
== -1)
1855 av
->has_asm_insn
= 1;
1860 /* This is a utility routine to take an expression that is a tree of either
1861 AND or IOR expressions and insert a new term. The new term will be
1862 inserted at the right side of the first node whose code does not match
1863 the root. A new node will be created with the root's code. Its left
1864 side will be the old right side and its right side will be the new
1867 If the `term' is itself a tree, all its leaves will be inserted. */
1870 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1874 /* Avoid consing in some special cases. */
1875 if (code
== AND
&& term
== true_rtx
)
1877 if (code
== AND
&& term
== false_rtx
)
1879 if (code
== AND
&& exp
== true_rtx
)
1881 if (code
== AND
&& exp
== false_rtx
)
1883 if (code
== IOR
&& term
== true_rtx
)
1885 if (code
== IOR
&& term
== false_rtx
)
1887 if (code
== IOR
&& exp
== true_rtx
)
1889 if (code
== IOR
&& exp
== false_rtx
)
1891 if (attr_equal_p (exp
, term
))
1894 if (GET_CODE (term
) == code
)
1896 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1897 insn_code
, insn_index
);
1898 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1899 insn_code
, insn_index
);
1904 if (GET_CODE (exp
) == code
)
1906 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1907 term
, insn_code
, insn_index
);
1908 if (new_rtx
!= XEXP (exp
, 1))
1909 /* Make a copy of this expression and call recursively. */
1910 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1916 /* Insert the new term. */
1917 newexp
= attr_rtx (code
, exp
, term
);
1920 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1923 /* If we have an expression which AND's a bunch of
1924 (not (eq_attrq "alternative" "n"))
1925 terms, we may have covered all or all but one of the possible alternatives.
1926 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1928 This routine is passed an expression and either AND or IOR. It returns a
1929 bitmask indicating which alternatives are mentioned within EXP. */
1932 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1935 if (GET_CODE (exp
) == code
)
1936 return compute_alternative_mask (XEXP (exp
, 0), code
)
1937 | compute_alternative_mask (XEXP (exp
, 1), code
);
1939 else if (code
== AND
&& GET_CODE (exp
) == NOT
1940 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1941 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1942 string
= XSTR (XEXP (exp
, 0), 1);
1944 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1945 && XSTR (exp
, 0) == alternative_name
)
1946 string
= XSTR (exp
, 1);
1948 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1950 if (code
== AND
&& XINT (exp
, 1))
1951 return XINT (exp
, 0);
1953 if (code
== IOR
&& !XINT (exp
, 1))
1954 return XINT (exp
, 0);
1962 return ((uint64_t) 1) << (string
[0] - '0');
1963 return ((uint64_t) 1) << atoi (string
);
1966 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1967 attribute with the value represented by that bit. */
1970 make_alternative_compare (uint64_t mask
)
1972 return mk_attr_alt (mask
);
1975 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1976 of "attr" for this insn code. From that value, we can compute a test
1977 showing when the EQ_ATTR will be true. This routine performs that
1978 computation. If a test condition involves an address, we leave the EQ_ATTR
1979 intact because addresses are only valid for the `length' attribute.
1981 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1982 it refers. VALUE is the value of that attribute for the insn
1983 corresponding to INSN_CODE and INSN_INDEX. */
1986 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1987 int insn_code
, int insn_index
)
1994 while (GET_CODE (value
) == ATTR
)
1996 struct attr_value
*av
= NULL
;
1998 attr
= find_attr (&XSTR (value
, 0), 0);
2000 if (insn_code_values
)
2002 struct attr_value_list
*iv
;
2003 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2004 if (iv
->attr
== attr
)
2012 struct insn_ent
*ie
;
2013 for (av
= attr
->first_value
; av
; av
= av
->next
)
2014 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2015 if (ie
->def
->insn_code
== insn_code
)
2025 switch (GET_CODE (value
))
2028 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2039 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2040 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
2041 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
2042 for (p
= string
; *p
; p
++)
2045 newexp
= attr_rtx (EQ
, value
,
2046 attr_rtx (SYMBOL_REF
,
2047 DEF_ATTR_STRING (string
)));
2052 /* We construct an IOR of all the cases for which the
2053 requested attribute value is present. Since we start with
2054 FALSE, if it is not present, FALSE will be returned.
2056 Each case is the AND of the NOT's of the previous conditions with the
2057 current condition; in the default case the current condition is TRUE.
2059 For each possible COND value, call ourselves recursively.
2061 The extra TRUE and FALSE expressions will be eliminated by another
2062 call to the simplification routine. */
2067 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2069 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2070 insn_code
, insn_index
);
2072 right
= insert_right_side (AND
, andexp
, this_cond
,
2073 insn_code
, insn_index
);
2074 right
= insert_right_side (AND
, right
,
2075 evaluate_eq_attr (exp
, attr
,
2078 insn_code
, insn_index
),
2079 insn_code
, insn_index
);
2080 orexp
= insert_right_side (IOR
, orexp
, right
,
2081 insn_code
, insn_index
);
2083 /* Add this condition into the AND expression. */
2084 newexp
= attr_rtx (NOT
, this_cond
);
2085 andexp
= insert_right_side (AND
, andexp
, newexp
,
2086 insn_code
, insn_index
);
2089 /* Handle the default case. */
2090 right
= insert_right_side (AND
, andexp
,
2091 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2092 insn_code
, insn_index
),
2093 insn_code
, insn_index
);
2094 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2101 /* If uses an address, must return original expression. But set the
2102 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2105 walk_attr_value (newexp
);
2109 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2110 return copy_rtx_unchanging (exp
);
2117 /* This routine is called when an AND of a term with a tree of AND's is
2118 encountered. If the term or its complement is present in the tree, it
2119 can be replaced with TRUE or FALSE, respectively.
2121 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2122 be true and hence are complementary.
2124 There is one special case: If we see
2125 (and (not (eq_attr "att" "v1"))
2126 (eq_attr "att" "v2"))
2127 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2128 replace the term, not anything in the AND tree. So we pass a pointer to
2132 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2137 int left_eliminates_term
, right_eliminates_term
;
2139 if (GET_CODE (exp
) == AND
)
2141 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2142 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2143 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2145 newexp
= attr_rtx (AND
, left
, right
);
2147 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2151 else if (GET_CODE (exp
) == IOR
)
2153 /* For the IOR case, we do the same as above, except that we can
2154 only eliminate `term' if both sides of the IOR would do so. */
2156 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2157 left_eliminates_term
= (temp
== true_rtx
);
2160 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2161 right_eliminates_term
= (temp
== true_rtx
);
2163 if (left_eliminates_term
&& right_eliminates_term
)
2166 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2168 newexp
= attr_rtx (IOR
, left
, right
);
2170 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2174 /* Check for simplifications. Do some extra checking here since this
2175 routine is called so many times. */
2180 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2183 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2186 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2188 if (attr_alt_subset_p (*pterm
, exp
))
2191 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2194 if (attr_alt_subset_p (exp
, *pterm
))
2200 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2202 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2205 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2211 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2212 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2214 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2217 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2223 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2224 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2226 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2229 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2235 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2237 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2241 else if (GET_CODE (exp
) == NOT
)
2243 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2247 else if (GET_CODE (*pterm
) == NOT
)
2249 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2253 else if (attr_equal_p (exp
, *pterm
))
2259 /* Similar to `simplify_and_tree', but for IOR trees. */
2262 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2267 int left_eliminates_term
, right_eliminates_term
;
2269 if (GET_CODE (exp
) == IOR
)
2271 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2272 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2273 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2275 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2277 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2281 else if (GET_CODE (exp
) == AND
)
2283 /* For the AND case, we do the same as above, except that we can
2284 only eliminate `term' if both sides of the AND would do so. */
2286 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2287 left_eliminates_term
= (temp
== false_rtx
);
2290 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2291 right_eliminates_term
= (temp
== false_rtx
);
2293 if (left_eliminates_term
&& right_eliminates_term
)
2296 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2298 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2300 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2304 if (attr_equal_p (exp
, *pterm
))
2307 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2310 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2313 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2314 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2315 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2318 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2319 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2320 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2326 /* Simplify test expression and use temporary obstack in order to avoid
2327 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2328 and avoid unnecessary copying if possible. */
2331 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2334 struct obstack
*old
;
2335 if (ATTR_IND_SIMPLIFIED_P (exp
))
2338 rtl_obstack
= temp_obstack
;
2339 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2341 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2343 return attr_copy_rtx (x
);
2346 /* Returns true if S1 is a subset of S2. */
2349 attr_alt_subset_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));
2363 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2370 /* Returns true if S1 is a subset of complement of S2. */
2373 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2375 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2378 return !(XINT (s1
, 0) & XINT (s2
, 0));
2381 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2384 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2394 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2397 attr_alt_intersection (rtx s1
, rtx s2
)
2399 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2401 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2404 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2407 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2410 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2413 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2418 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2423 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2426 attr_alt_union (rtx s1
, rtx s2
)
2428 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2430 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2433 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2436 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2439 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2442 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2448 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2452 /* Return EQ_ATTR_ALT expression representing complement of S. */
2455 attr_alt_complement (rtx s
)
2457 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2459 XINT (result
, 0) = XINT (s
, 0);
2460 XINT (result
, 1) = 1 - XINT (s
, 1);
2465 /* Return EQ_ATTR_ALT expression representing set containing elements set
2469 mk_attr_alt (uint64_t e
)
2471 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2473 XINT (result
, 0) = e
;
2474 XINT (result
, 1) = 0;
2479 /* Given an expression, see if it can be simplified for a particular insn
2480 code based on the values of other attributes being tested. This can
2481 eliminate nested get_attr_... calls.
2483 Note that if an endless recursion is specified in the patterns, the
2484 optimization will loop. However, it will do so in precisely the cases where
2485 an infinite recursion loop could occur during compilation. It's better that
2489 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2492 struct attr_desc
*attr
;
2493 struct attr_value
*av
;
2494 struct insn_ent
*ie
;
2495 struct attr_value_list
*iv
;
2498 bool left_alt
, right_alt
;
2500 /* Don't re-simplify something we already simplified. */
2501 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2504 switch (GET_CODE (exp
))
2507 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2508 if (left
== false_rtx
)
2510 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2511 if (right
== false_rtx
)
2514 if (GET_CODE (left
) == EQ_ATTR_ALT
2515 && GET_CODE (right
) == EQ_ATTR_ALT
)
2517 exp
= attr_alt_intersection (left
, right
);
2518 return simplify_test_exp (exp
, insn_code
, insn_index
);
2521 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2522 present on both sides, apply the distributive law since this will
2523 yield simplifications. */
2524 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2525 && compute_alternative_mask (left
, IOR
)
2526 && compute_alternative_mask (right
, IOR
))
2528 if (GET_CODE (left
) == IOR
)
2529 std::swap (left
, right
);
2531 newexp
= attr_rtx (IOR
,
2532 attr_rtx (AND
, left
, XEXP (right
, 0)),
2533 attr_rtx (AND
, left
, XEXP (right
, 1)));
2535 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2538 /* Try with the term on both sides. */
2539 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2540 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2541 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2543 if (left
== false_rtx
|| right
== false_rtx
)
2545 else if (left
== true_rtx
)
2549 else if (right
== true_rtx
)
2553 /* See if all or all but one of the insn's alternatives are specified
2554 in this tree. Optimize if so. */
2556 if (GET_CODE (left
) == NOT
)
2557 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2558 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2560 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2563 if (GET_CODE (right
) == NOT
)
2564 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2565 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2567 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2568 && XINT (right
, 1));
2571 && (GET_CODE (left
) == AND
2573 || GET_CODE (right
) == AND
2576 i
= compute_alternative_mask (exp
, AND
);
2577 if (i
& ~insn_alternatives
[insn_code
])
2578 fatal ("invalid alternative specified for pattern number %d",
2581 /* If all alternatives are excluded, this is false. */
2582 i
^= insn_alternatives
[insn_code
];
2585 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2587 /* If just one excluded, AND a comparison with that one to the
2588 front of the tree. The others will be eliminated by
2589 optimization. We do not want to do this if the insn has one
2590 alternative and we have tested none of them! */
2591 left
= make_alternative_compare (i
);
2592 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2593 newexp
= attr_rtx (AND
, left
, right
);
2595 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2599 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2601 newexp
= attr_rtx (AND
, left
, right
);
2602 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2607 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2608 if (left
== true_rtx
)
2610 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2611 if (right
== true_rtx
)
2614 if (GET_CODE (left
) == EQ_ATTR_ALT
2615 && GET_CODE (right
) == EQ_ATTR_ALT
)
2617 exp
= attr_alt_union (left
, right
);
2618 return simplify_test_exp (exp
, insn_code
, insn_index
);
2621 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2622 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2623 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2625 if (right
== true_rtx
|| left
== true_rtx
)
2627 else if (left
== false_rtx
)
2631 else if (right
== false_rtx
)
2636 /* Test for simple cases where the distributive law is useful. I.e.,
2637 convert (ior (and (x) (y))
2643 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2644 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2646 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2648 left
= XEXP (left
, 0);
2650 newexp
= attr_rtx (AND
, left
, right
);
2651 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2655 convert (ior (and (y) (x))
2657 to (and (ior (y) (z))
2659 Note that we want the common term to stay at the end.
2662 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2663 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2665 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2668 right
= XEXP (right
, 1);
2669 newexp
= attr_rtx (AND
, left
, right
);
2670 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2673 /* See if all or all but one of the insn's alternatives are specified
2674 in this tree. Optimize if so. */
2676 else if (insn_code
>= 0
2677 && (GET_CODE (left
) == IOR
2678 || (GET_CODE (left
) == EQ_ATTR_ALT
2680 || (GET_CODE (left
) == EQ_ATTR
2681 && XSTR (left
, 0) == alternative_name
)
2682 || GET_CODE (right
) == IOR
2683 || (GET_CODE (right
) == EQ_ATTR_ALT
2684 && !XINT (right
, 1))
2685 || (GET_CODE (right
) == EQ_ATTR
2686 && XSTR (right
, 0) == alternative_name
)))
2688 i
= compute_alternative_mask (exp
, IOR
);
2689 if (i
& ~insn_alternatives
[insn_code
])
2690 fatal ("invalid alternative specified for pattern number %d",
2693 /* If all alternatives are included, this is true. */
2694 i
^= insn_alternatives
[insn_code
];
2697 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2699 /* If just one excluded, IOR a comparison with that one to the
2700 front of the tree. The others will be eliminated by
2701 optimization. We do not want to do this if the insn has one
2702 alternative and we have tested none of them! */
2703 left
= make_alternative_compare (i
);
2704 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2705 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2707 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2711 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2713 newexp
= attr_rtx (IOR
, left
, right
);
2714 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2719 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2721 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2722 insn_code
, insn_index
);
2726 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2727 if (GET_CODE (left
) == NOT
)
2728 return XEXP (left
, 0);
2730 if (left
== false_rtx
)
2732 if (left
== true_rtx
)
2735 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2737 exp
= attr_alt_complement (left
);
2738 return simplify_test_exp (exp
, insn_code
, insn_index
);
2741 /* Try to apply De`Morgan's laws. */
2742 if (GET_CODE (left
) == IOR
)
2744 newexp
= attr_rtx (AND
,
2745 attr_rtx (NOT
, XEXP (left
, 0)),
2746 attr_rtx (NOT
, XEXP (left
, 1)));
2748 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2750 else if (GET_CODE (left
) == AND
)
2752 newexp
= attr_rtx (IOR
,
2753 attr_rtx (NOT
, XEXP (left
, 0)),
2754 attr_rtx (NOT
, XEXP (left
, 1)));
2756 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2758 else if (left
!= XEXP (exp
, 0))
2760 newexp
= attr_rtx (NOT
, left
);
2766 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2770 if (XSTR (exp
, 0) == alternative_name
)
2772 newexp
= mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
2776 /* Look at the value for this insn code in the specified attribute.
2777 We normally can replace this comparison with the condition that
2778 would give this insn the values being tested for. */
2780 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2785 if (insn_code_values
)
2787 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2788 if (iv
->attr
== attr
)
2796 for (av
= attr
->first_value
; av
; av
= av
->next
)
2797 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2798 if (ie
->def
->insn_code
== insn_code
)
2805 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2806 insn_code
, insn_index
);
2807 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2808 if (attr_rtx_cost (x
) < 7)
2818 /* We have already simplified this expression. Simplifying it again
2819 won't buy anything unless we weren't given a valid insn code
2820 to process (i.e., we are canonicalizing something.). */
2822 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2823 return copy_rtx_unchanging (newexp
);
2828 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2829 otherwise return 0. */
2832 tests_attr_p (rtx p
, struct attr_desc
*attr
)
2837 if (GET_CODE (p
) == EQ_ATTR
)
2839 if (XSTR (p
, 0) != attr
->name
)
2844 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2845 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2846 for (i
= 0; i
< ie
; i
++)
2851 if (tests_attr_p (XEXP (p
, i
), attr
))
2856 je
= XVECLEN (p
, i
);
2857 for (j
= 0; j
< je
; ++j
)
2858 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2867 /* Calculate a topological sorting of all attributes so that
2868 all attributes only depend on attributes in front of it.
2869 Place the result in *RET (which is a pointer to an array of
2870 attr_desc pointers), and return the size of that array. */
2873 get_attr_order (struct attr_desc
***ret
)
2877 struct attr_desc
*attr
;
2878 struct attr_desc
**all
, **sorted
;
2880 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2881 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2883 all
= XNEWVEC (struct attr_desc
*, num
);
2884 sorted
= XNEWVEC (struct attr_desc
*, num
);
2885 handled
= XCNEWVEC (char, num
);
2887 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2888 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2892 for (i
= 0; i
< num
; i
++)
2893 if (all
[i
]->is_const
)
2894 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2896 /* We have only few attributes hence we can live with the inner
2897 loop being O(n^2), unlike the normal fast variants of topological
2901 for (i
= 0; i
< num
; i
++)
2904 /* Let's see if I depends on anything interesting. */
2906 for (k
= 0; k
< num
; k
++)
2909 struct attr_value
*av
;
2910 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2911 if (av
->num_insns
!= 0)
2912 if (tests_attr_p (av
->value
, all
[k
]))
2916 /* Something in I depends on K. */
2921 /* Nothing in I depended on anything intersting, so
2924 sorted
[j
++] = all
[i
];
2930 for (j
= 0; j
< num
; j
++)
2932 struct attr_desc
*attr2
;
2933 struct attr_value
*av
;
2936 fprintf (stderr
, "%s depends on: ", attr
->name
);
2937 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2938 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2939 if (!attr2
->is_const
)
2940 for (av
= attr
->first_value
; av
; av
= av
->next
)
2941 if (av
->num_insns
!= 0)
2942 if (tests_attr_p (av
->value
, attr2
))
2944 fprintf (stderr
, "%s, ", attr2
->name
);
2947 fprintf (stderr
, "\n");
2955 /* Optimize the attribute lists by seeing if we can determine conditional
2956 values from the known values of other attributes. This will save subroutine
2957 calls during the compilation. NUM_INSN_CODES is the number of unique
2958 instruction codes. */
2961 optimize_attrs (int num_insn_codes
)
2963 struct attr_desc
*attr
;
2964 struct attr_value
*av
;
2965 struct insn_ent
*ie
;
2968 struct attr_value_list
*ivbuf
;
2969 struct attr_value_list
*iv
;
2970 struct attr_desc
**topsort
;
2973 /* For each insn code, make a list of all the insn_ent's for it,
2974 for all values for all attributes. */
2976 if (num_insn_ents
== 0)
2979 /* Make 2 extra elements, for "code" values -2 and -1. */
2980 insn_code_values
= XCNEWVEC (struct attr_value_list
*, num_insn_codes
+ 2);
2982 /* Offset the table address so we can index by -2 or -1. */
2983 insn_code_values
+= 2;
2985 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2987 /* Create the chain of insn*attr values such that we see dependend
2988 attributes after their dependencies. As we use a stack via the
2989 next pointers start from the end of the topological order. */
2990 topnum
= get_attr_order (&topsort
);
2991 for (i
= topnum
- 1; i
>= 0; i
--)
2992 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
2993 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2995 iv
->attr
= topsort
[i
];
2998 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2999 insn_code_values
[ie
->def
->insn_code
] = iv
;
3004 /* Sanity check on num_insn_ents. */
3005 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
3007 /* Process one insn code at a time. */
3008 for (i
= -2; i
< num_insn_codes
; i
++)
3010 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3011 We use it to mean "already simplified for this insn". */
3012 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3013 clear_struct_flag (iv
->av
->value
);
3015 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3017 struct obstack
*old
= rtl_obstack
;
3022 if (GET_CODE (av
->value
) != COND
)
3025 rtl_obstack
= temp_obstack
;
3027 while (GET_CODE (newexp
) == COND
)
3029 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
3030 ie
->def
->insn_index
);
3031 if (newexp2
== newexp
)
3037 /* If we created a new value for this instruction, and it's
3038 cheaper than the old value, and overall cheap, use that
3039 one as specific value for the current instruction.
3040 The last test is to avoid exploding the get_attr_ function
3041 sizes for no much gain. */
3042 if (newexp
!= av
->value
3043 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
3044 && attr_rtx_cost (newexp
) < 26
3047 newexp
= attr_copy_rtx (newexp
);
3048 remove_insn_ent (av
, ie
);
3049 av
= get_attr_value (ie
->def
->loc
, newexp
, attr
,
3050 ie
->def
->insn_code
);
3052 insert_insn_ent (av
, ie
);
3058 free (insn_code_values
- 2);
3059 insn_code_values
= NULL
;
3062 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3065 clear_struct_flag (rtx x
)
3072 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3073 if (ATTR_IND_SIMPLIFIED_P (x
))
3076 code
= GET_CODE (x
);
3095 /* Compare the elements. If any pair of corresponding elements
3096 fail to match, return 0 for the whole things. */
3098 fmt
= GET_RTX_FORMAT (code
);
3099 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3105 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3106 clear_struct_flag (XVECEXP (x
, i
, j
));
3110 clear_struct_flag (XEXP (x
, i
));
3116 /* Add attribute value NAME to the beginning of ATTR's list. */
3119 add_attr_value (struct attr_desc
*attr
, const char *name
)
3121 struct attr_value
*av
;
3123 av
= oballoc (struct attr_value
);
3124 av
->value
= attr_rtx (CONST_STRING
, name
);
3125 av
->next
= attr
->first_value
;
3126 attr
->first_value
= av
;
3127 av
->first_insn
= NULL
;
3129 av
->has_asm_insn
= 0;
3132 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3135 gen_attr (md_rtx_info
*info
)
3137 struct enum_type
*et
;
3138 struct enum_value
*ev
;
3139 struct attr_desc
*attr
;
3140 const char *name_ptr
;
3142 rtx def
= info
->def
;
3144 /* Make a new attribute structure. Check for duplicate by looking at
3145 attr->default_val, since it is initialized by this routine. */
3146 attr
= find_attr (&XSTR (def
, 0), 1);
3147 if (attr
->default_val
)
3149 error_at (info
->loc
, "duplicate definition for attribute %s",
3151 message_at (attr
->loc
, "previous definition");
3154 attr
->loc
= info
->loc
;
3156 if (GET_CODE (def
) == DEFINE_ENUM_ATTR
)
3158 attr
->enum_name
= XSTR (def
, 1);
3159 et
= lookup_enum_type (XSTR (def
, 1));
3160 if (!et
|| !et
->md_p
)
3161 error_at (info
->loc
, "No define_enum called `%s' defined",
3164 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3165 add_attr_value (attr
, ev
->name
);
3167 else if (*XSTR (def
, 1) == '\0')
3168 attr
->is_numeric
= 1;
3171 name_ptr
= XSTR (def
, 1);
3172 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3173 add_attr_value (attr
, p
);
3176 if (GET_CODE (XEXP (def
, 2)) == CONST
)
3179 if (attr
->is_numeric
)
3180 error_at (info
->loc
,
3181 "constant attributes may not take numeric values");
3183 /* Get rid of the CONST node. It is allowed only at top-level. */
3184 XEXP (def
, 2) = XEXP (XEXP (def
, 2), 0);
3187 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3188 error_at (info
->loc
, "`length' attribute must take numeric values");
3190 /* Set up the default value. */
3191 XEXP (def
, 2) = check_attr_value (info
->loc
, XEXP (def
, 2), attr
);
3192 attr
->default_val
= get_attr_value (info
->loc
, XEXP (def
, 2), attr
, -2);
3195 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3196 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3197 number of alternatives as this should be checked elsewhere. */
3200 count_alternatives (rtx exp
)
3205 if (GET_CODE (exp
) == MATCH_OPERAND
)
3206 return n_comma_elts (XSTR (exp
, 2));
3208 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3209 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3214 n
= count_alternatives (XEXP (exp
, i
));
3221 if (XVEC (exp
, i
) != NULL
)
3222 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3224 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3233 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3234 `alternative' attribute. */
3237 compares_alternatives_p (rtx exp
)
3242 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3245 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3246 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3251 if (compares_alternatives_p (XEXP (exp
, i
)))
3256 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3257 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3265 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3268 gen_insn (md_rtx_info
*info
)
3270 struct insn_def
*id
;
3271 rtx def
= info
->def
;
3273 id
= oballoc (struct insn_def
);
3277 id
->loc
= info
->loc
;
3279 switch (GET_CODE (def
))
3282 id
->insn_code
= info
->index
;
3283 id
->insn_index
= insn_index_number
;
3284 id
->num_alternatives
= count_alternatives (def
);
3285 if (id
->num_alternatives
== 0)
3286 id
->num_alternatives
= 1;
3290 case DEFINE_PEEPHOLE
:
3291 id
->insn_code
= info
->index
;
3292 id
->insn_index
= insn_index_number
;
3293 id
->num_alternatives
= count_alternatives (def
);
3294 if (id
->num_alternatives
== 0)
3295 id
->num_alternatives
= 1;
3299 case DEFINE_ASM_ATTRIBUTES
:
3301 id
->insn_index
= -1;
3302 id
->num_alternatives
= 1;
3304 got_define_asm_attributes
= 1;
3312 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3313 true or annul false is specified, and make a `struct delay_desc'. */
3316 gen_delay (md_rtx_info
*info
)
3318 struct delay_desc
*delay
;
3321 rtx def
= info
->def
;
3322 if (XVECLEN (def
, 1) % 3 != 0)
3324 error_at (info
->loc
, "number of elements in DEFINE_DELAY must"
3325 " be multiple of three");
3329 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3331 if (XVECEXP (def
, 1, i
+ 1))
3332 have_annul_true
= 1;
3333 if (XVECEXP (def
, 1, i
+ 2))
3334 have_annul_false
= 1;
3337 delay
= oballoc (struct delay_desc
);
3339 delay
->num
= ++num_delays
;
3340 delay
->next
= delays
;
3341 delay
->loc
= info
->loc
;
3345 /* Names of attributes that could be possibly cached. */
3346 static const char *cached_attrs
[32];
3347 /* Number of such attributes. */
3348 static int cached_attr_count
;
3349 /* Bitmasks of possibly cached attributes. */
3350 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3351 static unsigned int attrs_to_cache
;
3352 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3354 /* Finds non-const attributes that could be possibly cached.
3355 When create is TRUE, fills in cached_attrs array.
3356 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3360 find_attrs_to_cache (rtx exp
, bool create
)
3364 struct attr_desc
*attr
;
3369 switch (GET_CODE (exp
))
3372 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3373 find_attrs_to_cache (XEXP (exp
, 0), create
);
3377 name
= XSTR (exp
, 0);
3378 if (name
== alternative_name
)
3380 for (i
= 0; i
< cached_attr_count
; i
++)
3381 if (name
== cached_attrs
[i
])
3383 if ((attrs_seen_once
& (1U << i
)) != 0)
3384 attrs_seen_more_than_once
|= (1U << i
);
3386 attrs_seen_once
|= (1U << i
);
3391 attr
= find_attr (&name
, 0);
3395 if (cached_attr_count
== 32)
3397 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3398 attrs_seen_once
|= (1U << cached_attr_count
);
3399 cached_attr_count
++;
3404 find_attrs_to_cache (XEXP (exp
, 0), create
);
3405 find_attrs_to_cache (XEXP (exp
, 1), create
);
3409 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3410 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3418 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3419 We use AND and IOR both for logical and bit-wise operations, so
3420 interpret them as logical unless they are inside a comparison expression.
3422 An outermost pair of parentheses is emitted around this C expression unless
3423 EMIT_PARENS is false. */
3425 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3426 #define FLG_BITWISE 1
3427 /* Set if cached attribute will be known initialized in else block after
3428 this condition. This is true for LHS of toplevel && and || and
3429 even for RHS of ||, but not for RHS of &&. */
3431 /* Set if cached attribute will be known initialized in then block after
3432 this condition. This is true for LHS of toplevel && and || and
3433 even for RHS of &&, but not for RHS of ||. */
3434 #define FLG_INSIDE 4
3435 /* Cleared when an operand of &&. */
3436 #define FLG_OUTSIDE_AND 8
3439 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
,
3440 bool emit_parens
= true)
3442 int comparison_operator
= 0;
3444 struct attr_desc
*attr
;
3447 fprintf (outf
, "(");
3449 code
= GET_CODE (exp
);
3452 /* Binary operators. */
3455 fprintf (outf
, "(unsigned) ");
3461 comparison_operator
= FLG_BITWISE
;
3464 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3465 case AND
: case IOR
: case XOR
:
3466 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3467 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3469 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3470 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3471 flags
| comparison_operator
);
3476 flags
&= ~FLG_OUTSIDE_AND
;
3477 if (GET_CODE (XEXP (exp
, 0)) == code
3478 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3479 || (GET_CODE (XEXP (exp
, 0)) == NOT
3480 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3482 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3484 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3489 fprintf (outf
, " == ");
3492 fprintf (outf
, " != ");
3495 fprintf (outf
, " >= ");
3498 fprintf (outf
, " > ");
3501 fprintf (outf
, " >= (unsigned) ");
3504 fprintf (outf
, " > (unsigned) ");
3507 fprintf (outf
, " <= ");
3510 fprintf (outf
, " < ");
3513 fprintf (outf
, " <= (unsigned) ");
3516 fprintf (outf
, " < (unsigned) ");
3519 fprintf (outf
, " + ");
3522 fprintf (outf
, " - ");
3525 fprintf (outf
, " * ");
3528 fprintf (outf
, " / ");
3531 fprintf (outf
, " %% ");
3534 if (flags
& FLG_BITWISE
)
3535 fprintf (outf
, " & ");
3537 fprintf (outf
, " && ");
3540 if (flags
& FLG_BITWISE
)
3541 fprintf (outf
, " | ");
3543 fprintf (outf
, " || ");
3546 fprintf (outf
, " ^ ");
3549 fprintf (outf
, " << ");
3553 fprintf (outf
, " >> ");
3561 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3562 cached_x is only known to be initialized in then block. */
3563 flags
&= ~FLG_AFTER
;
3565 else if (code
== IOR
)
3567 if (flags
& FLG_OUTSIDE_AND
)
3568 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3569 cached_x is only known to be initialized in else block
3570 and else if conditions. */
3571 flags
&= ~FLG_INSIDE
;
3573 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3575 cached_x is not know to be initialized anywhere. */
3576 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3578 if ((code
== AND
|| code
== IOR
)
3579 && (GET_CODE (XEXP (exp
, 1)) == code
3580 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3581 || (GET_CODE (XEXP (exp
, 1)) == NOT
3582 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3584 bool need_parens
= true;
3586 /* No need to emit parentheses around the right-hand operand if we are
3587 continuing a chain of && or || (or & or |). */
3588 if (GET_CODE (XEXP (exp
, 1)) == code
)
3589 need_parens
= false;
3592 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
,
3596 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3597 flags
| comparison_operator
);
3601 /* Special-case (not (eq_attrq "alternative" "x")) */
3602 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3604 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3606 fprintf (outf
, "which_alternative != %s",
3607 XSTR (XEXP (exp
, 0), 1));
3611 fprintf (outf
, "! ");
3613 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3617 /* Otherwise, fall through to normal unary operator. */
3619 /* Unary operators. */
3624 if (flags
& FLG_BITWISE
)
3625 fprintf (outf
, "~ ");
3627 fprintf (outf
, "! ");
3630 fprintf (outf
, "abs ");
3633 fprintf (outf
, "-");
3639 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3640 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3645 int set
= XINT (exp
, 0), bit
= 0;
3647 if (flags
& FLG_BITWISE
)
3648 fatal ("EQ_ATTR_ALT not valid inside comparison");
3651 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3653 if (!(set
& (set
- 1)))
3655 if (!(set
& 0xffff))
3678 fprintf (outf
, "which_alternative %s= %d",
3679 XINT (exp
, 1) ? "!" : "=", bit
);
3683 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3684 XINT (exp
, 1) ? "!" : "", set
);
3689 /* Comparison test of an attribute with a value. Most of these will
3690 have been removed by optimization. Handle "alternative"
3691 specially and give error if EQ_ATTR present inside a comparison. */
3693 if (flags
& FLG_BITWISE
)
3694 fatal ("EQ_ATTR not valid inside comparison");
3696 if (XSTR (exp
, 0) == alternative_name
)
3698 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3702 attr
= find_attr (&XSTR (exp
, 0), 0);
3705 /* Now is the time to expand the value of a constant attribute. */
3708 write_test_expr (outf
,
3709 evaluate_eq_attr (exp
, attr
,
3710 attr
->default_val
->value
,
3717 for (i
= 0; i
< cached_attr_count
; i
++)
3718 if (attr
->name
== cached_attrs
[i
])
3720 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3721 fprintf (outf
, "cached_%s", attr
->name
);
3722 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3724 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3725 attr
->name
, attr
->name
);
3726 if (flags
& FLG_AFTER
)
3727 attrs_cached_after
|= (1U << i
);
3728 if (flags
& FLG_INSIDE
)
3729 attrs_cached_inside
|= (1U << i
);
3730 attrs_cached
|= (1U << i
);
3733 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3734 fprintf (outf
, " == ");
3735 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3739 /* Comparison test of flags for define_delays. */
3741 if (flags
& FLG_BITWISE
)
3742 fatal ("ATTR_FLAG not valid inside comparison");
3743 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3746 /* See if an operand matches a predicate. */
3748 /* If only a mode is given, just ensure the mode matches the operand.
3749 If neither a mode nor predicate is given, error. */
3750 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3752 if (GET_MODE (exp
) == VOIDmode
)
3753 fatal ("null MATCH_OPERAND specified as test");
3755 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3756 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3759 fprintf (outf
, "%s (operands[%d], %smode)",
3760 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3763 /* Constant integer. */
3765 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3769 fprint_c_condition (outf
, XSTR (exp
, 0));
3770 if (flags
& FLG_BITWISE
)
3771 fprintf (outf
, " != 0");
3774 /* A random C expression. */
3776 fprint_c_condition (outf
, XSTR (exp
, 0));
3779 /* The address of the branch target. */
3782 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3783 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3787 /* The address of the current insn. We implement this actually as the
3788 address of the current insn for backward branches, but the last
3789 address of the next insn for forward branches, and both with
3790 adjustments that account for the worst-case possible stretching of
3791 intervening alignments between this insn and its destination. */
3792 fprintf (outf
, "insn_current_reference_address (insn)");
3796 fprintf (outf
, "%s", XSTR (exp
, 0));
3800 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3801 fprintf (outf
, " ? ");
3802 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3803 fprintf (outf
, " : ");
3804 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3808 fatal ("bad RTX code `%s' in attribute calculation\n",
3809 GET_RTX_NAME (code
));
3813 fprintf (outf
, ")");
3815 return attrs_cached
;
3818 /* Given an attribute value, return the maximum CONST_STRING argument
3819 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3822 max_attr_value (rtx exp
, int *unknownp
)
3827 switch (GET_CODE (exp
))
3830 current_max
= atoi (XSTR (exp
, 0));
3834 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3835 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3837 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3838 if (n
> current_max
)
3844 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3845 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3846 if (n
> current_max
)
3852 current_max
= INT_MAX
;
3859 /* Given an attribute value, return the minimum CONST_STRING argument
3860 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3863 min_attr_value (rtx exp
, int *unknownp
)
3868 switch (GET_CODE (exp
))
3871 current_min
= atoi (XSTR (exp
, 0));
3875 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3876 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3878 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3879 if (n
< current_min
)
3885 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3886 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3887 if (n
< current_min
)
3893 current_min
= INT_MAX
;
3900 /* Given an attribute value, return the result of ORing together all
3901 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3902 if the numeric value is not known. */
3905 or_attr_value (rtx exp
, int *unknownp
)
3910 switch (GET_CODE (exp
))
3913 current_or
= atoi (XSTR (exp
, 0));
3917 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3918 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3919 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3923 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3924 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3936 /* Scan an attribute value, possibly a conditional, and record what actions
3937 will be required to do any conditional tests in it.
3940 `must_extract' if we need to extract the insn operands
3941 `must_constrain' if we must compute `which_alternative'
3942 `address_used' if an address expression was used
3943 `length_used' if an (eq_attr "length" ...) was used
3947 walk_attr_value (rtx exp
)
3956 code
= GET_CODE (exp
);
3960 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3961 /* Since this is an arbitrary expression, it can look at anything.
3962 However, constant expressions do not depend on any particular
3964 must_extract
= must_constrain
= 1;
3973 must_extract
= must_constrain
= 1;
3977 if (XSTR (exp
, 0) == alternative_name
)
3978 must_extract
= must_constrain
= 1;
3979 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3999 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
4004 walk_attr_value (XEXP (exp
, i
));
4008 if (XVEC (exp
, i
) != NULL
)
4009 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4010 walk_attr_value (XVECEXP (exp
, i
, j
));
4015 /* Write out a function to obtain the attribute for a given INSN. */
4018 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
4020 struct attr_value
*av
, *common_av
;
4023 /* Find the most used attribute value. Handle that as the `default' of the
4024 switch we will generate. */
4025 common_av
= find_most_used (attr
);
4027 /* Write out start of function, then all values with explicit `case' lines,
4028 then a `default', then the value with the most uses. */
4029 if (attr
->enum_name
)
4030 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4031 else if (!attr
->is_numeric
)
4032 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4034 fprintf (outf
, "int\n");
4036 /* If the attribute name starts with a star, the remainder is the name of
4037 the subroutine to use, instead of `get_attr_...'. */
4038 if (attr
->name
[0] == '*')
4039 fprintf (outf
, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4040 else if (attr
->is_const
== 0)
4041 fprintf (outf
, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4044 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4045 fprintf (outf
, "{\n");
4047 for (av
= attr
->first_value
; av
; av
= av
->next
)
4048 if (av
->num_insns
== 1)
4049 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4050 true_rtx
, av
->first_insn
->def
->insn_code
,
4051 av
->first_insn
->def
->insn_index
, 0);
4052 else if (av
->num_insns
!= 0)
4053 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4054 true_rtx
, -2, 0, 0);
4056 fprintf (outf
, "}\n\n");
4060 fprintf (outf
, "{\n");
4062 /* Find attributes that are worth caching in the conditions. */
4063 cached_attr_count
= 0;
4064 attrs_seen_more_than_once
= 0;
4065 for (av
= attr
->first_value
; av
; av
= av
->next
)
4067 attrs_seen_once
= 0;
4068 find_attrs_to_cache (av
->value
, true);
4070 /* Remove those that aren't worth caching from the array. */
4071 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4072 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4074 const char *name
= cached_attrs
[i
];
4075 struct attr_desc
*cached_attr
;
4077 cached_attrs
[j
] = name
;
4078 cached_attr
= find_attr (&name
, 0);
4079 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4080 if (cached_attr
->enum_name
)
4081 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4082 else if (!cached_attr
->is_numeric
)
4083 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4085 fprintf (outf
, " int");
4086 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4089 cached_attr_count
= j
;
4090 if (cached_attr_count
)
4091 fprintf (outf
, "\n");
4093 fprintf (outf
, " switch (recog_memoized (insn))\n");
4094 fprintf (outf
, " {\n");
4096 for (av
= attr
->first_value
; av
; av
= av
->next
)
4097 if (av
!= common_av
)
4098 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4100 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4101 fprintf (outf
, " }\n}\n\n");
4102 cached_attr_count
= 0;
4105 /* Given an AND tree of known true terms (because we are inside an `if' with
4106 that as the condition or are in an `else' clause) and an expression,
4107 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4108 the bulk of the work. */
4111 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4115 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4117 if (GET_CODE (known_true
) == AND
)
4119 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4120 insn_code
, insn_index
);
4121 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4122 insn_code
, insn_index
);
4127 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4133 /* Write out a series of tests and assignment statements to perform tests and
4134 sets of an attribute value. We are passed an indentation amount and prefix
4135 and suffix strings to write around each attribute value (e.g., "return"
4139 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
4140 const char *prefix
, const char *suffix
, rtx known_true
,
4141 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4143 if (GET_CODE (value
) == COND
)
4145 /* Assume the default value will be the default of the COND unless we
4146 find an always true expression. */
4147 rtx default_val
= XEXP (value
, 1);
4148 rtx our_known_true
= known_true
;
4153 if (cached_attr_count
)
4155 attrs_seen_once
= 0;
4156 attrs_seen_more_than_once
= 0;
4157 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4158 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4159 attrs_to_cache
|= attrs_seen_more_than_once
;
4162 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4167 /* Reset our_known_true after some time to not accumulate
4168 too much cruft (slowing down genattrtab). */
4170 our_known_true
= known_true
;
4171 testexp
= eliminate_known_true (our_known_true
,
4172 XVECEXP (value
, 0, i
),
4173 insn_code
, insn_index
);
4174 newexp
= attr_rtx (NOT
, testexp
);
4175 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4176 insn_code
, insn_index
);
4178 /* If the test expression is always true or if the next `known_true'
4179 expression is always false, this is the last case, so break
4180 out and let this value be the `else' case. */
4181 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4183 default_val
= XVECEXP (value
, 0, i
+ 1);
4187 /* Compute the expression to pass to our recursive call as being
4189 inner_true
= insert_right_side (AND
, our_known_true
,
4190 testexp
, insn_code
, insn_index
);
4192 /* If this is always false, skip it. */
4193 if (inner_true
== false_rtx
)
4196 attrs_cached_inside
= attrs_cached
;
4197 attrs_cached_after
= attrs_cached
;
4198 write_indent (outf
, indent
);
4199 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4201 write_test_expr (outf
, testexp
, attrs_cached
,
4202 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4203 attrs_cached
= attrs_cached_after
;
4204 fprintf (outf
, "\n");
4205 write_indent (outf
, indent
+ 2);
4206 fprintf (outf
, "{\n");
4208 write_attr_set (outf
, attr
, indent
+ 4,
4209 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4210 inner_true
, insn_code
, insn_index
,
4211 attrs_cached_inside
);
4212 write_indent (outf
, indent
+ 2);
4213 fprintf (outf
, "}\n");
4214 our_known_true
= newexp
;
4219 write_indent (outf
, indent
);
4220 fprintf (outf
, "else\n");
4221 write_indent (outf
, indent
+ 2);
4222 fprintf (outf
, "{\n");
4225 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4226 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4231 write_indent (outf
, indent
+ 2);
4232 fprintf (outf
, "}\n");
4237 write_indent (outf
, indent
);
4238 fprintf (outf
, "%s ", prefix
);
4239 write_attr_value (outf
, attr
, value
);
4240 fprintf (outf
, "%s\n", suffix
);
4244 /* Write a series of case statements for every instruction in list IE.
4245 INDENT is the amount of indentation to write before each case. */
4248 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4250 for (; ie
!= 0; ie
= ie
->next
)
4251 if (ie
->def
->insn_code
!= -1)
4253 write_indent (outf
, indent
);
4254 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4255 fprintf (outf
, "case %d: /* define_peephole, %s:%d */\n",
4256 ie
->def
->insn_code
, ie
->def
->loc
.filename
,
4257 ie
->def
->loc
.lineno
);
4259 fprintf (outf
, "case %d: /* %s */\n",
4260 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4264 /* Write out the computation for one attribute value. */
4267 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4268 int write_case_lines
, const char *prefix
, const char *suffix
,
4269 int indent
, rtx known_true
)
4271 if (av
->num_insns
== 0)
4274 if (av
->has_asm_insn
)
4276 write_indent (outf
, indent
);
4277 fprintf (outf
, "case -1:\n");
4278 write_indent (outf
, indent
+ 2);
4279 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4280 write_indent (outf
, indent
+ 2);
4281 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4282 write_indent (outf
, indent
+ 2);
4283 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4286 if (write_case_lines
)
4287 write_insn_cases (outf
, av
->first_insn
, indent
);
4290 write_indent (outf
, indent
);
4291 fprintf (outf
, "default:\n");
4294 /* See what we have to do to output this value. */
4295 must_extract
= must_constrain
= address_used
= 0;
4296 walk_attr_value (av
->value
);
4300 write_indent (outf
, indent
+ 2);
4301 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4303 else if (must_extract
)
4305 write_indent (outf
, indent
+ 2);
4306 fprintf (outf
, "extract_insn_cached (insn);\n");
4310 if (av
->num_insns
== 1)
4311 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4312 known_true
, av
->first_insn
->def
->insn_code
,
4313 av
->first_insn
->def
->insn_index
, 0);
4315 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4316 known_true
, -2, 0, 0);
4318 if (strncmp (prefix
, "return", 6))
4320 write_indent (outf
, indent
+ 2);
4321 fprintf (outf
, "break;\n");
4323 fprintf (outf
, "\n");
4326 /* Utilities to write in various forms. */
4329 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4331 if (attr
->is_numeric
)
4335 fprintf (outf
, "%d", num
);
4337 if (num
> 9 || num
< 0)
4338 fprintf (outf
, " /* %#x */", num
);
4342 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4343 fprintf (outf
, "_");
4344 write_upcase (outf
, s
);
4349 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4353 switch (GET_CODE (value
))
4356 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4360 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4364 fprint_c_condition (outf
, XSTR (value
, 0));
4369 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4370 if (attr
->enum_name
)
4371 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4372 else if (!attr
->is_numeric
)
4373 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4374 else if (!attr2
->is_numeric
)
4375 fprintf (outf
, "(int)");
4377 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4378 (attr2
->is_const
? "" : "insn"));
4399 write_attr_value (outf
, attr
, XEXP (value
, 0));
4403 write_attr_value (outf
, attr
, XEXP (value
, 1));
4412 write_upcase (FILE *outf
, const char *str
)
4416 /* The argument of TOUPPER should not have side effects. */
4417 fputc (TOUPPER (*str
), outf
);
4423 write_indent (FILE *outf
, int indent
)
4425 for (; indent
> 8; indent
-= 8)
4426 fprintf (outf
, "\t");
4428 for (; indent
; indent
--)
4429 fprintf (outf
, " ");
4432 /* If the target does not have annul-true or annul-false delay slots, this
4433 function will create a dummy eligible_for function on OUTF which always
4434 returns false. KIND will be annul_true or annul_false. */
4437 write_dummy_eligible_delay (FILE *outf
, const char *kind
)
4439 /* Write function prelude. */
4441 fprintf (outf
, "int\n");
4442 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4443 " int slot ATTRIBUTE_UNUSED,\n"
4444 " rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4445 " int flags ATTRIBUTE_UNUSED)\n",
4447 fprintf (outf
, "{\n");
4448 fprintf (outf
, " return 0;\n");
4449 fprintf (outf
, "}\n\n");
4452 /* Write a subroutine that is given an insn that requires a delay slot, a
4453 delay slot ordinal, and a candidate insn. It returns nonzero if the
4454 candidate can be placed in the specified delay slot of the insn.
4456 We can write as many as three subroutines. `eligible_for_delay'
4457 handles normal delay slots, `eligible_for_annul_true' indicates that
4458 the specified insn can be annulled if the branch is true, and likewise
4459 for `eligible_for_annul_false'.
4461 KIND is a string distinguishing these three cases ("delay", "annul_true",
4462 or "annul_false"). */
4465 write_eligible_delay (FILE *outf
, const char *kind
)
4467 struct delay_desc
*delay
;
4471 struct attr_desc
*attr
;
4472 struct attr_value
*av
, *common_av
;
4475 /* Compute the maximum number of delay slots required. We use the delay
4476 ordinal times this number plus one, plus the slot number as an index into
4477 the appropriate predicate to test. */
4479 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4480 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4481 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4483 /* Write function prelude. */
4485 fprintf (outf
, "int\n");
4486 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4487 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4489 fprintf (outf
, "{\n");
4490 fprintf (outf
, " rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4491 fprintf (outf
, "\n");
4492 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4493 fprintf (outf
, "\n");
4494 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4495 converts a compound instruction into a loop. */
4496 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4497 fprintf (outf
, " return 0;\n");
4498 fprintf (outf
, "\n");
4500 /* If more than one delay type, find out which type the delay insn is. */
4504 attr
= find_attr (&delay_type_str
, 0);
4506 common_av
= find_most_used (attr
);
4508 fprintf (outf
, " insn = delay_insn;\n");
4509 fprintf (outf
, " switch (recog_memoized (insn))\n");
4510 fprintf (outf
, " {\n");
4512 sprintf (str
, " * %d;\n break;", max_slots
);
4513 for (av
= attr
->first_value
; av
; av
= av
->next
)
4514 if (av
!= common_av
)
4515 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4517 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4518 fprintf (outf
, " }\n\n");
4520 /* Ensure matched. Otherwise, shouldn't have been called. */
4521 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4524 /* If just one type of delay slot, write simple switch. */
4525 if (num_delays
== 1 && max_slots
== 1)
4527 fprintf (outf
, " insn = candidate_insn;\n");
4528 fprintf (outf
, " switch (recog_memoized (insn))\n");
4529 fprintf (outf
, " {\n");
4531 attr
= find_attr (&delay_1_0_str
, 0);
4533 common_av
= find_most_used (attr
);
4535 for (av
= attr
->first_value
; av
; av
= av
->next
)
4536 if (av
!= common_av
)
4537 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4539 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4540 fprintf (outf
, " }\n");
4545 /* Write a nested CASE. The first indicates which condition we need to
4546 test, and the inner CASE tests the condition. */
4547 fprintf (outf
, " insn = candidate_insn;\n");
4548 fprintf (outf
, " switch (slot)\n");
4549 fprintf (outf
, " {\n");
4551 for (delay
= delays
; delay
; delay
= delay
->next
)
4552 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4554 fprintf (outf
, " case %d:\n",
4555 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4556 fprintf (outf
, " switch (recog_memoized (insn))\n");
4557 fprintf (outf
, "\t{\n");
4559 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4561 attr
= find_attr (&pstr
, 0);
4563 common_av
= find_most_used (attr
);
4565 for (av
= attr
->first_value
; av
; av
= av
->next
)
4566 if (av
!= common_av
)
4567 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4569 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4570 fprintf (outf
, " }\n");
4573 fprintf (outf
, " default:\n");
4574 fprintf (outf
, " gcc_unreachable ();\n");
4575 fprintf (outf
, " }\n");
4578 fprintf (outf
, "}\n\n");
4581 /* This page contains miscellaneous utility routines. */
4583 /* Given a pointer to a (char *), return a malloc'ed string containing the
4584 next comma-separated element. Advance the pointer to after the string
4585 scanned, or the end-of-string. Return NULL if at end of string. */
4588 next_comma_elt (const char **pstr
)
4592 start
= scan_comma_elt (pstr
);
4597 return attr_string (start
, *pstr
- start
);
4600 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4601 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4602 replaced by a pointer to a canonical copy of the string. */
4604 static struct attr_desc
*
4605 find_attr (const char **name_p
, int create
)
4607 struct attr_desc
*attr
;
4609 const char *name
= *name_p
;
4611 /* Before we resort to using `strcmp', see if the string address matches
4612 anywhere. In most cases, it should have been canonicalized to do so. */
4613 if (name
== alternative_name
)
4616 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4617 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4618 if (name
== attr
->name
)
4621 /* Otherwise, do it the slow way. */
4622 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4623 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4625 *name_p
= attr
->name
;
4632 attr
= oballoc (struct attr_desc
);
4633 attr
->name
= DEF_ATTR_STRING (name
);
4634 attr
->enum_name
= 0;
4635 attr
->first_value
= attr
->default_val
= NULL
;
4636 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4637 attr
->next
= attrs
[index
];
4638 attrs
[index
] = attr
;
4640 *name_p
= attr
->name
;
4645 /* Create internal attribute with the given default value. */
4648 make_internal_attr (const char *name
, rtx value
, int special
)
4650 struct attr_desc
*attr
;
4652 attr
= find_attr (&name
, 1);
4653 gcc_assert (!attr
->default_val
);
4655 attr
->is_numeric
= 1;
4657 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4658 attr
->default_val
= get_attr_value (file_location ("<internal>", 0),
4662 /* Find the most used value of an attribute. */
4664 static struct attr_value
*
4665 find_most_used (struct attr_desc
*attr
)
4667 struct attr_value
*av
;
4668 struct attr_value
*most_used
;
4674 for (av
= attr
->first_value
; av
; av
= av
->next
)
4675 if (av
->num_insns
> nuses
)
4676 nuses
= av
->num_insns
, most_used
= av
;
4681 /* Return (attr_value "n") */
4684 make_numeric_value (int n
)
4686 static rtx int_values
[20];
4690 gcc_assert (n
>= 0);
4692 if (n
< 20 && int_values
[n
])
4693 return int_values
[n
];
4695 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4696 exp
= attr_rtx (CONST_STRING
, p
);
4699 int_values
[n
] = exp
;
4705 copy_rtx_unchanging (rtx orig
)
4707 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4710 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4714 /* Determine if an insn has a constant number of delay slots, i.e., the
4715 number of delay slots is not a function of the length of the insn. */
4718 write_const_num_delay_slots (FILE *outf
)
4720 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4721 struct attr_value
*av
;
4725 fprintf (outf
, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4726 fprintf (outf
, "{\n");
4727 fprintf (outf
, " switch (recog_memoized (insn))\n");
4728 fprintf (outf
, " {\n");
4730 for (av
= attr
->first_value
; av
; av
= av
->next
)
4733 walk_attr_value (av
->value
);
4735 write_insn_cases (outf
, av
->first_insn
, 4);
4738 fprintf (outf
, " default:\n");
4739 fprintf (outf
, " return 1;\n");
4740 fprintf (outf
, " }\n}\n\n");
4744 /* Synthetic attributes used by insn-automata.c and the scheduler.
4745 These are primarily concerned with (define_insn_reservation)
4750 struct insn_reserv
*next
;
4753 int default_latency
;
4756 /* Sequence number of this insn. */
4759 /* Whether a (define_bypass) construct names this insn in its
4764 static struct insn_reserv
*all_insn_reservs
= 0;
4765 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4766 static size_t n_insn_reservs
;
4768 /* Store information from a DEFINE_INSN_RESERVATION for future
4769 attribute generation. */
4771 gen_insn_reserv (md_rtx_info
*info
)
4773 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4774 rtx def
= info
->def
;
4776 struct attr_desc attr
;
4777 memset (&attr
, 0, sizeof (attr
));
4778 attr
.name
= DEF_ATTR_STRING (XSTR (def
, 0));
4779 attr
.loc
= info
->loc
;
4781 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4782 decl
->default_latency
= XINT (def
, 1);
4783 decl
->condexp
= check_attr_test (info
->loc
, XEXP (def
, 2), &attr
);
4784 decl
->insn_num
= n_insn_reservs
;
4785 decl
->bypassed
= false;
4788 *last_insn_reserv_p
= decl
;
4789 last_insn_reserv_p
= &decl
->next
;
4793 /* Store information from a DEFINE_BYPASS for future attribute
4794 generation. The only thing we care about is the list of output
4795 insns, which will later be used to tag reservation structures with
4796 a 'bypassed' bit. */
4800 struct bypass_list
*next
;
4801 const char *pattern
;
4804 static struct bypass_list
*all_bypasses
;
4805 static size_t n_bypasses
;
4806 static size_t n_bypassed
;
4809 gen_bypass_1 (const char *s
, size_t len
)
4811 struct bypass_list
*b
;
4816 s
= attr_string (s
, len
);
4817 for (b
= all_bypasses
; b
; b
= b
->next
)
4818 if (s
== b
->pattern
)
4819 return; /* already got that one */
4821 b
= oballoc (struct bypass_list
);
4823 b
->next
= all_bypasses
;
4829 gen_bypass (md_rtx_info
*info
)
4831 const char *p
, *base
;
4833 rtx def
= info
->def
;
4834 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4837 gen_bypass_1 (base
, p
- base
);
4840 while (ISSPACE (*p
));
4843 gen_bypass_1 (base
, p
- base
);
4846 /* Find and mark all of the bypassed insns. */
4848 process_bypasses (void)
4850 struct bypass_list
*b
;
4851 struct insn_reserv
*r
;
4855 /* The reservation list is likely to be much longer than the bypass
4857 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4858 for (b
= all_bypasses
; b
; b
= b
->next
)
4859 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4867 /* Check that attribute NAME is used in define_insn_reservation condition
4868 EXP. Return true if it is. */
4870 check_tune_attr (const char *name
, rtx exp
)
4872 switch (GET_CODE (exp
))
4875 if (check_tune_attr (name
, XEXP (exp
, 0)))
4877 return check_tune_attr (name
, XEXP (exp
, 1));
4880 return (check_tune_attr (name
, XEXP (exp
, 0))
4881 && check_tune_attr (name
, XEXP (exp
, 1)));
4884 return XSTR (exp
, 0) == name
;
4891 /* Try to find a const attribute (usually cpu or tune) that is used
4892 in all define_insn_reservation conditions. */
4893 static struct attr_desc
*
4894 find_tune_attr (rtx exp
)
4896 struct attr_desc
*attr
;
4898 switch (GET_CODE (exp
))
4902 attr
= find_tune_attr (XEXP (exp
, 0));
4905 return find_tune_attr (XEXP (exp
, 1));
4908 if (XSTR (exp
, 0) == alternative_name
)
4911 attr
= find_attr (&XSTR (exp
, 0), 0);
4914 if (attr
->is_const
&& !attr
->is_special
)
4916 struct insn_reserv
*decl
;
4918 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4919 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4930 /* Create all of the attributes that describe automaton properties.
4931 Write the DFA and latency function prototypes to the files that
4932 need to have them, and write the init_sched_attrs(). */
4935 make_automaton_attrs (void)
4938 struct insn_reserv
*decl
;
4939 rtx code_exp
, lats_exp
, byps_exp
;
4940 struct attr_desc
*tune_attr
;
4942 if (n_insn_reservs
== 0)
4945 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4946 if (tune_attr
!= NULL
)
4948 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4949 struct attr_value
*val
;
4952 gcc_assert (tune_attr
->is_const
4953 && !tune_attr
->is_special
4954 && !tune_attr
->is_numeric
);
4956 /* Write the prototypes for all DFA functions. */
4957 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4959 if (val
== tune_attr
->default_val
)
4961 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4963 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4964 XSTR (val
->value
, 0));
4966 fprintf (dfa_file
, "\n");
4968 /* Write the prototypes for all latency functions. */
4969 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4971 if (val
== tune_attr
->default_val
)
4973 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4974 fprintf (latency_file
,
4975 "extern int insn_default_latency_%s (rtx_insn *);\n",
4976 XSTR (val
->value
, 0));
4978 fprintf (latency_file
, "\n");
4980 /* Write the prototypes for all automaton functions. */
4981 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4983 if (val
== tune_attr
->default_val
)
4985 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4987 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4988 "extern int insn_default_latency_%s (rtx_insn *);\n",
4989 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4991 fprintf (attr_file
, "\n");
4992 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4993 fprintf (attr_file
, "int (*insn_default_latency) (rtx_insn *);\n");
4994 fprintf (attr_file
, "\n");
4995 fprintf (attr_file
, "void\n");
4996 fprintf (attr_file
, "init_sched_attrs (void)\n");
4997 fprintf (attr_file
, "{\n");
4999 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
5003 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
5005 if (val
== tune_attr
->default_val
)
5007 for (decl
= all_insn_reservs
, i
= 0;
5013 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
5014 if (condexp
== false_rtx
)
5016 if (condexp
== true_rtx
)
5018 condexps
[i
] = condexp
;
5019 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
5020 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
5024 code_exp
= rtx_alloc (COND
);
5025 lats_exp
= rtx_alloc (COND
);
5028 XVEC (code_exp
, 0) = rtvec_alloc (j
);
5029 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
5033 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
5034 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
5038 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5039 XEXP (lats_exp
, 1) = make_numeric_value (0);
5046 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
5047 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
5049 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
5050 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5053 name
= XNEWVEC (char,
5054 sizeof ("*internal_dfa_insn_code_")
5055 + strlen (XSTR (val
->value
, 0)));
5056 strcpy (name
, "*internal_dfa_insn_code_");
5057 strcat (name
, XSTR (val
->value
, 0));
5058 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5059 strcpy (name
, "*insn_default_latency_");
5060 strcat (name
, XSTR (val
->value
, 0));
5061 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5066 fprintf (attr_file
, " if (");
5070 fprintf (attr_file
, " else if (");
5071 write_test_expr (attr_file
, test
, 0, 0);
5072 fprintf (attr_file
, ")\n");
5073 fprintf (attr_file
, " {\n");
5074 fprintf (attr_file
, " internal_dfa_insn_code\n");
5075 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5076 XSTR (val
->value
, 0));
5077 fprintf (attr_file
, " insn_default_latency\n");
5078 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5079 XSTR (val
->value
, 0));
5080 fprintf (attr_file
, " }\n");
5083 fprintf (attr_file
, " else\n");
5084 fprintf (attr_file
, " gcc_unreachable ();\n");
5085 fprintf (attr_file
, "}\n");
5086 fprintf (attr_file
, "\n");
5088 XDELETEVEC (condexps
);
5092 code_exp
= rtx_alloc (COND
);
5093 lats_exp
= rtx_alloc (COND
);
5095 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5096 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5098 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5099 XEXP (lats_exp
, 1) = make_numeric_value (0);
5101 for (decl
= all_insn_reservs
, i
= 0;
5103 decl
= decl
->next
, i
+= 2)
5105 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5106 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5108 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5109 XVECEXP (lats_exp
, 0, i
+1)
5110 = make_numeric_value (decl
->default_latency
);
5112 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5113 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5116 if (n_bypasses
== 0)
5117 byps_exp
= make_numeric_value (0);
5120 process_bypasses ();
5122 byps_exp
= rtx_alloc (COND
);
5123 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypassed
* 2);
5124 XEXP (byps_exp
, 1) = make_numeric_value (0);
5125 for (decl
= all_insn_reservs
, i
= 0;
5130 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5131 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5136 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5140 write_header (FILE *outf
)
5142 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5143 " from the machine description file `md'. */\n\n");
5145 fprintf (outf
, "#include \"config.h\"\n");
5146 fprintf (outf
, "#include \"system.h\"\n");
5147 fprintf (outf
, "#include \"coretypes.h\"\n");
5148 fprintf (outf
, "#include \"backend.h\"\n");
5149 fprintf (outf
, "#include \"predict.h\"\n");
5150 fprintf (outf
, "#include \"tree.h\"\n");
5151 fprintf (outf
, "#include \"rtl.h\"\n");
5152 fprintf (outf
, "#include \"alias.h\"\n");
5153 fprintf (outf
, "#include \"options.h\"\n");
5154 fprintf (outf
, "#include \"varasm.h\"\n");
5155 fprintf (outf
, "#include \"stor-layout.h\"\n");
5156 fprintf (outf
, "#include \"calls.h\"\n");
5157 fprintf (outf
, "#include \"insn-attr.h\"\n");
5158 fprintf (outf
, "#include \"tm_p.h\"\n");
5159 fprintf (outf
, "#include \"insn-config.h\"\n");
5160 fprintf (outf
, "#include \"recog.h\"\n");
5161 fprintf (outf
, "#include \"regs.h\"\n");
5162 fprintf (outf
, "#include \"real.h\"\n");
5163 fprintf (outf
, "#include \"output.h\"\n");
5164 fprintf (outf
, "#include \"toplev.h\"\n");
5165 fprintf (outf
, "#include \"flags.h\"\n");
5166 fprintf (outf
, "#include \"emit-rtl.h\"\n");
5167 fprintf (outf
, "\n");
5168 fprintf (outf
, "#define operands recog_data.operand\n\n");
5172 open_outfile (const char *file_name
)
5175 outf
= fopen (file_name
, "w");
5177 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5178 write_header (outf
);
5183 handle_arg (const char *arg
)
5188 attr_file_name
= &arg
[2];
5191 dfa_file_name
= &arg
[2];
5194 latency_file_name
= &arg
[2];
5202 main (int argc
, const char **argv
)
5204 struct attr_desc
*attr
;
5205 struct insn_def
*id
;
5208 progname
= "genattrtab";
5210 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5211 return FATAL_EXIT_CODE
;
5213 attr_file
= open_outfile (attr_file_name
);
5214 dfa_file
= open_outfile (dfa_file_name
);
5215 latency_file
= open_outfile (latency_file_name
);
5217 obstack_init (hash_obstack
);
5218 obstack_init (temp_obstack
);
5220 /* Set up true and false rtx's */
5221 true_rtx
= rtx_alloc (CONST_INT
);
5222 XWINT (true_rtx
, 0) = 1;
5223 false_rtx
= rtx_alloc (CONST_INT
);
5224 XWINT (false_rtx
, 0) = 0;
5225 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5226 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5228 alternative_name
= DEF_ATTR_STRING ("alternative");
5229 length_str
= DEF_ATTR_STRING ("length");
5230 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5231 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5232 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5234 /* Read the machine description. */
5237 while (read_md_rtx (&info
))
5239 switch (GET_CODE (info
.def
))
5242 case DEFINE_PEEPHOLE
:
5243 case DEFINE_ASM_ATTRIBUTES
:
5248 case DEFINE_ENUM_ATTR
:
5256 case DEFINE_INSN_RESERVATION
:
5257 gen_insn_reserv (&info
);
5267 if (GET_CODE (info
.def
) != DEFINE_ASM_ATTRIBUTES
)
5268 insn_index_number
++;
5272 return FATAL_EXIT_CODE
;
5274 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5275 if (! got_define_asm_attributes
)
5278 info
.def
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5279 XVEC (info
.def
, 0) = rtvec_alloc (0);
5280 info
.loc
= file_location ("<internal>", 0);
5285 /* Expand DEFINE_DELAY information into new attribute. */
5288 /* Make `insn_alternatives'. */
5289 int num_insn_codes
= get_num_insn_codes ();
5290 insn_alternatives
= oballocvec (uint64_t, num_insn_codes
);
5291 for (id
= defs
; id
; id
= id
->next
)
5292 if (id
->insn_code
>= 0)
5293 insn_alternatives
[id
->insn_code
]
5294 = (((uint64_t) 1) << id
->num_alternatives
) - 1;
5296 /* Make `insn_n_alternatives'. */
5297 insn_n_alternatives
= oballocvec (int, num_insn_codes
);
5298 for (id
= defs
; id
; id
= id
->next
)
5299 if (id
->insn_code
>= 0)
5300 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5302 /* Construct extra attributes for automata. */
5303 make_automaton_attrs ();
5305 /* Prepare to write out attribute subroutines by checking everything stored
5306 away and building the attribute cases. */
5310 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5311 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5312 attr
->default_val
->value
5313 = check_attr_value (attr
->loc
, attr
->default_val
->value
, attr
);
5316 return FATAL_EXIT_CODE
;
5318 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5319 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5322 /* Construct extra attributes for `length'. */
5323 make_length_attrs ();
5325 /* Perform any possible optimizations to speed up compilation. */
5326 optimize_attrs (num_insn_codes
);
5328 /* Now write out all the `gen_attr_...' routines. Do these before the
5329 special routines so that they get defined before they are used. */
5331 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5332 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5336 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5337 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5339 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5340 outf
= latency_file
;
5343 #undef IS_ATTR_GROUP
5345 if (! attr
->is_special
&& ! attr
->is_const
)
5346 write_attr_get (outf
, attr
);
5349 /* Write out delay eligibility information, if DEFINE_DELAY present.
5350 (The function to compute the number of delay slots will be written
5352 write_eligible_delay (attr_file
, "delay");
5353 if (have_annul_true
)
5354 write_eligible_delay (attr_file
, "annul_true");
5356 write_dummy_eligible_delay (attr_file
, "annul_true");
5357 if (have_annul_false
)
5358 write_eligible_delay (attr_file
, "annul_false");
5360 write_dummy_eligible_delay (attr_file
, "annul_false");
5362 /* Write out constant delay slot info. */
5363 write_const_num_delay_slots (attr_file
);
5365 write_length_unit_log (attr_file
);
5367 if (fclose (attr_file
) != 0)
5368 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5369 if (fclose (dfa_file
) != 0)
5370 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5371 if (fclose (latency_file
) != 0)
5372 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5374 return SUCCESS_EXIT_CODE
;