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. */
1229 /* First, check for degenerate COND. */
1230 if (XVECLEN (exp
, 0) == 0)
1231 return make_canonical (loc
, attr
, XEXP (exp
, 1));
1232 defval
= XEXP (exp
, 1) = make_canonical (loc
, attr
, XEXP (exp
, 1));
1234 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1236 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1237 XVECEXP (exp
, 0, i
+ 1)
1238 = make_canonical (loc
, attr
, XVECEXP (exp
, 0, i
+ 1));
1239 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1255 copy_boolean (rtx exp
)
1257 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1258 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1259 copy_boolean (XEXP (exp
, 1)));
1260 if (GET_CODE (exp
) == MATCH_OPERAND
)
1262 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1263 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1265 else if (GET_CODE (exp
) == EQ_ATTR
)
1267 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1268 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1274 /* Given a value and an attribute description, return a `struct attr_value *'
1275 that represents that value. This is either an existing structure, if the
1276 value has been previously encountered, or a newly-created structure.
1278 `insn_code' is the code of an insn whose attribute has the specified
1279 value (-2 if not processing an insn). We ensure that all insns for
1280 a given value have the same number of alternatives if the value checks
1281 alternatives. LOC is the location to use for error reporting. */
1283 static struct attr_value
*
1284 get_attr_value (file_location loc
, rtx value
, struct attr_desc
*attr
,
1287 struct attr_value
*av
;
1288 uint64_t num_alt
= 0;
1290 value
= make_canonical (loc
, attr
, value
);
1291 if (compares_alternatives_p (value
))
1293 if (insn_code
< 0 || insn_alternatives
== NULL
)
1294 fatal_at (loc
, "(eq_attr \"alternatives\" ...) used in non-insn"
1297 num_alt
= insn_alternatives
[insn_code
];
1300 for (av
= attr
->first_value
; av
; av
= av
->next
)
1301 if (rtx_equal_p (value
, av
->value
)
1302 && (num_alt
== 0 || av
->first_insn
== NULL
1303 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1306 av
= oballoc (struct attr_value
);
1308 av
->next
= attr
->first_value
;
1309 attr
->first_value
= av
;
1310 av
->first_insn
= NULL
;
1312 av
->has_asm_insn
= 0;
1317 /* After all DEFINE_DELAYs have been read in, create internal attributes
1318 to generate the required routines.
1320 First, we compute the number of delay slots for each insn (as a COND of
1321 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1322 delay type is specified, we compute a similar function giving the
1323 DEFINE_DELAY ordinal for each insn.
1325 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1326 tells whether a given insn can be in that delay slot.
1328 Normal attribute filling and optimization expands these to contain the
1329 information needed to handle delay slots. */
1332 expand_delays (void)
1334 struct delay_desc
*delay
;
1340 /* First, generate data for `num_delay_slots' function. */
1342 condexp
= rtx_alloc (COND
);
1343 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1344 XEXP (condexp
, 1) = make_numeric_value (0);
1346 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1348 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1349 XVECEXP (condexp
, 0, i
+ 1)
1350 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1353 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1355 /* If more than one delay type, do the same for computing the delay type. */
1358 condexp
= rtx_alloc (COND
);
1359 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1360 XEXP (condexp
, 1) = make_numeric_value (0);
1362 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1364 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1365 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1368 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1371 /* For each delay possibility and delay slot, compute an eligibility
1372 attribute for non-annulled insns and for each type of annulled (annul
1373 if true and annul if false). */
1374 for (delay
= delays
; delay
; delay
= delay
->next
)
1376 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1378 condexp
= XVECEXP (delay
->def
, 1, i
);
1380 condexp
= false_rtx
;
1381 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1382 make_numeric_value (1), make_numeric_value (0));
1384 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1385 "*delay_%d_%d", delay
->num
, i
/ 3);
1386 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1388 if (have_annul_true
)
1390 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1391 if (condexp
== 0) condexp
= false_rtx
;
1392 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1393 make_numeric_value (1),
1394 make_numeric_value (0));
1395 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1396 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1397 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1400 if (have_annul_false
)
1402 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1403 if (condexp
== 0) condexp
= false_rtx
;
1404 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1405 make_numeric_value (1),
1406 make_numeric_value (0));
1407 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1408 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1409 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1415 /* Once all attributes and insns have been read and checked, we construct for
1416 each attribute value a list of all the insns that have that value for
1420 fill_attr (struct attr_desc
*attr
)
1422 struct attr_value
*av
;
1423 struct insn_ent
*ie
;
1424 struct insn_def
*id
;
1428 /* Don't fill constant attributes. The value is independent of
1429 any particular insn. */
1433 for (id
= defs
; id
; id
= id
->next
)
1435 /* If no value is specified for this insn for this attribute, use the
1438 if (XVEC (id
->def
, id
->vec_idx
))
1439 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1440 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1442 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1445 av
= attr
->default_val
;
1447 av
= get_attr_value (id
->loc
, value
, attr
, id
->insn_code
);
1449 ie
= oballoc (struct insn_ent
);
1451 insert_insn_ent (av
, ie
);
1455 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1456 test that checks relative positions of insns (uses MATCH_DUP or PC).
1457 If so, replace it with what is obtained by passing the expression to
1458 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1459 recursively on each value (including the default value). Otherwise,
1460 return the value returned by NO_ADDRESS_FN applied to EXP. */
1463 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1464 rtx (*address_fn
) (rtx
))
1469 if (GET_CODE (exp
) == COND
)
1471 /* See if any tests use addresses. */
1473 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1474 walk_attr_value (XVECEXP (exp
, 0, i
));
1477 return (*address_fn
) (exp
);
1479 /* Make a new copy of this COND, replacing each element. */
1480 newexp
= rtx_alloc (COND
);
1481 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1482 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1484 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1485 XVECEXP (newexp
, 0, i
+ 1)
1486 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1487 no_address_fn
, address_fn
);
1490 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1491 no_address_fn
, address_fn
);
1496 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1499 walk_attr_value (XEXP (exp
, 0));
1501 return (*address_fn
) (exp
);
1503 return attr_rtx (IF_THEN_ELSE
,
1504 substitute_address (XEXP (exp
, 0),
1505 no_address_fn
, address_fn
),
1506 substitute_address (XEXP (exp
, 1),
1507 no_address_fn
, address_fn
),
1508 substitute_address (XEXP (exp
, 2),
1509 no_address_fn
, address_fn
));
1512 return (*no_address_fn
) (exp
);
1515 /* Make new attributes from the `length' attribute. The following are made,
1516 each corresponding to a function called from `shorten_branches' or
1519 *insn_default_length This is the length of the insn to be returned
1520 by `get_attr_length' before `shorten_branches'
1521 has been called. In each case where the length
1522 depends on relative addresses, the largest
1523 possible is used. This routine is also used
1524 to compute the initial size of the insn.
1526 *insn_variable_length_p This returns 1 if the insn's length depends
1527 on relative addresses, zero otherwise.
1529 *insn_current_length This is only called when it is known that the
1530 insn has a variable length and returns the
1531 current length, based on relative addresses.
1535 make_length_attrs (void)
1537 static const char *new_names
[] =
1539 "*insn_default_length",
1541 "*insn_variable_length_p",
1542 "*insn_current_length"
1544 static rtx (*const no_address_fn
[]) (rtx
)
1545 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1546 static rtx (*const address_fn
[]) (rtx
)
1547 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1549 struct attr_desc
*length_attr
, *new_attr
;
1550 struct attr_value
*av
, *new_av
;
1551 struct insn_ent
*ie
, *new_ie
;
1553 /* See if length attribute is defined. If so, it must be numeric. Make
1554 it special so we don't output anything for it. */
1555 length_attr
= find_attr (&length_str
, 0);
1556 if (length_attr
== 0)
1559 if (! length_attr
->is_numeric
)
1560 fatal_at (length_attr
->loc
, "length attribute must be numeric");
1562 length_attr
->is_const
= 0;
1563 length_attr
->is_special
= 1;
1565 /* Make each new attribute, in turn. */
1566 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1568 make_internal_attr (new_names
[i
],
1569 substitute_address (length_attr
->default_val
->value
,
1570 no_address_fn
[i
], address_fn
[i
]),
1572 new_attr
= find_attr (&new_names
[i
], 0);
1573 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1574 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1576 new_av
= get_attr_value (ie
->def
->loc
,
1577 substitute_address (av
->value
,
1580 new_attr
, ie
->def
->insn_code
);
1581 new_ie
= oballoc (struct insn_ent
);
1582 new_ie
->def
= ie
->def
;
1583 insert_insn_ent (new_av
, new_ie
);
1588 /* Utility functions called from above routine. */
1591 identity_fn (rtx exp
)
1597 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1599 return make_numeric_value (0);
1603 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1605 return make_numeric_value (1);
1612 return make_numeric_value (max_attr_value (exp
, &unknown
));
1619 return make_numeric_value (min_attr_value (exp
, &unknown
));
1623 write_length_unit_log (FILE *outf
)
1625 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1626 struct attr_value
*av
;
1627 struct insn_ent
*ie
;
1628 unsigned int length_unit_log
, length_or
;
1633 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1634 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1635 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1636 length_or
|= or_attr_value (av
->value
, &unknown
);
1639 if (length_attr
== NULL
|| unknown
)
1640 length_unit_log
= 0;
1643 length_or
= ~length_or
;
1644 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1647 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1650 /* Compute approximate cost of the expression. Used to decide whether
1651 expression is cheap enough for inline. */
1653 attr_rtx_cost (rtx x
)
1659 code
= GET_CODE (x
);
1672 /* Alternatives don't result into function call. */
1673 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1680 const char *fmt
= GET_RTX_FORMAT (code
);
1681 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1687 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1688 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1691 cost
+= attr_rtx_cost (XEXP (x
, i
));
1701 /* Take a COND expression and see if any of the conditions in it can be
1702 simplified. If any are known true or known false for the particular insn
1703 code, the COND can be further simplified.
1705 Also call ourselves on any COND operations that are values of this COND.
1707 We do not modify EXP; rather, we make and return a new rtx. */
1710 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1713 /* We store the desired contents here,
1714 then build a new expression if they don't match EXP. */
1715 rtx defval
= XEXP (exp
, 1);
1716 rtx new_defval
= XEXP (exp
, 1);
1717 int len
= XVECLEN (exp
, 0);
1718 rtx
*tests
= XNEWVEC (rtx
, len
);
1722 /* This lets us free all storage allocated below, if appropriate. */
1723 obstack_finish (rtl_obstack
);
1725 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1727 /* See if default value needs simplification. */
1728 if (GET_CODE (defval
) == COND
)
1729 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1731 /* Simplify the subexpressions, and see what tests we can get rid of. */
1733 for (i
= 0; i
< len
; i
+= 2)
1735 rtx newtest
, newval
;
1737 /* Simplify this test. */
1738 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1741 newval
= tests
[i
+ 1];
1742 /* See if this value may need simplification. */
1743 if (GET_CODE (newval
) == COND
)
1744 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1746 /* Look for ways to delete or combine this test. */
1747 if (newtest
== true_rtx
)
1749 /* If test is true, make this value the default
1750 and discard this + any following tests. */
1752 defval
= tests
[i
+ 1];
1753 new_defval
= newval
;
1756 else if (newtest
== false_rtx
)
1758 /* If test is false, discard it and its value. */
1759 for (j
= i
; j
< len
- 2; j
++)
1760 tests
[j
] = tests
[j
+ 2];
1765 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1767 /* If this value and the value for the prev test are the same,
1771 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1772 insn_code
, insn_index
);
1774 /* Delete this test/value. */
1775 for (j
= i
; j
< len
- 2; j
++)
1776 tests
[j
] = tests
[j
+ 2];
1782 tests
[i
+ 1] = newval
;
1785 /* If the last test in a COND has the same value
1786 as the default value, that test isn't needed. */
1788 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1791 /* See if we changed anything. */
1792 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1795 for (i
= 0; i
< len
; i
++)
1796 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1804 if (GET_CODE (defval
) == COND
)
1805 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1813 rtx newexp
= rtx_alloc (COND
);
1815 XVEC (newexp
, 0) = rtvec_alloc (len
);
1816 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1817 XEXP (newexp
, 1) = new_defval
;
1824 /* Remove an insn entry from an attribute value. */
1827 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1829 struct insn_ent
*previe
;
1831 if (av
->first_insn
== ie
)
1832 av
->first_insn
= ie
->next
;
1835 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1837 previe
->next
= ie
->next
;
1841 if (ie
->def
->insn_code
== -1)
1842 av
->has_asm_insn
= 0;
1847 /* Insert an insn entry in an attribute value list. */
1850 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1852 ie
->next
= av
->first_insn
;
1853 av
->first_insn
= ie
;
1855 if (ie
->def
->insn_code
== -1)
1856 av
->has_asm_insn
= 1;
1861 /* This is a utility routine to take an expression that is a tree of either
1862 AND or IOR expressions and insert a new term. The new term will be
1863 inserted at the right side of the first node whose code does not match
1864 the root. A new node will be created with the root's code. Its left
1865 side will be the old right side and its right side will be the new
1868 If the `term' is itself a tree, all its leaves will be inserted. */
1871 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1875 /* Avoid consing in some special cases. */
1876 if (code
== AND
&& term
== true_rtx
)
1878 if (code
== AND
&& term
== false_rtx
)
1880 if (code
== AND
&& exp
== true_rtx
)
1882 if (code
== AND
&& exp
== false_rtx
)
1884 if (code
== IOR
&& term
== true_rtx
)
1886 if (code
== IOR
&& term
== false_rtx
)
1888 if (code
== IOR
&& exp
== true_rtx
)
1890 if (code
== IOR
&& exp
== false_rtx
)
1892 if (attr_equal_p (exp
, term
))
1895 if (GET_CODE (term
) == code
)
1897 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1898 insn_code
, insn_index
);
1899 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1900 insn_code
, insn_index
);
1905 if (GET_CODE (exp
) == code
)
1907 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1908 term
, insn_code
, insn_index
);
1909 if (new_rtx
!= XEXP (exp
, 1))
1910 /* Make a copy of this expression and call recursively. */
1911 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1917 /* Insert the new term. */
1918 newexp
= attr_rtx (code
, exp
, term
);
1921 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1924 /* If we have an expression which AND's a bunch of
1925 (not (eq_attrq "alternative" "n"))
1926 terms, we may have covered all or all but one of the possible alternatives.
1927 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1929 This routine is passed an expression and either AND or IOR. It returns a
1930 bitmask indicating which alternatives are mentioned within EXP. */
1933 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1936 if (GET_CODE (exp
) == code
)
1937 return compute_alternative_mask (XEXP (exp
, 0), code
)
1938 | compute_alternative_mask (XEXP (exp
, 1), code
);
1940 else if (code
== AND
&& GET_CODE (exp
) == NOT
1941 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1942 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1943 string
= XSTR (XEXP (exp
, 0), 1);
1945 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1946 && XSTR (exp
, 0) == alternative_name
)
1947 string
= XSTR (exp
, 1);
1949 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1951 if (code
== AND
&& XINT (exp
, 1))
1952 return XINT (exp
, 0);
1954 if (code
== IOR
&& !XINT (exp
, 1))
1955 return XINT (exp
, 0);
1963 return ((uint64_t) 1) << (string
[0] - '0');
1964 return ((uint64_t) 1) << atoi (string
);
1967 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1968 attribute with the value represented by that bit. */
1971 make_alternative_compare (uint64_t mask
)
1973 return mk_attr_alt (mask
);
1976 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1977 of "attr" for this insn code. From that value, we can compute a test
1978 showing when the EQ_ATTR will be true. This routine performs that
1979 computation. If a test condition involves an address, we leave the EQ_ATTR
1980 intact because addresses are only valid for the `length' attribute.
1982 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1983 it refers. VALUE is the value of that attribute for the insn
1984 corresponding to INSN_CODE and INSN_INDEX. */
1987 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1988 int insn_code
, int insn_index
)
1995 while (GET_CODE (value
) == ATTR
)
1997 struct attr_value
*av
= NULL
;
1999 attr
= find_attr (&XSTR (value
, 0), 0);
2001 if (insn_code_values
)
2003 struct attr_value_list
*iv
;
2004 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2005 if (iv
->attr
== attr
)
2013 struct insn_ent
*ie
;
2014 for (av
= attr
->first_value
; av
; av
= av
->next
)
2015 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2016 if (ie
->def
->insn_code
== insn_code
)
2026 switch (GET_CODE (value
))
2029 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2040 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2041 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
2042 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
2043 for (p
= string
; *p
; p
++)
2046 newexp
= attr_rtx (EQ
, value
,
2047 attr_rtx (SYMBOL_REF
,
2048 DEF_ATTR_STRING (string
)));
2053 /* We construct an IOR of all the cases for which the
2054 requested attribute value is present. Since we start with
2055 FALSE, if it is not present, FALSE will be returned.
2057 Each case is the AND of the NOT's of the previous conditions with the
2058 current condition; in the default case the current condition is TRUE.
2060 For each possible COND value, call ourselves recursively.
2062 The extra TRUE and FALSE expressions will be eliminated by another
2063 call to the simplification routine. */
2068 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2070 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2071 insn_code
, insn_index
);
2073 right
= insert_right_side (AND
, andexp
, this_cond
,
2074 insn_code
, insn_index
);
2075 right
= insert_right_side (AND
, right
,
2076 evaluate_eq_attr (exp
, attr
,
2079 insn_code
, insn_index
),
2080 insn_code
, insn_index
);
2081 orexp
= insert_right_side (IOR
, orexp
, right
,
2082 insn_code
, insn_index
);
2084 /* Add this condition into the AND expression. */
2085 newexp
= attr_rtx (NOT
, this_cond
);
2086 andexp
= insert_right_side (AND
, andexp
, newexp
,
2087 insn_code
, insn_index
);
2090 /* Handle the default case. */
2091 right
= insert_right_side (AND
, andexp
,
2092 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2093 insn_code
, insn_index
),
2094 insn_code
, insn_index
);
2095 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2102 /* If uses an address, must return original expression. But set the
2103 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2106 walk_attr_value (newexp
);
2110 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2111 return copy_rtx_unchanging (exp
);
2118 /* This routine is called when an AND of a term with a tree of AND's is
2119 encountered. If the term or its complement is present in the tree, it
2120 can be replaced with TRUE or FALSE, respectively.
2122 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2123 be true and hence are complementary.
2125 There is one special case: If we see
2126 (and (not (eq_attr "att" "v1"))
2127 (eq_attr "att" "v2"))
2128 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2129 replace the term, not anything in the AND tree. So we pass a pointer to
2133 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2138 int left_eliminates_term
, right_eliminates_term
;
2140 if (GET_CODE (exp
) == AND
)
2142 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2143 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2144 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2146 newexp
= attr_rtx (AND
, left
, right
);
2148 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2152 else if (GET_CODE (exp
) == IOR
)
2154 /* For the IOR case, we do the same as above, except that we can
2155 only eliminate `term' if both sides of the IOR would do so. */
2157 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2158 left_eliminates_term
= (temp
== true_rtx
);
2161 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2162 right_eliminates_term
= (temp
== true_rtx
);
2164 if (left_eliminates_term
&& right_eliminates_term
)
2167 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2169 newexp
= attr_rtx (IOR
, left
, right
);
2171 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2175 /* Check for simplifications. Do some extra checking here since this
2176 routine is called so many times. */
2181 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2184 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2187 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2189 if (attr_alt_subset_p (*pterm
, exp
))
2192 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2195 if (attr_alt_subset_p (exp
, *pterm
))
2201 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2203 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2206 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2212 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2213 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2215 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2218 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2224 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2225 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2227 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2230 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2236 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2238 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2242 else if (GET_CODE (exp
) == NOT
)
2244 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2248 else if (GET_CODE (*pterm
) == NOT
)
2250 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2254 else if (attr_equal_p (exp
, *pterm
))
2260 /* Similar to `simplify_and_tree', but for IOR trees. */
2263 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2268 int left_eliminates_term
, right_eliminates_term
;
2270 if (GET_CODE (exp
) == IOR
)
2272 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2273 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2274 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2276 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2278 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2282 else if (GET_CODE (exp
) == AND
)
2284 /* For the AND case, we do the same as above, except that we can
2285 only eliminate `term' if both sides of the AND would do so. */
2287 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2288 left_eliminates_term
= (temp
== false_rtx
);
2291 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2292 right_eliminates_term
= (temp
== false_rtx
);
2294 if (left_eliminates_term
&& right_eliminates_term
)
2297 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2299 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2301 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2305 if (attr_equal_p (exp
, *pterm
))
2308 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2311 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2314 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2315 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2316 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2319 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2320 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2321 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2327 /* Simplify test expression and use temporary obstack in order to avoid
2328 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2329 and avoid unnecessary copying if possible. */
2332 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2335 struct obstack
*old
;
2336 if (ATTR_IND_SIMPLIFIED_P (exp
))
2339 rtl_obstack
= temp_obstack
;
2340 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2342 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2344 return attr_copy_rtx (x
);
2347 /* Returns true if S1 is a subset of S2. */
2350 attr_alt_subset_p (rtx s1
, rtx s2
)
2352 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2355 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2358 return !(XINT (s1
, 0) & XINT (s2
, 0));
2364 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2371 /* Returns true if S1 is a subset of complement of S2. */
2374 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2376 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2379 return !(XINT (s1
, 0) & XINT (s2
, 0));
2382 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2385 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2395 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2398 attr_alt_intersection (rtx s1
, rtx s2
)
2400 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2402 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2405 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2408 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2411 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2414 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2419 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2424 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2427 attr_alt_union (rtx s1
, rtx s2
)
2429 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2431 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2434 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2437 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2440 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2443 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2449 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2453 /* Return EQ_ATTR_ALT expression representing complement of S. */
2456 attr_alt_complement (rtx s
)
2458 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2460 XINT (result
, 0) = XINT (s
, 0);
2461 XINT (result
, 1) = 1 - XINT (s
, 1);
2466 /* Return EQ_ATTR_ALT expression representing set containing elements set
2470 mk_attr_alt (uint64_t e
)
2472 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2474 XINT (result
, 0) = e
;
2475 XINT (result
, 1) = 0;
2480 /* Given an expression, see if it can be simplified for a particular insn
2481 code based on the values of other attributes being tested. This can
2482 eliminate nested get_attr_... calls.
2484 Note that if an endless recursion is specified in the patterns, the
2485 optimization will loop. However, it will do so in precisely the cases where
2486 an infinite recursion loop could occur during compilation. It's better that
2490 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2493 struct attr_desc
*attr
;
2494 struct attr_value
*av
;
2495 struct insn_ent
*ie
;
2496 struct attr_value_list
*iv
;
2499 bool left_alt
, right_alt
;
2501 /* Don't re-simplify something we already simplified. */
2502 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2505 switch (GET_CODE (exp
))
2508 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2509 if (left
== false_rtx
)
2511 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2512 if (right
== false_rtx
)
2515 if (GET_CODE (left
) == EQ_ATTR_ALT
2516 && GET_CODE (right
) == EQ_ATTR_ALT
)
2518 exp
= attr_alt_intersection (left
, right
);
2519 return simplify_test_exp (exp
, insn_code
, insn_index
);
2522 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2523 present on both sides, apply the distributive law since this will
2524 yield simplifications. */
2525 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2526 && compute_alternative_mask (left
, IOR
)
2527 && compute_alternative_mask (right
, IOR
))
2529 if (GET_CODE (left
) == IOR
)
2530 std::swap (left
, right
);
2532 newexp
= attr_rtx (IOR
,
2533 attr_rtx (AND
, left
, XEXP (right
, 0)),
2534 attr_rtx (AND
, left
, XEXP (right
, 1)));
2536 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2539 /* Try with the term on both sides. */
2540 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2541 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2542 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2544 if (left
== false_rtx
|| right
== false_rtx
)
2546 else if (left
== true_rtx
)
2550 else if (right
== true_rtx
)
2554 /* See if all or all but one of the insn's alternatives are specified
2555 in this tree. Optimize if so. */
2557 if (GET_CODE (left
) == NOT
)
2558 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2559 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2561 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2564 if (GET_CODE (right
) == NOT
)
2565 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2566 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2568 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2569 && XINT (right
, 1));
2572 && (GET_CODE (left
) == AND
2574 || GET_CODE (right
) == AND
2577 i
= compute_alternative_mask (exp
, AND
);
2578 if (i
& ~insn_alternatives
[insn_code
])
2579 fatal ("invalid alternative specified for pattern number %d",
2582 /* If all alternatives are excluded, this is false. */
2583 i
^= insn_alternatives
[insn_code
];
2586 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2588 /* If just one excluded, AND a comparison with that one to the
2589 front of the tree. The others will be eliminated by
2590 optimization. We do not want to do this if the insn has one
2591 alternative and we have tested none of them! */
2592 left
= make_alternative_compare (i
);
2593 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2594 newexp
= attr_rtx (AND
, left
, right
);
2596 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2600 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2602 newexp
= attr_rtx (AND
, left
, right
);
2603 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2608 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2609 if (left
== true_rtx
)
2611 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2612 if (right
== true_rtx
)
2615 if (GET_CODE (left
) == EQ_ATTR_ALT
2616 && GET_CODE (right
) == EQ_ATTR_ALT
)
2618 exp
= attr_alt_union (left
, right
);
2619 return simplify_test_exp (exp
, insn_code
, insn_index
);
2622 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2623 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2624 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2626 if (right
== true_rtx
|| left
== true_rtx
)
2628 else if (left
== false_rtx
)
2632 else if (right
== false_rtx
)
2637 /* Test for simple cases where the distributive law is useful. I.e.,
2638 convert (ior (and (x) (y))
2644 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2645 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2647 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2649 left
= XEXP (left
, 0);
2651 newexp
= attr_rtx (AND
, left
, right
);
2652 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2656 convert (ior (and (y) (x))
2658 to (and (ior (y) (z))
2660 Note that we want the common term to stay at the end.
2663 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2664 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2666 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2669 right
= XEXP (right
, 1);
2670 newexp
= attr_rtx (AND
, left
, right
);
2671 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2674 /* See if all or all but one of the insn's alternatives are specified
2675 in this tree. Optimize if so. */
2677 else if (insn_code
>= 0
2678 && (GET_CODE (left
) == IOR
2679 || (GET_CODE (left
) == EQ_ATTR_ALT
2681 || (GET_CODE (left
) == EQ_ATTR
2682 && XSTR (left
, 0) == alternative_name
)
2683 || GET_CODE (right
) == IOR
2684 || (GET_CODE (right
) == EQ_ATTR_ALT
2685 && !XINT (right
, 1))
2686 || (GET_CODE (right
) == EQ_ATTR
2687 && XSTR (right
, 0) == alternative_name
)))
2689 i
= compute_alternative_mask (exp
, IOR
);
2690 if (i
& ~insn_alternatives
[insn_code
])
2691 fatal ("invalid alternative specified for pattern number %d",
2694 /* If all alternatives are included, this is true. */
2695 i
^= insn_alternatives
[insn_code
];
2698 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2700 /* If just one excluded, IOR a comparison with that one to the
2701 front of the tree. The others will be eliminated by
2702 optimization. We do not want to do this if the insn has one
2703 alternative and we have tested none of them! */
2704 left
= make_alternative_compare (i
);
2705 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2706 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2708 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2712 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2714 newexp
= attr_rtx (IOR
, left
, right
);
2715 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2720 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2722 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2723 insn_code
, insn_index
);
2727 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2728 if (GET_CODE (left
) == NOT
)
2729 return XEXP (left
, 0);
2731 if (left
== false_rtx
)
2733 if (left
== true_rtx
)
2736 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2738 exp
= attr_alt_complement (left
);
2739 return simplify_test_exp (exp
, insn_code
, insn_index
);
2742 /* Try to apply De`Morgan's laws. */
2743 if (GET_CODE (left
) == IOR
)
2745 newexp
= attr_rtx (AND
,
2746 attr_rtx (NOT
, XEXP (left
, 0)),
2747 attr_rtx (NOT
, XEXP (left
, 1)));
2749 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2751 else if (GET_CODE (left
) == AND
)
2753 newexp
= attr_rtx (IOR
,
2754 attr_rtx (NOT
, XEXP (left
, 0)),
2755 attr_rtx (NOT
, XEXP (left
, 1)));
2757 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2759 else if (left
!= XEXP (exp
, 0))
2761 newexp
= attr_rtx (NOT
, left
);
2767 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2771 if (XSTR (exp
, 0) == alternative_name
)
2773 newexp
= mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
2777 /* Look at the value for this insn code in the specified attribute.
2778 We normally can replace this comparison with the condition that
2779 would give this insn the values being tested for. */
2781 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2786 if (insn_code_values
)
2788 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2789 if (iv
->attr
== attr
)
2797 for (av
= attr
->first_value
; av
; av
= av
->next
)
2798 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2799 if (ie
->def
->insn_code
== insn_code
)
2806 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2807 insn_code
, insn_index
);
2808 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2809 if (attr_rtx_cost (x
) < 7)
2819 /* We have already simplified this expression. Simplifying it again
2820 won't buy anything unless we weren't given a valid insn code
2821 to process (i.e., we are canonicalizing something.). */
2823 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2824 return copy_rtx_unchanging (newexp
);
2829 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2830 otherwise return 0. */
2833 tests_attr_p (rtx p
, struct attr_desc
*attr
)
2838 if (GET_CODE (p
) == EQ_ATTR
)
2840 if (XSTR (p
, 0) != attr
->name
)
2845 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2846 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2847 for (i
= 0; i
< ie
; i
++)
2852 if (tests_attr_p (XEXP (p
, i
), attr
))
2857 je
= XVECLEN (p
, i
);
2858 for (j
= 0; j
< je
; ++j
)
2859 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2868 /* Calculate a topological sorting of all attributes so that
2869 all attributes only depend on attributes in front of it.
2870 Place the result in *RET (which is a pointer to an array of
2871 attr_desc pointers), and return the size of that array. */
2874 get_attr_order (struct attr_desc
***ret
)
2878 struct attr_desc
*attr
;
2879 struct attr_desc
**all
, **sorted
;
2881 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2882 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2884 all
= XNEWVEC (struct attr_desc
*, num
);
2885 sorted
= XNEWVEC (struct attr_desc
*, num
);
2886 handled
= XCNEWVEC (char, num
);
2888 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2889 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2893 for (i
= 0; i
< num
; i
++)
2894 if (all
[i
]->is_const
)
2895 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2897 /* We have only few attributes hence we can live with the inner
2898 loop being O(n^2), unlike the normal fast variants of topological
2902 for (i
= 0; i
< num
; i
++)
2905 /* Let's see if I depends on anything interesting. */
2907 for (k
= 0; k
< num
; k
++)
2910 struct attr_value
*av
;
2911 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2912 if (av
->num_insns
!= 0)
2913 if (tests_attr_p (av
->value
, all
[k
]))
2917 /* Something in I depends on K. */
2922 /* Nothing in I depended on anything intersting, so
2925 sorted
[j
++] = all
[i
];
2931 for (j
= 0; j
< num
; j
++)
2933 struct attr_desc
*attr2
;
2934 struct attr_value
*av
;
2937 fprintf (stderr
, "%s depends on: ", attr
->name
);
2938 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2939 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2940 if (!attr2
->is_const
)
2941 for (av
= attr
->first_value
; av
; av
= av
->next
)
2942 if (av
->num_insns
!= 0)
2943 if (tests_attr_p (av
->value
, attr2
))
2945 fprintf (stderr
, "%s, ", attr2
->name
);
2948 fprintf (stderr
, "\n");
2956 /* Optimize the attribute lists by seeing if we can determine conditional
2957 values from the known values of other attributes. This will save subroutine
2958 calls during the compilation. NUM_INSN_CODES is the number of unique
2959 instruction codes. */
2962 optimize_attrs (int num_insn_codes
)
2964 struct attr_desc
*attr
;
2965 struct attr_value
*av
;
2966 struct insn_ent
*ie
;
2969 struct attr_value_list
*ivbuf
;
2970 struct attr_value_list
*iv
;
2971 struct attr_desc
**topsort
;
2974 /* For each insn code, make a list of all the insn_ent's for it,
2975 for all values for all attributes. */
2977 if (num_insn_ents
== 0)
2980 /* Make 2 extra elements, for "code" values -2 and -1. */
2981 insn_code_values
= XCNEWVEC (struct attr_value_list
*, num_insn_codes
+ 2);
2983 /* Offset the table address so we can index by -2 or -1. */
2984 insn_code_values
+= 2;
2986 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2988 /* Create the chain of insn*attr values such that we see dependend
2989 attributes after their dependencies. As we use a stack via the
2990 next pointers start from the end of the topological order. */
2991 topnum
= get_attr_order (&topsort
);
2992 for (i
= topnum
- 1; i
>= 0; i
--)
2993 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
2994 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2996 iv
->attr
= topsort
[i
];
2999 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
3000 insn_code_values
[ie
->def
->insn_code
] = iv
;
3005 /* Sanity check on num_insn_ents. */
3006 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
3008 /* Process one insn code at a time. */
3009 for (i
= -2; i
< num_insn_codes
; i
++)
3011 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3012 We use it to mean "already simplified for this insn". */
3013 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3014 clear_struct_flag (iv
->av
->value
);
3016 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3018 struct obstack
*old
= rtl_obstack
;
3023 if (GET_CODE (av
->value
) != COND
)
3026 rtl_obstack
= temp_obstack
;
3028 while (GET_CODE (newexp
) == COND
)
3030 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
3031 ie
->def
->insn_index
);
3032 if (newexp2
== newexp
)
3038 /* If we created a new value for this instruction, and it's
3039 cheaper than the old value, and overall cheap, use that
3040 one as specific value for the current instruction.
3041 The last test is to avoid exploding the get_attr_ function
3042 sizes for no much gain. */
3043 if (newexp
!= av
->value
3044 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
3045 && attr_rtx_cost (newexp
) < 26
3048 newexp
= attr_copy_rtx (newexp
);
3049 remove_insn_ent (av
, ie
);
3050 av
= get_attr_value (ie
->def
->loc
, newexp
, attr
,
3051 ie
->def
->insn_code
);
3053 insert_insn_ent (av
, ie
);
3059 free (insn_code_values
- 2);
3060 insn_code_values
= NULL
;
3063 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3066 clear_struct_flag (rtx x
)
3073 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3074 if (ATTR_IND_SIMPLIFIED_P (x
))
3077 code
= GET_CODE (x
);
3096 /* Compare the elements. If any pair of corresponding elements
3097 fail to match, return 0 for the whole things. */
3099 fmt
= GET_RTX_FORMAT (code
);
3100 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3106 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3107 clear_struct_flag (XVECEXP (x
, i
, j
));
3111 clear_struct_flag (XEXP (x
, i
));
3117 /* Add attribute value NAME to the beginning of ATTR's list. */
3120 add_attr_value (struct attr_desc
*attr
, const char *name
)
3122 struct attr_value
*av
;
3124 av
= oballoc (struct attr_value
);
3125 av
->value
= attr_rtx (CONST_STRING
, name
);
3126 av
->next
= attr
->first_value
;
3127 attr
->first_value
= av
;
3128 av
->first_insn
= NULL
;
3130 av
->has_asm_insn
= 0;
3133 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3136 gen_attr (md_rtx_info
*info
)
3138 struct enum_type
*et
;
3139 struct enum_value
*ev
;
3140 struct attr_desc
*attr
;
3141 const char *name_ptr
;
3143 rtx def
= info
->def
;
3145 /* Make a new attribute structure. Check for duplicate by looking at
3146 attr->default_val, since it is initialized by this routine. */
3147 attr
= find_attr (&XSTR (def
, 0), 1);
3148 if (attr
->default_val
)
3150 error_at (info
->loc
, "duplicate definition for attribute %s",
3152 message_at (attr
->loc
, "previous definition");
3155 attr
->loc
= info
->loc
;
3157 if (GET_CODE (def
) == DEFINE_ENUM_ATTR
)
3159 attr
->enum_name
= XSTR (def
, 1);
3160 et
= lookup_enum_type (XSTR (def
, 1));
3161 if (!et
|| !et
->md_p
)
3162 error_at (info
->loc
, "No define_enum called `%s' defined",
3165 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3166 add_attr_value (attr
, ev
->name
);
3168 else if (*XSTR (def
, 1) == '\0')
3169 attr
->is_numeric
= 1;
3172 name_ptr
= XSTR (def
, 1);
3173 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3174 add_attr_value (attr
, p
);
3177 if (GET_CODE (XEXP (def
, 2)) == CONST
)
3180 if (attr
->is_numeric
)
3181 error_at (info
->loc
,
3182 "constant attributes may not take numeric values");
3184 /* Get rid of the CONST node. It is allowed only at top-level. */
3185 XEXP (def
, 2) = XEXP (XEXP (def
, 2), 0);
3188 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3189 error_at (info
->loc
, "`length' attribute must take numeric values");
3191 /* Set up the default value. */
3192 XEXP (def
, 2) = check_attr_value (info
->loc
, XEXP (def
, 2), attr
);
3193 attr
->default_val
= get_attr_value (info
->loc
, XEXP (def
, 2), attr
, -2);
3196 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3197 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3198 number of alternatives as this should be checked elsewhere. */
3201 count_alternatives (rtx exp
)
3206 if (GET_CODE (exp
) == MATCH_OPERAND
)
3207 return n_comma_elts (XSTR (exp
, 2));
3209 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3210 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3215 n
= count_alternatives (XEXP (exp
, i
));
3222 if (XVEC (exp
, i
) != NULL
)
3223 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3225 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3234 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3235 `alternative' attribute. */
3238 compares_alternatives_p (rtx exp
)
3243 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3246 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3247 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3252 if (compares_alternatives_p (XEXP (exp
, i
)))
3257 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3258 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3266 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3269 gen_insn (md_rtx_info
*info
)
3271 struct insn_def
*id
;
3272 rtx def
= info
->def
;
3274 id
= oballoc (struct insn_def
);
3278 id
->loc
= info
->loc
;
3280 switch (GET_CODE (def
))
3283 id
->insn_code
= info
->index
;
3284 id
->insn_index
= insn_index_number
;
3285 id
->num_alternatives
= count_alternatives (def
);
3286 if (id
->num_alternatives
== 0)
3287 id
->num_alternatives
= 1;
3291 case DEFINE_PEEPHOLE
:
3292 id
->insn_code
= info
->index
;
3293 id
->insn_index
= insn_index_number
;
3294 id
->num_alternatives
= count_alternatives (def
);
3295 if (id
->num_alternatives
== 0)
3296 id
->num_alternatives
= 1;
3300 case DEFINE_ASM_ATTRIBUTES
:
3302 id
->insn_index
= -1;
3303 id
->num_alternatives
= 1;
3305 got_define_asm_attributes
= 1;
3313 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3314 true or annul false is specified, and make a `struct delay_desc'. */
3317 gen_delay (md_rtx_info
*info
)
3319 struct delay_desc
*delay
;
3322 rtx def
= info
->def
;
3323 if (XVECLEN (def
, 1) % 3 != 0)
3325 error_at (info
->loc
, "number of elements in DEFINE_DELAY must"
3326 " be multiple of three");
3330 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3332 if (XVECEXP (def
, 1, i
+ 1))
3333 have_annul_true
= 1;
3334 if (XVECEXP (def
, 1, i
+ 2))
3335 have_annul_false
= 1;
3338 delay
= oballoc (struct delay_desc
);
3340 delay
->num
= ++num_delays
;
3341 delay
->next
= delays
;
3342 delay
->loc
= info
->loc
;
3346 /* Names of attributes that could be possibly cached. */
3347 static const char *cached_attrs
[32];
3348 /* Number of such attributes. */
3349 static int cached_attr_count
;
3350 /* Bitmasks of possibly cached attributes. */
3351 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3352 static unsigned int attrs_to_cache
;
3353 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3355 /* Finds non-const attributes that could be possibly cached.
3356 When create is TRUE, fills in cached_attrs array.
3357 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3361 find_attrs_to_cache (rtx exp
, bool create
)
3365 struct attr_desc
*attr
;
3370 switch (GET_CODE (exp
))
3373 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3374 find_attrs_to_cache (XEXP (exp
, 0), create
);
3378 name
= XSTR (exp
, 0);
3379 if (name
== alternative_name
)
3381 for (i
= 0; i
< cached_attr_count
; i
++)
3382 if (name
== cached_attrs
[i
])
3384 if ((attrs_seen_once
& (1U << i
)) != 0)
3385 attrs_seen_more_than_once
|= (1U << i
);
3387 attrs_seen_once
|= (1U << i
);
3392 attr
= find_attr (&name
, 0);
3396 if (cached_attr_count
== 32)
3398 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3399 attrs_seen_once
|= (1U << cached_attr_count
);
3400 cached_attr_count
++;
3405 find_attrs_to_cache (XEXP (exp
, 0), create
);
3406 find_attrs_to_cache (XEXP (exp
, 1), create
);
3410 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3411 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3419 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3420 We use AND and IOR both for logical and bit-wise operations, so
3421 interpret them as logical unless they are inside a comparison expression.
3423 An outermost pair of parentheses is emitted around this C expression unless
3424 EMIT_PARENS is false. */
3426 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3427 #define FLG_BITWISE 1
3428 /* Set if cached attribute will be known initialized in else block after
3429 this condition. This is true for LHS of toplevel && and || and
3430 even for RHS of ||, but not for RHS of &&. */
3432 /* Set if cached attribute will be known initialized in then block after
3433 this condition. This is true for LHS of toplevel && and || and
3434 even for RHS of &&, but not for RHS of ||. */
3435 #define FLG_INSIDE 4
3436 /* Cleared when an operand of &&. */
3437 #define FLG_OUTSIDE_AND 8
3440 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
,
3441 bool emit_parens
= true)
3443 int comparison_operator
= 0;
3445 struct attr_desc
*attr
;
3448 fprintf (outf
, "(");
3450 code
= GET_CODE (exp
);
3453 /* Binary operators. */
3456 fprintf (outf
, "(unsigned) ");
3462 comparison_operator
= FLG_BITWISE
;
3465 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3466 case AND
: case IOR
: case XOR
:
3467 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3468 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3470 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3471 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3472 flags
| comparison_operator
);
3477 flags
&= ~FLG_OUTSIDE_AND
;
3478 if (GET_CODE (XEXP (exp
, 0)) == code
3479 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3480 || (GET_CODE (XEXP (exp
, 0)) == NOT
3481 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3483 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3485 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3490 fprintf (outf
, " == ");
3493 fprintf (outf
, " != ");
3496 fprintf (outf
, " >= ");
3499 fprintf (outf
, " > ");
3502 fprintf (outf
, " >= (unsigned) ");
3505 fprintf (outf
, " > (unsigned) ");
3508 fprintf (outf
, " <= ");
3511 fprintf (outf
, " < ");
3514 fprintf (outf
, " <= (unsigned) ");
3517 fprintf (outf
, " < (unsigned) ");
3520 fprintf (outf
, " + ");
3523 fprintf (outf
, " - ");
3526 fprintf (outf
, " * ");
3529 fprintf (outf
, " / ");
3532 fprintf (outf
, " %% ");
3535 if (flags
& FLG_BITWISE
)
3536 fprintf (outf
, " & ");
3538 fprintf (outf
, " && ");
3541 if (flags
& FLG_BITWISE
)
3542 fprintf (outf
, " | ");
3544 fprintf (outf
, " || ");
3547 fprintf (outf
, " ^ ");
3550 fprintf (outf
, " << ");
3554 fprintf (outf
, " >> ");
3562 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3563 cached_x is only known to be initialized in then block. */
3564 flags
&= ~FLG_AFTER
;
3566 else if (code
== IOR
)
3568 if (flags
& FLG_OUTSIDE_AND
)
3569 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3570 cached_x is only known to be initialized in else block
3571 and else if conditions. */
3572 flags
&= ~FLG_INSIDE
;
3574 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3576 cached_x is not know to be initialized anywhere. */
3577 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3579 if ((code
== AND
|| code
== IOR
)
3580 && (GET_CODE (XEXP (exp
, 1)) == code
3581 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3582 || (GET_CODE (XEXP (exp
, 1)) == NOT
3583 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3585 bool need_parens
= true;
3587 /* No need to emit parentheses around the right-hand operand if we are
3588 continuing a chain of && or || (or & or |). */
3589 if (GET_CODE (XEXP (exp
, 1)) == code
)
3590 need_parens
= false;
3593 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
,
3597 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3598 flags
| comparison_operator
);
3602 /* Special-case (not (eq_attrq "alternative" "x")) */
3603 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3605 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3607 fprintf (outf
, "which_alternative != %s",
3608 XSTR (XEXP (exp
, 0), 1));
3612 fprintf (outf
, "! ");
3614 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3618 /* Otherwise, fall through to normal unary operator. */
3621 /* Unary operators. */
3626 if (flags
& FLG_BITWISE
)
3627 fprintf (outf
, "~ ");
3629 fprintf (outf
, "! ");
3632 fprintf (outf
, "abs ");
3635 fprintf (outf
, "-");
3641 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3642 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3647 int set
= XINT (exp
, 0), bit
= 0;
3649 if (flags
& FLG_BITWISE
)
3650 fatal ("EQ_ATTR_ALT not valid inside comparison");
3653 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3655 if (!(set
& (set
- 1)))
3657 if (!(set
& 0xffff))
3680 fprintf (outf
, "which_alternative %s= %d",
3681 XINT (exp
, 1) ? "!" : "=", bit
);
3685 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3686 XINT (exp
, 1) ? "!" : "", set
);
3691 /* Comparison test of an attribute with a value. Most of these will
3692 have been removed by optimization. Handle "alternative"
3693 specially and give error if EQ_ATTR present inside a comparison. */
3695 if (flags
& FLG_BITWISE
)
3696 fatal ("EQ_ATTR not valid inside comparison");
3698 if (XSTR (exp
, 0) == alternative_name
)
3700 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3704 attr
= find_attr (&XSTR (exp
, 0), 0);
3707 /* Now is the time to expand the value of a constant attribute. */
3710 write_test_expr (outf
,
3711 evaluate_eq_attr (exp
, attr
,
3712 attr
->default_val
->value
,
3719 for (i
= 0; i
< cached_attr_count
; i
++)
3720 if (attr
->name
== cached_attrs
[i
])
3722 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3723 fprintf (outf
, "cached_%s", attr
->name
);
3724 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3726 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3727 attr
->name
, attr
->name
);
3728 if (flags
& FLG_AFTER
)
3729 attrs_cached_after
|= (1U << i
);
3730 if (flags
& FLG_INSIDE
)
3731 attrs_cached_inside
|= (1U << i
);
3732 attrs_cached
|= (1U << i
);
3735 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3736 fprintf (outf
, " == ");
3737 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3741 /* Comparison test of flags for define_delays. */
3743 if (flags
& FLG_BITWISE
)
3744 fatal ("ATTR_FLAG not valid inside comparison");
3745 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3748 /* See if an operand matches a predicate. */
3750 /* If only a mode is given, just ensure the mode matches the operand.
3751 If neither a mode nor predicate is given, error. */
3752 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3754 if (GET_MODE (exp
) == VOIDmode
)
3755 fatal ("null MATCH_OPERAND specified as test");
3757 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3758 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3761 fprintf (outf
, "%s (operands[%d], %smode)",
3762 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3765 /* Constant integer. */
3767 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3771 fprint_c_condition (outf
, XSTR (exp
, 0));
3772 if (flags
& FLG_BITWISE
)
3773 fprintf (outf
, " != 0");
3776 /* A random C expression. */
3778 fprint_c_condition (outf
, XSTR (exp
, 0));
3781 /* The address of the branch target. */
3784 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3785 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3789 /* The address of the current insn. We implement this actually as the
3790 address of the current insn for backward branches, but the last
3791 address of the next insn for forward branches, and both with
3792 adjustments that account for the worst-case possible stretching of
3793 intervening alignments between this insn and its destination. */
3794 fprintf (outf
, "insn_current_reference_address (insn)");
3798 fprintf (outf
, "%s", XSTR (exp
, 0));
3802 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3803 fprintf (outf
, " ? ");
3804 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3805 fprintf (outf
, " : ");
3806 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3810 fatal ("bad RTX code `%s' in attribute calculation\n",
3811 GET_RTX_NAME (code
));
3815 fprintf (outf
, ")");
3817 return attrs_cached
;
3820 /* Given an attribute value, return the maximum CONST_STRING argument
3821 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3824 max_attr_value (rtx exp
, int *unknownp
)
3829 switch (GET_CODE (exp
))
3832 current_max
= atoi (XSTR (exp
, 0));
3836 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3837 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3839 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3840 if (n
> current_max
)
3846 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3847 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3848 if (n
> current_max
)
3854 current_max
= INT_MAX
;
3861 /* Given an attribute value, return the minimum CONST_STRING argument
3862 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3865 min_attr_value (rtx exp
, int *unknownp
)
3870 switch (GET_CODE (exp
))
3873 current_min
= atoi (XSTR (exp
, 0));
3877 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3878 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3880 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3881 if (n
< current_min
)
3887 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3888 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3889 if (n
< current_min
)
3895 current_min
= INT_MAX
;
3902 /* Given an attribute value, return the result of ORing together all
3903 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3904 if the numeric value is not known. */
3907 or_attr_value (rtx exp
, int *unknownp
)
3912 switch (GET_CODE (exp
))
3915 current_or
= atoi (XSTR (exp
, 0));
3919 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3920 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3921 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3925 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3926 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3938 /* Scan an attribute value, possibly a conditional, and record what actions
3939 will be required to do any conditional tests in it.
3942 `must_extract' if we need to extract the insn operands
3943 `must_constrain' if we must compute `which_alternative'
3944 `address_used' if an address expression was used
3945 `length_used' if an (eq_attr "length" ...) was used
3949 walk_attr_value (rtx exp
)
3958 code
= GET_CODE (exp
);
3962 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3963 /* Since this is an arbitrary expression, it can look at anything.
3964 However, constant expressions do not depend on any particular
3966 must_extract
= must_constrain
= 1;
3975 must_extract
= must_constrain
= 1;
3979 if (XSTR (exp
, 0) == alternative_name
)
3980 must_extract
= must_constrain
= 1;
3981 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
4001 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
4006 walk_attr_value (XEXP (exp
, i
));
4010 if (XVEC (exp
, i
) != NULL
)
4011 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4012 walk_attr_value (XVECEXP (exp
, i
, j
));
4017 /* Write out a function to obtain the attribute for a given INSN. */
4020 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
4022 struct attr_value
*av
, *common_av
;
4025 /* Find the most used attribute value. Handle that as the `default' of the
4026 switch we will generate. */
4027 common_av
= find_most_used (attr
);
4029 /* Write out start of function, then all values with explicit `case' lines,
4030 then a `default', then the value with the most uses. */
4031 if (attr
->enum_name
)
4032 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4033 else if (!attr
->is_numeric
)
4034 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4036 fprintf (outf
, "int\n");
4038 /* If the attribute name starts with a star, the remainder is the name of
4039 the subroutine to use, instead of `get_attr_...'. */
4040 if (attr
->name
[0] == '*')
4041 fprintf (outf
, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4042 else if (attr
->is_const
== 0)
4043 fprintf (outf
, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4046 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4047 fprintf (outf
, "{\n");
4049 for (av
= attr
->first_value
; av
; av
= av
->next
)
4050 if (av
->num_insns
== 1)
4051 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4052 true_rtx
, av
->first_insn
->def
->insn_code
,
4053 av
->first_insn
->def
->insn_index
, 0);
4054 else if (av
->num_insns
!= 0)
4055 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4056 true_rtx
, -2, 0, 0);
4058 fprintf (outf
, "}\n\n");
4062 fprintf (outf
, "{\n");
4064 /* Find attributes that are worth caching in the conditions. */
4065 cached_attr_count
= 0;
4066 attrs_seen_more_than_once
= 0;
4067 for (av
= attr
->first_value
; av
; av
= av
->next
)
4069 attrs_seen_once
= 0;
4070 find_attrs_to_cache (av
->value
, true);
4072 /* Remove those that aren't worth caching from the array. */
4073 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4074 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4076 const char *name
= cached_attrs
[i
];
4077 struct attr_desc
*cached_attr
;
4079 cached_attrs
[j
] = name
;
4080 cached_attr
= find_attr (&name
, 0);
4081 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4082 if (cached_attr
->enum_name
)
4083 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4084 else if (!cached_attr
->is_numeric
)
4085 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4087 fprintf (outf
, " int");
4088 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4091 cached_attr_count
= j
;
4092 if (cached_attr_count
)
4093 fprintf (outf
, "\n");
4095 fprintf (outf
, " switch (recog_memoized (insn))\n");
4096 fprintf (outf
, " {\n");
4098 for (av
= attr
->first_value
; av
; av
= av
->next
)
4099 if (av
!= common_av
)
4100 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4102 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4103 fprintf (outf
, " }\n}\n\n");
4104 cached_attr_count
= 0;
4107 /* Given an AND tree of known true terms (because we are inside an `if' with
4108 that as the condition or are in an `else' clause) and an expression,
4109 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4110 the bulk of the work. */
4113 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4117 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4119 if (GET_CODE (known_true
) == AND
)
4121 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4122 insn_code
, insn_index
);
4123 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4124 insn_code
, insn_index
);
4129 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4135 /* Write out a series of tests and assignment statements to perform tests and
4136 sets of an attribute value. We are passed an indentation amount and prefix
4137 and suffix strings to write around each attribute value (e.g., "return"
4141 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
4142 const char *prefix
, const char *suffix
, rtx known_true
,
4143 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4145 if (GET_CODE (value
) == COND
)
4147 /* Assume the default value will be the default of the COND unless we
4148 find an always true expression. */
4149 rtx default_val
= XEXP (value
, 1);
4150 rtx our_known_true
= known_true
;
4155 if (cached_attr_count
)
4157 attrs_seen_once
= 0;
4158 attrs_seen_more_than_once
= 0;
4159 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4160 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4161 attrs_to_cache
|= attrs_seen_more_than_once
;
4164 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4169 /* Reset our_known_true after some time to not accumulate
4170 too much cruft (slowing down genattrtab). */
4172 our_known_true
= known_true
;
4173 testexp
= eliminate_known_true (our_known_true
,
4174 XVECEXP (value
, 0, i
),
4175 insn_code
, insn_index
);
4176 newexp
= attr_rtx (NOT
, testexp
);
4177 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4178 insn_code
, insn_index
);
4180 /* If the test expression is always true or if the next `known_true'
4181 expression is always false, this is the last case, so break
4182 out and let this value be the `else' case. */
4183 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4185 default_val
= XVECEXP (value
, 0, i
+ 1);
4189 /* Compute the expression to pass to our recursive call as being
4191 inner_true
= insert_right_side (AND
, our_known_true
,
4192 testexp
, insn_code
, insn_index
);
4194 /* If this is always false, skip it. */
4195 if (inner_true
== false_rtx
)
4198 attrs_cached_inside
= attrs_cached
;
4199 attrs_cached_after
= attrs_cached
;
4200 write_indent (outf
, indent
);
4201 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4203 write_test_expr (outf
, testexp
, attrs_cached
,
4204 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4205 attrs_cached
= attrs_cached_after
;
4206 fprintf (outf
, "\n");
4207 write_indent (outf
, indent
+ 2);
4208 fprintf (outf
, "{\n");
4210 write_attr_set (outf
, attr
, indent
+ 4,
4211 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4212 inner_true
, insn_code
, insn_index
,
4213 attrs_cached_inside
);
4214 write_indent (outf
, indent
+ 2);
4215 fprintf (outf
, "}\n");
4216 our_known_true
= newexp
;
4221 write_indent (outf
, indent
);
4222 fprintf (outf
, "else\n");
4223 write_indent (outf
, indent
+ 2);
4224 fprintf (outf
, "{\n");
4227 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4228 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4233 write_indent (outf
, indent
+ 2);
4234 fprintf (outf
, "}\n");
4239 write_indent (outf
, indent
);
4240 fprintf (outf
, "%s ", prefix
);
4241 write_attr_value (outf
, attr
, value
);
4242 fprintf (outf
, "%s\n", suffix
);
4246 /* Write a series of case statements for every instruction in list IE.
4247 INDENT is the amount of indentation to write before each case. */
4250 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4252 for (; ie
!= 0; ie
= ie
->next
)
4253 if (ie
->def
->insn_code
!= -1)
4255 write_indent (outf
, indent
);
4256 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4257 fprintf (outf
, "case %d: /* define_peephole, %s:%d */\n",
4258 ie
->def
->insn_code
, ie
->def
->loc
.filename
,
4259 ie
->def
->loc
.lineno
);
4261 fprintf (outf
, "case %d: /* %s */\n",
4262 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4266 /* Write out the computation for one attribute value. */
4269 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4270 int write_case_lines
, const char *prefix
, const char *suffix
,
4271 int indent
, rtx known_true
)
4273 if (av
->num_insns
== 0)
4276 if (av
->has_asm_insn
)
4278 write_indent (outf
, indent
);
4279 fprintf (outf
, "case -1:\n");
4280 write_indent (outf
, indent
+ 2);
4281 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4282 write_indent (outf
, indent
+ 2);
4283 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4284 write_indent (outf
, indent
+ 2);
4285 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4286 write_indent (outf
, indent
+ 2);
4287 fprintf (outf
, "/* FALLTHRU */\n");
4290 if (write_case_lines
)
4291 write_insn_cases (outf
, av
->first_insn
, indent
);
4294 write_indent (outf
, indent
);
4295 fprintf (outf
, "default:\n");
4298 /* See what we have to do to output this value. */
4299 must_extract
= must_constrain
= address_used
= 0;
4300 walk_attr_value (av
->value
);
4304 write_indent (outf
, indent
+ 2);
4305 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4307 else if (must_extract
)
4309 write_indent (outf
, indent
+ 2);
4310 fprintf (outf
, "extract_insn_cached (insn);\n");
4314 if (av
->num_insns
== 1)
4315 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4316 known_true
, av
->first_insn
->def
->insn_code
,
4317 av
->first_insn
->def
->insn_index
, 0);
4319 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4320 known_true
, -2, 0, 0);
4322 if (strncmp (prefix
, "return", 6))
4324 write_indent (outf
, indent
+ 2);
4325 fprintf (outf
, "break;\n");
4327 fprintf (outf
, "\n");
4330 /* Utilities to write in various forms. */
4333 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4335 if (attr
->is_numeric
)
4339 fprintf (outf
, "%d", num
);
4341 if (num
> 9 || num
< 0)
4342 fprintf (outf
, " /* %#x */", num
);
4346 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4347 fprintf (outf
, "_");
4348 write_upcase (outf
, s
);
4353 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4357 switch (GET_CODE (value
))
4360 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4364 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4368 fprint_c_condition (outf
, XSTR (value
, 0));
4373 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4374 if (attr
->enum_name
)
4375 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4376 else if (!attr
->is_numeric
)
4377 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4378 else if (!attr2
->is_numeric
)
4379 fprintf (outf
, "(int)");
4381 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4382 (attr2
->is_const
? "" : "insn"));
4403 write_attr_value (outf
, attr
, XEXP (value
, 0));
4407 write_attr_value (outf
, attr
, XEXP (value
, 1));
4416 write_upcase (FILE *outf
, const char *str
)
4420 /* The argument of TOUPPER should not have side effects. */
4421 fputc (TOUPPER (*str
), outf
);
4427 write_indent (FILE *outf
, int indent
)
4429 for (; indent
> 8; indent
-= 8)
4430 fprintf (outf
, "\t");
4432 for (; indent
; indent
--)
4433 fprintf (outf
, " ");
4436 /* If the target does not have annul-true or annul-false delay slots, this
4437 function will create a dummy eligible_for function on OUTF which always
4438 returns false. KIND will be annul_true or annul_false. */
4441 write_dummy_eligible_delay (FILE *outf
, const char *kind
)
4443 /* Write function prelude. */
4445 fprintf (outf
, "int\n");
4446 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4447 " int slot ATTRIBUTE_UNUSED,\n"
4448 " rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4449 " int flags ATTRIBUTE_UNUSED)\n",
4451 fprintf (outf
, "{\n");
4452 fprintf (outf
, " return 0;\n");
4453 fprintf (outf
, "}\n\n");
4456 /* Write a subroutine that is given an insn that requires a delay slot, a
4457 delay slot ordinal, and a candidate insn. It returns nonzero if the
4458 candidate can be placed in the specified delay slot of the insn.
4460 We can write as many as three subroutines. `eligible_for_delay'
4461 handles normal delay slots, `eligible_for_annul_true' indicates that
4462 the specified insn can be annulled if the branch is true, and likewise
4463 for `eligible_for_annul_false'.
4465 KIND is a string distinguishing these three cases ("delay", "annul_true",
4466 or "annul_false"). */
4469 write_eligible_delay (FILE *outf
, const char *kind
)
4471 struct delay_desc
*delay
;
4475 struct attr_desc
*attr
;
4476 struct attr_value
*av
, *common_av
;
4479 /* Compute the maximum number of delay slots required. We use the delay
4480 ordinal times this number plus one, plus the slot number as an index into
4481 the appropriate predicate to test. */
4483 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4484 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4485 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4487 /* Write function prelude. */
4489 fprintf (outf
, "int\n");
4490 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4491 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4493 fprintf (outf
, "{\n");
4494 fprintf (outf
, " rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4495 fprintf (outf
, "\n");
4496 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4497 fprintf (outf
, "\n");
4498 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4499 converts a compound instruction into a loop. */
4500 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4501 fprintf (outf
, " return 0;\n");
4502 fprintf (outf
, "\n");
4504 /* If more than one delay type, find out which type the delay insn is. */
4508 attr
= find_attr (&delay_type_str
, 0);
4510 common_av
= find_most_used (attr
);
4512 fprintf (outf
, " insn = delay_insn;\n");
4513 fprintf (outf
, " switch (recog_memoized (insn))\n");
4514 fprintf (outf
, " {\n");
4516 sprintf (str
, " * %d;\n break;", max_slots
);
4517 for (av
= attr
->first_value
; av
; av
= av
->next
)
4518 if (av
!= common_av
)
4519 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4521 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4522 fprintf (outf
, " }\n\n");
4524 /* Ensure matched. Otherwise, shouldn't have been called. */
4525 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4528 /* If just one type of delay slot, write simple switch. */
4529 if (num_delays
== 1 && max_slots
== 1)
4531 fprintf (outf
, " insn = candidate_insn;\n");
4532 fprintf (outf
, " switch (recog_memoized (insn))\n");
4533 fprintf (outf
, " {\n");
4535 attr
= find_attr (&delay_1_0_str
, 0);
4537 common_av
= find_most_used (attr
);
4539 for (av
= attr
->first_value
; av
; av
= av
->next
)
4540 if (av
!= common_av
)
4541 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4543 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4544 fprintf (outf
, " }\n");
4549 /* Write a nested CASE. The first indicates which condition we need to
4550 test, and the inner CASE tests the condition. */
4551 fprintf (outf
, " insn = candidate_insn;\n");
4552 fprintf (outf
, " switch (slot)\n");
4553 fprintf (outf
, " {\n");
4555 for (delay
= delays
; delay
; delay
= delay
->next
)
4556 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4558 fprintf (outf
, " case %d:\n",
4559 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4560 fprintf (outf
, " switch (recog_memoized (insn))\n");
4561 fprintf (outf
, "\t{\n");
4563 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4565 attr
= find_attr (&pstr
, 0);
4567 common_av
= find_most_used (attr
);
4569 for (av
= attr
->first_value
; av
; av
= av
->next
)
4570 if (av
!= common_av
)
4571 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4573 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4574 fprintf (outf
, " }\n");
4577 fprintf (outf
, " default:\n");
4578 fprintf (outf
, " gcc_unreachable ();\n");
4579 fprintf (outf
, " }\n");
4582 fprintf (outf
, "}\n\n");
4585 /* This page contains miscellaneous utility routines. */
4587 /* Given a pointer to a (char *), return a malloc'ed string containing the
4588 next comma-separated element. Advance the pointer to after the string
4589 scanned, or the end-of-string. Return NULL if at end of string. */
4592 next_comma_elt (const char **pstr
)
4596 start
= scan_comma_elt (pstr
);
4601 return attr_string (start
, *pstr
- start
);
4604 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4605 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4606 replaced by a pointer to a canonical copy of the string. */
4608 static struct attr_desc
*
4609 find_attr (const char **name_p
, int create
)
4611 struct attr_desc
*attr
;
4613 const char *name
= *name_p
;
4615 /* Before we resort to using `strcmp', see if the string address matches
4616 anywhere. In most cases, it should have been canonicalized to do so. */
4617 if (name
== alternative_name
)
4620 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4621 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4622 if (name
== attr
->name
)
4625 /* Otherwise, do it the slow way. */
4626 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4627 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4629 *name_p
= attr
->name
;
4636 attr
= oballoc (struct attr_desc
);
4637 attr
->name
= DEF_ATTR_STRING (name
);
4638 attr
->enum_name
= 0;
4639 attr
->first_value
= attr
->default_val
= NULL
;
4640 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4641 attr
->next
= attrs
[index
];
4642 attrs
[index
] = attr
;
4644 *name_p
= attr
->name
;
4649 /* Create internal attribute with the given default value. */
4652 make_internal_attr (const char *name
, rtx value
, int special
)
4654 struct attr_desc
*attr
;
4656 attr
= find_attr (&name
, 1);
4657 gcc_assert (!attr
->default_val
);
4659 attr
->is_numeric
= 1;
4661 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4662 attr
->default_val
= get_attr_value (file_location ("<internal>", 0),
4666 /* Find the most used value of an attribute. */
4668 static struct attr_value
*
4669 find_most_used (struct attr_desc
*attr
)
4671 struct attr_value
*av
;
4672 struct attr_value
*most_used
;
4678 for (av
= attr
->first_value
; av
; av
= av
->next
)
4679 if (av
->num_insns
> nuses
)
4680 nuses
= av
->num_insns
, most_used
= av
;
4685 /* Return (attr_value "n") */
4688 make_numeric_value (int n
)
4690 static rtx int_values
[20];
4694 gcc_assert (n
>= 0);
4696 if (n
< 20 && int_values
[n
])
4697 return int_values
[n
];
4699 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4700 exp
= attr_rtx (CONST_STRING
, p
);
4703 int_values
[n
] = exp
;
4709 copy_rtx_unchanging (rtx orig
)
4711 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4714 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4718 /* Determine if an insn has a constant number of delay slots, i.e., the
4719 number of delay slots is not a function of the length of the insn. */
4722 write_const_num_delay_slots (FILE *outf
)
4724 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4725 struct attr_value
*av
;
4729 fprintf (outf
, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4730 fprintf (outf
, "{\n");
4731 fprintf (outf
, " switch (recog_memoized (insn))\n");
4732 fprintf (outf
, " {\n");
4734 for (av
= attr
->first_value
; av
; av
= av
->next
)
4737 walk_attr_value (av
->value
);
4739 write_insn_cases (outf
, av
->first_insn
, 4);
4742 fprintf (outf
, " default:\n");
4743 fprintf (outf
, " return 1;\n");
4744 fprintf (outf
, " }\n}\n\n");
4748 /* Synthetic attributes used by insn-automata.c and the scheduler.
4749 These are primarily concerned with (define_insn_reservation)
4754 struct insn_reserv
*next
;
4757 int default_latency
;
4760 /* Sequence number of this insn. */
4763 /* Whether a (define_bypass) construct names this insn in its
4768 static struct insn_reserv
*all_insn_reservs
= 0;
4769 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4770 static size_t n_insn_reservs
;
4772 /* Store information from a DEFINE_INSN_RESERVATION for future
4773 attribute generation. */
4775 gen_insn_reserv (md_rtx_info
*info
)
4777 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4778 rtx def
= info
->def
;
4780 struct attr_desc attr
;
4781 memset (&attr
, 0, sizeof (attr
));
4782 attr
.name
= DEF_ATTR_STRING (XSTR (def
, 0));
4783 attr
.loc
= info
->loc
;
4785 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4786 decl
->default_latency
= XINT (def
, 1);
4787 decl
->condexp
= check_attr_test (info
->loc
, XEXP (def
, 2), &attr
);
4788 decl
->insn_num
= n_insn_reservs
;
4789 decl
->bypassed
= false;
4792 *last_insn_reserv_p
= decl
;
4793 last_insn_reserv_p
= &decl
->next
;
4797 /* Store information from a DEFINE_BYPASS for future attribute
4798 generation. The only thing we care about is the list of output
4799 insns, which will later be used to tag reservation structures with
4800 a 'bypassed' bit. */
4804 struct bypass_list
*next
;
4805 const char *pattern
;
4808 static struct bypass_list
*all_bypasses
;
4809 static size_t n_bypasses
;
4810 static size_t n_bypassed
;
4813 gen_bypass_1 (const char *s
, size_t len
)
4815 struct bypass_list
*b
;
4820 s
= attr_string (s
, len
);
4821 for (b
= all_bypasses
; b
; b
= b
->next
)
4822 if (s
== b
->pattern
)
4823 return; /* already got that one */
4825 b
= oballoc (struct bypass_list
);
4827 b
->next
= all_bypasses
;
4833 gen_bypass (md_rtx_info
*info
)
4835 const char *p
, *base
;
4837 rtx def
= info
->def
;
4838 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4841 gen_bypass_1 (base
, p
- base
);
4844 while (ISSPACE (*p
));
4847 gen_bypass_1 (base
, p
- base
);
4850 /* Find and mark all of the bypassed insns. */
4852 process_bypasses (void)
4854 struct bypass_list
*b
;
4855 struct insn_reserv
*r
;
4859 /* The reservation list is likely to be much longer than the bypass
4861 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4862 for (b
= all_bypasses
; b
; b
= b
->next
)
4863 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4871 /* Check that attribute NAME is used in define_insn_reservation condition
4872 EXP. Return true if it is. */
4874 check_tune_attr (const char *name
, rtx exp
)
4876 switch (GET_CODE (exp
))
4879 if (check_tune_attr (name
, XEXP (exp
, 0)))
4881 return check_tune_attr (name
, XEXP (exp
, 1));
4884 return (check_tune_attr (name
, XEXP (exp
, 0))
4885 && check_tune_attr (name
, XEXP (exp
, 1)));
4888 return XSTR (exp
, 0) == name
;
4895 /* Try to find a const attribute (usually cpu or tune) that is used
4896 in all define_insn_reservation conditions. */
4897 static struct attr_desc
*
4898 find_tune_attr (rtx exp
)
4900 struct attr_desc
*attr
;
4902 switch (GET_CODE (exp
))
4906 attr
= find_tune_attr (XEXP (exp
, 0));
4909 return find_tune_attr (XEXP (exp
, 1));
4912 if (XSTR (exp
, 0) == alternative_name
)
4915 attr
= find_attr (&XSTR (exp
, 0), 0);
4918 if (attr
->is_const
&& !attr
->is_special
)
4920 struct insn_reserv
*decl
;
4922 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4923 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4934 /* Create all of the attributes that describe automaton properties.
4935 Write the DFA and latency function prototypes to the files that
4936 need to have them, and write the init_sched_attrs(). */
4939 make_automaton_attrs (void)
4942 struct insn_reserv
*decl
;
4943 rtx code_exp
, lats_exp
, byps_exp
;
4944 struct attr_desc
*tune_attr
;
4946 if (n_insn_reservs
== 0)
4949 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4950 if (tune_attr
!= NULL
)
4952 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4953 struct attr_value
*val
;
4956 gcc_assert (tune_attr
->is_const
4957 && !tune_attr
->is_special
4958 && !tune_attr
->is_numeric
);
4960 /* Write the prototypes for all DFA functions. */
4961 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4963 if (val
== tune_attr
->default_val
)
4965 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4967 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4968 XSTR (val
->value
, 0));
4970 fprintf (dfa_file
, "\n");
4972 /* Write the prototypes for all latency functions. */
4973 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4975 if (val
== tune_attr
->default_val
)
4977 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4978 fprintf (latency_file
,
4979 "extern int insn_default_latency_%s (rtx_insn *);\n",
4980 XSTR (val
->value
, 0));
4982 fprintf (latency_file
, "\n");
4984 /* Write the prototypes for all automaton functions. */
4985 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4987 if (val
== tune_attr
->default_val
)
4989 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4991 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4992 "extern int insn_default_latency_%s (rtx_insn *);\n",
4993 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4995 fprintf (attr_file
, "\n");
4996 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4997 fprintf (attr_file
, "int (*insn_default_latency) (rtx_insn *);\n");
4998 fprintf (attr_file
, "\n");
4999 fprintf (attr_file
, "void\n");
5000 fprintf (attr_file
, "init_sched_attrs (void)\n");
5001 fprintf (attr_file
, "{\n");
5003 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
5007 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
5009 if (val
== tune_attr
->default_val
)
5011 for (decl
= all_insn_reservs
, i
= 0;
5017 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
5018 if (condexp
== false_rtx
)
5020 if (condexp
== true_rtx
)
5022 condexps
[i
] = condexp
;
5023 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
5024 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
5028 code_exp
= rtx_alloc (COND
);
5029 lats_exp
= rtx_alloc (COND
);
5032 XVEC (code_exp
, 0) = rtvec_alloc (j
);
5033 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
5037 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
5038 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
5042 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5043 XEXP (lats_exp
, 1) = make_numeric_value (0);
5050 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
5051 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
5053 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
5054 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5057 name
= XNEWVEC (char,
5058 sizeof ("*internal_dfa_insn_code_")
5059 + strlen (XSTR (val
->value
, 0)));
5060 strcpy (name
, "*internal_dfa_insn_code_");
5061 strcat (name
, XSTR (val
->value
, 0));
5062 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5063 strcpy (name
, "*insn_default_latency_");
5064 strcat (name
, XSTR (val
->value
, 0));
5065 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5070 fprintf (attr_file
, " if (");
5074 fprintf (attr_file
, " else if (");
5075 write_test_expr (attr_file
, test
, 0, 0);
5076 fprintf (attr_file
, ")\n");
5077 fprintf (attr_file
, " {\n");
5078 fprintf (attr_file
, " internal_dfa_insn_code\n");
5079 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5080 XSTR (val
->value
, 0));
5081 fprintf (attr_file
, " insn_default_latency\n");
5082 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5083 XSTR (val
->value
, 0));
5084 fprintf (attr_file
, " }\n");
5087 fprintf (attr_file
, " else\n");
5088 fprintf (attr_file
, " gcc_unreachable ();\n");
5089 fprintf (attr_file
, "}\n");
5090 fprintf (attr_file
, "\n");
5092 XDELETEVEC (condexps
);
5096 code_exp
= rtx_alloc (COND
);
5097 lats_exp
= rtx_alloc (COND
);
5099 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5100 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5102 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5103 XEXP (lats_exp
, 1) = make_numeric_value (0);
5105 for (decl
= all_insn_reservs
, i
= 0;
5107 decl
= decl
->next
, i
+= 2)
5109 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5110 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5112 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5113 XVECEXP (lats_exp
, 0, i
+1)
5114 = make_numeric_value (decl
->default_latency
);
5116 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5117 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5120 if (n_bypasses
== 0)
5121 byps_exp
= make_numeric_value (0);
5124 process_bypasses ();
5126 byps_exp
= rtx_alloc (COND
);
5127 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypassed
* 2);
5128 XEXP (byps_exp
, 1) = make_numeric_value (0);
5129 for (decl
= all_insn_reservs
, i
= 0;
5134 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5135 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5140 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5144 write_header (FILE *outf
)
5146 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5147 " from the machine description file `md'. */\n\n");
5149 fprintf (outf
, "#include \"config.h\"\n");
5150 fprintf (outf
, "#include \"system.h\"\n");
5151 fprintf (outf
, "#include \"coretypes.h\"\n");
5152 fprintf (outf
, "#include \"backend.h\"\n");
5153 fprintf (outf
, "#include \"predict.h\"\n");
5154 fprintf (outf
, "#include \"tree.h\"\n");
5155 fprintf (outf
, "#include \"rtl.h\"\n");
5156 fprintf (outf
, "#include \"alias.h\"\n");
5157 fprintf (outf
, "#include \"options.h\"\n");
5158 fprintf (outf
, "#include \"varasm.h\"\n");
5159 fprintf (outf
, "#include \"stor-layout.h\"\n");
5160 fprintf (outf
, "#include \"calls.h\"\n");
5161 fprintf (outf
, "#include \"insn-attr.h\"\n");
5162 fprintf (outf
, "#include \"tm_p.h\"\n");
5163 fprintf (outf
, "#include \"insn-config.h\"\n");
5164 fprintf (outf
, "#include \"recog.h\"\n");
5165 fprintf (outf
, "#include \"regs.h\"\n");
5166 fprintf (outf
, "#include \"real.h\"\n");
5167 fprintf (outf
, "#include \"output.h\"\n");
5168 fprintf (outf
, "#include \"toplev.h\"\n");
5169 fprintf (outf
, "#include \"flags.h\"\n");
5170 fprintf (outf
, "#include \"emit-rtl.h\"\n");
5171 fprintf (outf
, "\n");
5172 fprintf (outf
, "#define operands recog_data.operand\n\n");
5176 open_outfile (const char *file_name
)
5179 outf
= fopen (file_name
, "w");
5181 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5182 write_header (outf
);
5187 handle_arg (const char *arg
)
5192 attr_file_name
= &arg
[2];
5195 dfa_file_name
= &arg
[2];
5198 latency_file_name
= &arg
[2];
5206 main (int argc
, const char **argv
)
5208 struct attr_desc
*attr
;
5209 struct insn_def
*id
;
5212 progname
= "genattrtab";
5214 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5215 return FATAL_EXIT_CODE
;
5217 attr_file
= open_outfile (attr_file_name
);
5218 dfa_file
= open_outfile (dfa_file_name
);
5219 latency_file
= open_outfile (latency_file_name
);
5221 obstack_init (hash_obstack
);
5222 obstack_init (temp_obstack
);
5224 /* Set up true and false rtx's */
5225 true_rtx
= rtx_alloc (CONST_INT
);
5226 XWINT (true_rtx
, 0) = 1;
5227 false_rtx
= rtx_alloc (CONST_INT
);
5228 XWINT (false_rtx
, 0) = 0;
5229 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5230 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5232 alternative_name
= DEF_ATTR_STRING ("alternative");
5233 length_str
= DEF_ATTR_STRING ("length");
5234 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5235 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5236 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5238 /* Read the machine description. */
5241 while (read_md_rtx (&info
))
5243 switch (GET_CODE (info
.def
))
5246 case DEFINE_PEEPHOLE
:
5247 case DEFINE_ASM_ATTRIBUTES
:
5252 case DEFINE_ENUM_ATTR
:
5260 case DEFINE_INSN_RESERVATION
:
5261 gen_insn_reserv (&info
);
5271 if (GET_CODE (info
.def
) != DEFINE_ASM_ATTRIBUTES
)
5272 insn_index_number
++;
5276 return FATAL_EXIT_CODE
;
5278 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5279 if (! got_define_asm_attributes
)
5282 info
.def
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5283 XVEC (info
.def
, 0) = rtvec_alloc (0);
5284 info
.loc
= file_location ("<internal>", 0);
5289 /* Expand DEFINE_DELAY information into new attribute. */
5292 /* Make `insn_alternatives'. */
5293 int num_insn_codes
= get_num_insn_codes ();
5294 insn_alternatives
= oballocvec (uint64_t, num_insn_codes
);
5295 for (id
= defs
; id
; id
= id
->next
)
5296 if (id
->insn_code
>= 0)
5297 insn_alternatives
[id
->insn_code
]
5298 = (((uint64_t) 1) << id
->num_alternatives
) - 1;
5300 /* Make `insn_n_alternatives'. */
5301 insn_n_alternatives
= oballocvec (int, num_insn_codes
);
5302 for (id
= defs
; id
; id
= id
->next
)
5303 if (id
->insn_code
>= 0)
5304 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5306 /* Construct extra attributes for automata. */
5307 make_automaton_attrs ();
5309 /* Prepare to write out attribute subroutines by checking everything stored
5310 away and building the attribute cases. */
5314 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5315 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5316 attr
->default_val
->value
5317 = check_attr_value (attr
->loc
, attr
->default_val
->value
, attr
);
5320 return FATAL_EXIT_CODE
;
5322 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5323 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5326 /* Construct extra attributes for `length'. */
5327 make_length_attrs ();
5329 /* Perform any possible optimizations to speed up compilation. */
5330 optimize_attrs (num_insn_codes
);
5332 /* Now write out all the `gen_attr_...' routines. Do these before the
5333 special routines so that they get defined before they are used. */
5335 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5336 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5340 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5341 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5343 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5344 outf
= latency_file
;
5347 #undef IS_ATTR_GROUP
5349 if (! attr
->is_special
&& ! attr
->is_const
)
5350 write_attr_get (outf
, attr
);
5353 /* Write out delay eligibility information, if DEFINE_DELAY present.
5354 (The function to compute the number of delay slots will be written
5356 write_eligible_delay (attr_file
, "delay");
5357 if (have_annul_true
)
5358 write_eligible_delay (attr_file
, "annul_true");
5360 write_dummy_eligible_delay (attr_file
, "annul_true");
5361 if (have_annul_false
)
5362 write_eligible_delay (attr_file
, "annul_false");
5364 write_dummy_eligible_delay (attr_file
, "annul_false");
5366 /* Write out constant delay slot info. */
5367 write_const_num_delay_slots (attr_file
);
5369 write_length_unit_log (attr_file
);
5371 if (fclose (attr_file
) != 0)
5372 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5373 if (fclose (dfa_file
) != 0)
5374 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5375 if (fclose (latency_file
) != 0)
5376 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5378 return SUCCESS_EXIT_CODE
;