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;
892 fatal_at (loc
, "invalid operator `%s' in definition of attribute"
893 " `%s'", GET_RTX_NAME (GET_CODE (exp
)), attr
->name
);
899 /* Given an expression EXP, ensure that it is validly formed and that
900 all named attribute values are valid for ATTR. Issue an error if not.
901 LOC is the location of the .md construct that contains EXP.
903 Return a perhaps modified replacement expression for the value. */
906 check_attr_value (file_location loc
, rtx exp
, struct attr_desc
*attr
)
908 struct attr_value
*av
;
912 switch (GET_CODE (exp
))
915 if (!attr
->is_numeric
)
918 "CONST_INT not valid for non-numeric attribute `%s'",
923 if (INTVAL (exp
) < 0)
926 "negative numeric value specified for attribute `%s'",
933 if (! strcmp (XSTR (exp
, 0), "*"))
936 if (attr
->is_numeric
)
943 "non-numeric value specified for numeric"
944 " attribute `%s'", attr
->name
);
950 for (av
= attr
->first_value
; av
; av
= av
->next
)
951 if (GET_CODE (av
->value
) == CONST_STRING
952 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
956 error_at (loc
, "unknown value `%s' for attribute `%s'",
957 XSTR (exp
, 0), attr
->name
);
961 XEXP (exp
, 0) = check_attr_test (loc
, XEXP (exp
, 0), attr
);
962 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
963 XEXP (exp
, 2) = check_attr_value (loc
, XEXP (exp
, 2), attr
);
971 if (!attr
->is_numeric
)
973 error_at (loc
, "invalid operation `%s' for non-numeric"
974 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp
)),
982 XEXP (exp
, 0) = check_attr_value (loc
, XEXP (exp
, 0), attr
);
983 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
992 XEXP (exp
, 0) = check_attr_value (loc
, XEXP (exp
, 0), attr
);
996 if (XVECLEN (exp
, 0) % 2 != 0)
998 error_at (loc
, "first operand of COND must have even length");
1002 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1004 XVECEXP (exp
, 0, i
) = check_attr_test (attr
->loc
,
1005 XVECEXP (exp
, 0, i
),
1007 XVECEXP (exp
, 0, i
+ 1)
1008 = check_attr_value (loc
, XVECEXP (exp
, 0, i
+ 1), attr
);
1011 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
1016 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1018 error_at (loc
, "unknown attribute `%s' in ATTR",
1020 else if (attr
->is_const
&& ! attr2
->is_const
)
1021 error_at (attr
->loc
,
1022 "constant attribute `%s' cannot refer to non-constant"
1023 " attribute `%s'", attr
->name
, attr2
->name
);
1024 else if (attr
->is_numeric
!= attr2
->is_numeric
)
1026 "numeric attribute mismatch calling `%s' from `%s'",
1027 attr2
->name
, attr
->name
);
1032 /* A constant SYMBOL_REF is valid as a constant attribute test and
1033 is expanded later by make_canonical into a COND. In a non-constant
1034 attribute test, it is left be. */
1035 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1038 error_at (loc
, "invalid operator `%s' in definition of attribute `%s'",
1039 GET_RTX_NAME (GET_CODE (exp
)), attr
->name
);
1046 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1047 It becomes a COND with each test being (eq_attr "alternative" "n") */
1050 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1052 int num_alt
= id
->num_alternatives
;
1056 if (XVECLEN (exp
, 1) != num_alt
)
1058 error_at (id
->loc
, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1059 " was %d expected %d", XVECLEN (exp
, 1), num_alt
);
1063 /* Make a COND with all tests but the last. Select the last value via the
1065 condexp
= rtx_alloc (COND
);
1066 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1068 for (i
= 0; i
< num_alt
- 1; i
++)
1071 p
= attr_numeral (i
);
1073 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1074 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1077 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1079 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1082 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1083 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1086 convert_set_attr (rtx exp
, struct insn_def
*id
)
1089 const char *name_ptr
;
1093 /* See how many alternative specified. */
1094 n
= n_comma_elts (XSTR (exp
, 1));
1096 return attr_rtx (SET
,
1097 attr_rtx (ATTR
, XSTR (exp
, 0)),
1098 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1100 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1101 XSTR (newexp
, 0) = XSTR (exp
, 0);
1102 XVEC (newexp
, 1) = rtvec_alloc (n
);
1104 /* Process each comma-separated name. */
1105 name_ptr
= XSTR (exp
, 1);
1107 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1108 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1110 return convert_set_attr_alternative (newexp
, id
);
1113 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1114 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1120 struct insn_def
*id
;
1121 struct attr_desc
*attr
;
1125 for (id
= defs
; id
; id
= id
->next
)
1127 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1130 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1132 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1133 switch (GET_CODE (value
))
1136 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1138 error_at (id
->loc
, "bad attribute set");
1143 case SET_ATTR_ALTERNATIVE
:
1144 value
= convert_set_attr_alternative (value
, id
);
1148 value
= convert_set_attr (value
, id
);
1152 error_at (id
->loc
, "invalid attribute code %s",
1153 GET_RTX_NAME (GET_CODE (value
)));
1156 if (value
== NULL_RTX
)
1159 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1161 error_at (id
->loc
, "unknown attribute %s",
1162 XSTR (XEXP (value
, 0), 0));
1166 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1167 XEXP (value
, 1) = check_attr_value (id
->loc
, XEXP (value
, 1), attr
);
1172 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1173 expressions by converting them into a COND. This removes cases from this
1174 program. Also, replace an attribute value of "*" with the default attribute
1175 value. LOC is the location to use for error reporting. */
1178 make_canonical (file_location loc
, struct attr_desc
*attr
, rtx exp
)
1183 switch (GET_CODE (exp
))
1186 exp
= make_numeric_value (INTVAL (exp
));
1190 if (! strcmp (XSTR (exp
, 0), "*"))
1192 if (attr
->default_val
== 0)
1193 fatal_at (loc
, "(attr_value \"*\") used in invalid context");
1194 exp
= attr
->default_val
->value
;
1197 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1202 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1204 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1205 This makes the COND something that won't be considered an arbitrary
1206 expression by walk_attr_value. */
1207 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1208 exp
= check_attr_value (loc
, exp
, attr
);
1212 newexp
= rtx_alloc (COND
);
1213 XVEC (newexp
, 0) = rtvec_alloc (2);
1214 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1215 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1217 XEXP (newexp
, 1) = XEXP (exp
, 2);
1220 /* Fall through to COND case since this is now a COND. */
1227 /* First, check for degenerate COND. */
1228 if (XVECLEN (exp
, 0) == 0)
1229 return make_canonical (loc
, attr
, XEXP (exp
, 1));
1230 defval
= XEXP (exp
, 1) = make_canonical (loc
, attr
, XEXP (exp
, 1));
1232 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1234 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1235 XVECEXP (exp
, 0, i
+ 1)
1236 = make_canonical (loc
, attr
, XVECEXP (exp
, 0, i
+ 1));
1237 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1253 copy_boolean (rtx exp
)
1255 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1256 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1257 copy_boolean (XEXP (exp
, 1)));
1258 if (GET_CODE (exp
) == MATCH_OPERAND
)
1260 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1261 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1263 else if (GET_CODE (exp
) == EQ_ATTR
)
1265 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1266 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1272 /* Given a value and an attribute description, return a `struct attr_value *'
1273 that represents that value. This is either an existing structure, if the
1274 value has been previously encountered, or a newly-created structure.
1276 `insn_code' is the code of an insn whose attribute has the specified
1277 value (-2 if not processing an insn). We ensure that all insns for
1278 a given value have the same number of alternatives if the value checks
1279 alternatives. LOC is the location to use for error reporting. */
1281 static struct attr_value
*
1282 get_attr_value (file_location loc
, rtx value
, struct attr_desc
*attr
,
1285 struct attr_value
*av
;
1286 uint64_t num_alt
= 0;
1288 value
= make_canonical (loc
, attr
, value
);
1289 if (compares_alternatives_p (value
))
1291 if (insn_code
< 0 || insn_alternatives
== NULL
)
1292 fatal_at (loc
, "(eq_attr \"alternatives\" ...) used in non-insn"
1295 num_alt
= insn_alternatives
[insn_code
];
1298 for (av
= attr
->first_value
; av
; av
= av
->next
)
1299 if (rtx_equal_p (value
, av
->value
)
1300 && (num_alt
== 0 || av
->first_insn
== NULL
1301 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1304 av
= oballoc (struct attr_value
);
1306 av
->next
= attr
->first_value
;
1307 attr
->first_value
= av
;
1308 av
->first_insn
= NULL
;
1310 av
->has_asm_insn
= 0;
1315 /* After all DEFINE_DELAYs have been read in, create internal attributes
1316 to generate the required routines.
1318 First, we compute the number of delay slots for each insn (as a COND of
1319 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1320 delay type is specified, we compute a similar function giving the
1321 DEFINE_DELAY ordinal for each insn.
1323 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1324 tells whether a given insn can be in that delay slot.
1326 Normal attribute filling and optimization expands these to contain the
1327 information needed to handle delay slots. */
1330 expand_delays (void)
1332 struct delay_desc
*delay
;
1338 /* First, generate data for `num_delay_slots' function. */
1340 condexp
= rtx_alloc (COND
);
1341 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1342 XEXP (condexp
, 1) = make_numeric_value (0);
1344 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1346 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1347 XVECEXP (condexp
, 0, i
+ 1)
1348 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1351 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1353 /* If more than one delay type, do the same for computing the delay type. */
1356 condexp
= rtx_alloc (COND
);
1357 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1358 XEXP (condexp
, 1) = make_numeric_value (0);
1360 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1362 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1363 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1366 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1369 /* For each delay possibility and delay slot, compute an eligibility
1370 attribute for non-annulled insns and for each type of annulled (annul
1371 if true and annul if false). */
1372 for (delay
= delays
; delay
; delay
= delay
->next
)
1374 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1376 condexp
= XVECEXP (delay
->def
, 1, i
);
1378 condexp
= false_rtx
;
1379 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1380 make_numeric_value (1), make_numeric_value (0));
1382 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1383 "*delay_%d_%d", delay
->num
, i
/ 3);
1384 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1386 if (have_annul_true
)
1388 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1389 if (condexp
== 0) condexp
= false_rtx
;
1390 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1391 make_numeric_value (1),
1392 make_numeric_value (0));
1393 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1394 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1395 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1398 if (have_annul_false
)
1400 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1401 if (condexp
== 0) condexp
= false_rtx
;
1402 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1403 make_numeric_value (1),
1404 make_numeric_value (0));
1405 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1406 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1407 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1413 /* Once all attributes and insns have been read and checked, we construct for
1414 each attribute value a list of all the insns that have that value for
1418 fill_attr (struct attr_desc
*attr
)
1420 struct attr_value
*av
;
1421 struct insn_ent
*ie
;
1422 struct insn_def
*id
;
1426 /* Don't fill constant attributes. The value is independent of
1427 any particular insn. */
1431 for (id
= defs
; id
; id
= id
->next
)
1433 /* If no value is specified for this insn for this attribute, use the
1436 if (XVEC (id
->def
, id
->vec_idx
))
1437 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1438 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1440 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1443 av
= attr
->default_val
;
1445 av
= get_attr_value (id
->loc
, value
, attr
, id
->insn_code
);
1447 ie
= oballoc (struct insn_ent
);
1449 insert_insn_ent (av
, ie
);
1453 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1454 test that checks relative positions of insns (uses MATCH_DUP or PC).
1455 If so, replace it with what is obtained by passing the expression to
1456 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1457 recursively on each value (including the default value). Otherwise,
1458 return the value returned by NO_ADDRESS_FN applied to EXP. */
1461 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1462 rtx (*address_fn
) (rtx
))
1467 if (GET_CODE (exp
) == COND
)
1469 /* See if any tests use addresses. */
1471 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1472 walk_attr_value (XVECEXP (exp
, 0, i
));
1475 return (*address_fn
) (exp
);
1477 /* Make a new copy of this COND, replacing each element. */
1478 newexp
= rtx_alloc (COND
);
1479 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1480 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1482 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1483 XVECEXP (newexp
, 0, i
+ 1)
1484 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1485 no_address_fn
, address_fn
);
1488 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1489 no_address_fn
, address_fn
);
1494 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1497 walk_attr_value (XEXP (exp
, 0));
1499 return (*address_fn
) (exp
);
1501 return attr_rtx (IF_THEN_ELSE
,
1502 substitute_address (XEXP (exp
, 0),
1503 no_address_fn
, address_fn
),
1504 substitute_address (XEXP (exp
, 1),
1505 no_address_fn
, address_fn
),
1506 substitute_address (XEXP (exp
, 2),
1507 no_address_fn
, address_fn
));
1510 return (*no_address_fn
) (exp
);
1513 /* Make new attributes from the `length' attribute. The following are made,
1514 each corresponding to a function called from `shorten_branches' or
1517 *insn_default_length This is the length of the insn to be returned
1518 by `get_attr_length' before `shorten_branches'
1519 has been called. In each case where the length
1520 depends on relative addresses, the largest
1521 possible is used. This routine is also used
1522 to compute the initial size of the insn.
1524 *insn_variable_length_p This returns 1 if the insn's length depends
1525 on relative addresses, zero otherwise.
1527 *insn_current_length This is only called when it is known that the
1528 insn has a variable length and returns the
1529 current length, based on relative addresses.
1533 make_length_attrs (void)
1535 static const char *new_names
[] =
1537 "*insn_default_length",
1539 "*insn_variable_length_p",
1540 "*insn_current_length"
1542 static rtx (*const no_address_fn
[]) (rtx
)
1543 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1544 static rtx (*const address_fn
[]) (rtx
)
1545 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1547 struct attr_desc
*length_attr
, *new_attr
;
1548 struct attr_value
*av
, *new_av
;
1549 struct insn_ent
*ie
, *new_ie
;
1551 /* See if length attribute is defined. If so, it must be numeric. Make
1552 it special so we don't output anything for it. */
1553 length_attr
= find_attr (&length_str
, 0);
1554 if (length_attr
== 0)
1557 if (! length_attr
->is_numeric
)
1558 fatal_at (length_attr
->loc
, "length attribute must be numeric");
1560 length_attr
->is_const
= 0;
1561 length_attr
->is_special
= 1;
1563 /* Make each new attribute, in turn. */
1564 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1566 make_internal_attr (new_names
[i
],
1567 substitute_address (length_attr
->default_val
->value
,
1568 no_address_fn
[i
], address_fn
[i
]),
1570 new_attr
= find_attr (&new_names
[i
], 0);
1571 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1572 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1574 new_av
= get_attr_value (ie
->def
->loc
,
1575 substitute_address (av
->value
,
1578 new_attr
, ie
->def
->insn_code
);
1579 new_ie
= oballoc (struct insn_ent
);
1580 new_ie
->def
= ie
->def
;
1581 insert_insn_ent (new_av
, new_ie
);
1586 /* Utility functions called from above routine. */
1589 identity_fn (rtx exp
)
1595 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1597 return make_numeric_value (0);
1601 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1603 return make_numeric_value (1);
1610 return make_numeric_value (max_attr_value (exp
, &unknown
));
1617 return make_numeric_value (min_attr_value (exp
, &unknown
));
1621 write_length_unit_log (FILE *outf
)
1623 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1624 struct attr_value
*av
;
1625 struct insn_ent
*ie
;
1626 unsigned int length_unit_log
, length_or
;
1631 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1632 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1633 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1634 length_or
|= or_attr_value (av
->value
, &unknown
);
1637 if (length_attr
== NULL
|| unknown
)
1638 length_unit_log
= 0;
1641 length_or
= ~length_or
;
1642 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1645 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1648 /* Compute approximate cost of the expression. Used to decide whether
1649 expression is cheap enough for inline. */
1651 attr_rtx_cost (rtx x
)
1657 code
= GET_CODE (x
);
1670 /* Alternatives don't result into function call. */
1671 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1678 const char *fmt
= GET_RTX_FORMAT (code
);
1679 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1685 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1686 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1689 cost
+= attr_rtx_cost (XEXP (x
, i
));
1699 /* Take a COND expression and see if any of the conditions in it can be
1700 simplified. If any are known true or known false for the particular insn
1701 code, the COND can be further simplified.
1703 Also call ourselves on any COND operations that are values of this COND.
1705 We do not modify EXP; rather, we make and return a new rtx. */
1708 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1711 /* We store the desired contents here,
1712 then build a new expression if they don't match EXP. */
1713 rtx defval
= XEXP (exp
, 1);
1714 rtx new_defval
= XEXP (exp
, 1);
1715 int len
= XVECLEN (exp
, 0);
1716 rtx
*tests
= XNEWVEC (rtx
, len
);
1720 /* This lets us free all storage allocated below, if appropriate. */
1721 obstack_finish (rtl_obstack
);
1723 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1725 /* See if default value needs simplification. */
1726 if (GET_CODE (defval
) == COND
)
1727 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1729 /* Simplify the subexpressions, and see what tests we can get rid of. */
1731 for (i
= 0; i
< len
; i
+= 2)
1733 rtx newtest
, newval
;
1735 /* Simplify this test. */
1736 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1739 newval
= tests
[i
+ 1];
1740 /* See if this value may need simplification. */
1741 if (GET_CODE (newval
) == COND
)
1742 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1744 /* Look for ways to delete or combine this test. */
1745 if (newtest
== true_rtx
)
1747 /* If test is true, make this value the default
1748 and discard this + any following tests. */
1750 defval
= tests
[i
+ 1];
1751 new_defval
= newval
;
1754 else if (newtest
== false_rtx
)
1756 /* If test is false, discard it and its value. */
1757 for (j
= i
; j
< len
- 2; j
++)
1758 tests
[j
] = tests
[j
+ 2];
1763 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1765 /* If this value and the value for the prev test are the same,
1769 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1770 insn_code
, insn_index
);
1772 /* Delete this test/value. */
1773 for (j
= i
; j
< len
- 2; j
++)
1774 tests
[j
] = tests
[j
+ 2];
1780 tests
[i
+ 1] = newval
;
1783 /* If the last test in a COND has the same value
1784 as the default value, that test isn't needed. */
1786 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1789 /* See if we changed anything. */
1790 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1793 for (i
= 0; i
< len
; i
++)
1794 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1802 if (GET_CODE (defval
) == COND
)
1803 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1811 rtx newexp
= rtx_alloc (COND
);
1813 XVEC (newexp
, 0) = rtvec_alloc (len
);
1814 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1815 XEXP (newexp
, 1) = new_defval
;
1822 /* Remove an insn entry from an attribute value. */
1825 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1827 struct insn_ent
*previe
;
1829 if (av
->first_insn
== ie
)
1830 av
->first_insn
= ie
->next
;
1833 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1835 previe
->next
= ie
->next
;
1839 if (ie
->def
->insn_code
== -1)
1840 av
->has_asm_insn
= 0;
1845 /* Insert an insn entry in an attribute value list. */
1848 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1850 ie
->next
= av
->first_insn
;
1851 av
->first_insn
= ie
;
1853 if (ie
->def
->insn_code
== -1)
1854 av
->has_asm_insn
= 1;
1859 /* This is a utility routine to take an expression that is a tree of either
1860 AND or IOR expressions and insert a new term. The new term will be
1861 inserted at the right side of the first node whose code does not match
1862 the root. A new node will be created with the root's code. Its left
1863 side will be the old right side and its right side will be the new
1866 If the `term' is itself a tree, all its leaves will be inserted. */
1869 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1873 /* Avoid consing in some special cases. */
1874 if (code
== AND
&& term
== true_rtx
)
1876 if (code
== AND
&& term
== false_rtx
)
1878 if (code
== AND
&& exp
== true_rtx
)
1880 if (code
== AND
&& exp
== false_rtx
)
1882 if (code
== IOR
&& term
== true_rtx
)
1884 if (code
== IOR
&& term
== false_rtx
)
1886 if (code
== IOR
&& exp
== true_rtx
)
1888 if (code
== IOR
&& exp
== false_rtx
)
1890 if (attr_equal_p (exp
, term
))
1893 if (GET_CODE (term
) == code
)
1895 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1896 insn_code
, insn_index
);
1897 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1898 insn_code
, insn_index
);
1903 if (GET_CODE (exp
) == code
)
1905 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1906 term
, insn_code
, insn_index
);
1907 if (new_rtx
!= XEXP (exp
, 1))
1908 /* Make a copy of this expression and call recursively. */
1909 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1915 /* Insert the new term. */
1916 newexp
= attr_rtx (code
, exp
, term
);
1919 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1922 /* If we have an expression which AND's a bunch of
1923 (not (eq_attrq "alternative" "n"))
1924 terms, we may have covered all or all but one of the possible alternatives.
1925 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1927 This routine is passed an expression and either AND or IOR. It returns a
1928 bitmask indicating which alternatives are mentioned within EXP. */
1931 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1934 if (GET_CODE (exp
) == code
)
1935 return compute_alternative_mask (XEXP (exp
, 0), code
)
1936 | compute_alternative_mask (XEXP (exp
, 1), code
);
1938 else if (code
== AND
&& GET_CODE (exp
) == NOT
1939 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1940 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1941 string
= XSTR (XEXP (exp
, 0), 1);
1943 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1944 && XSTR (exp
, 0) == alternative_name
)
1945 string
= XSTR (exp
, 1);
1947 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1949 if (code
== AND
&& XINT (exp
, 1))
1950 return XINT (exp
, 0);
1952 if (code
== IOR
&& !XINT (exp
, 1))
1953 return XINT (exp
, 0);
1961 return ((uint64_t) 1) << (string
[0] - '0');
1962 return ((uint64_t) 1) << atoi (string
);
1965 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1966 attribute with the value represented by that bit. */
1969 make_alternative_compare (uint64_t mask
)
1971 return mk_attr_alt (mask
);
1974 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1975 of "attr" for this insn code. From that value, we can compute a test
1976 showing when the EQ_ATTR will be true. This routine performs that
1977 computation. If a test condition involves an address, we leave the EQ_ATTR
1978 intact because addresses are only valid for the `length' attribute.
1980 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1981 it refers. VALUE is the value of that attribute for the insn
1982 corresponding to INSN_CODE and INSN_INDEX. */
1985 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1986 int insn_code
, int insn_index
)
1993 while (GET_CODE (value
) == ATTR
)
1995 struct attr_value
*av
= NULL
;
1997 attr
= find_attr (&XSTR (value
, 0), 0);
1999 if (insn_code_values
)
2001 struct attr_value_list
*iv
;
2002 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2003 if (iv
->attr
== attr
)
2011 struct insn_ent
*ie
;
2012 for (av
= attr
->first_value
; av
; av
= av
->next
)
2013 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2014 if (ie
->def
->insn_code
== insn_code
)
2024 switch (GET_CODE (value
))
2027 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2038 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2039 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
2040 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
2041 for (p
= string
; *p
; p
++)
2044 newexp
= attr_rtx (EQ
, value
,
2045 attr_rtx (SYMBOL_REF
,
2046 DEF_ATTR_STRING (string
)));
2051 /* We construct an IOR of all the cases for which the
2052 requested attribute value is present. Since we start with
2053 FALSE, if it is not present, FALSE will be returned.
2055 Each case is the AND of the NOT's of the previous conditions with the
2056 current condition; in the default case the current condition is TRUE.
2058 For each possible COND value, call ourselves recursively.
2060 The extra TRUE and FALSE expressions will be eliminated by another
2061 call to the simplification routine. */
2066 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2068 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2069 insn_code
, insn_index
);
2071 right
= insert_right_side (AND
, andexp
, this_cond
,
2072 insn_code
, insn_index
);
2073 right
= insert_right_side (AND
, right
,
2074 evaluate_eq_attr (exp
, attr
,
2077 insn_code
, insn_index
),
2078 insn_code
, insn_index
);
2079 orexp
= insert_right_side (IOR
, orexp
, right
,
2080 insn_code
, insn_index
);
2082 /* Add this condition into the AND expression. */
2083 newexp
= attr_rtx (NOT
, this_cond
);
2084 andexp
= insert_right_side (AND
, andexp
, newexp
,
2085 insn_code
, insn_index
);
2088 /* Handle the default case. */
2089 right
= insert_right_side (AND
, andexp
,
2090 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2091 insn_code
, insn_index
),
2092 insn_code
, insn_index
);
2093 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2100 /* If uses an address, must return original expression. But set the
2101 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2104 walk_attr_value (newexp
);
2108 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2109 return copy_rtx_unchanging (exp
);
2116 /* This routine is called when an AND of a term with a tree of AND's is
2117 encountered. If the term or its complement is present in the tree, it
2118 can be replaced with TRUE or FALSE, respectively.
2120 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2121 be true and hence are complementary.
2123 There is one special case: If we see
2124 (and (not (eq_attr "att" "v1"))
2125 (eq_attr "att" "v2"))
2126 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2127 replace the term, not anything in the AND tree. So we pass a pointer to
2131 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2136 int left_eliminates_term
, right_eliminates_term
;
2138 if (GET_CODE (exp
) == AND
)
2140 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2141 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2142 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2144 newexp
= attr_rtx (AND
, left
, right
);
2146 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2150 else if (GET_CODE (exp
) == IOR
)
2152 /* For the IOR case, we do the same as above, except that we can
2153 only eliminate `term' if both sides of the IOR would do so. */
2155 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2156 left_eliminates_term
= (temp
== true_rtx
);
2159 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2160 right_eliminates_term
= (temp
== true_rtx
);
2162 if (left_eliminates_term
&& right_eliminates_term
)
2165 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2167 newexp
= attr_rtx (IOR
, left
, right
);
2169 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2173 /* Check for simplifications. Do some extra checking here since this
2174 routine is called so many times. */
2179 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2182 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2185 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2187 if (attr_alt_subset_p (*pterm
, exp
))
2190 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2193 if (attr_alt_subset_p (exp
, *pterm
))
2199 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2201 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2204 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2210 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2211 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2213 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2216 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2222 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2223 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2225 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2228 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2234 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2236 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2240 else if (GET_CODE (exp
) == NOT
)
2242 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2246 else if (GET_CODE (*pterm
) == NOT
)
2248 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2252 else if (attr_equal_p (exp
, *pterm
))
2258 /* Similar to `simplify_and_tree', but for IOR trees. */
2261 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2266 int left_eliminates_term
, right_eliminates_term
;
2268 if (GET_CODE (exp
) == IOR
)
2270 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2271 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2272 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2274 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2276 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2280 else if (GET_CODE (exp
) == AND
)
2282 /* For the AND case, we do the same as above, except that we can
2283 only eliminate `term' if both sides of the AND would do so. */
2285 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2286 left_eliminates_term
= (temp
== false_rtx
);
2289 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2290 right_eliminates_term
= (temp
== false_rtx
);
2292 if (left_eliminates_term
&& right_eliminates_term
)
2295 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2297 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2299 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2303 if (attr_equal_p (exp
, *pterm
))
2306 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2309 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2312 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2313 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2314 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2317 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2318 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2319 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2325 /* Simplify test expression and use temporary obstack in order to avoid
2326 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2327 and avoid unnecessary copying if possible. */
2330 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2333 struct obstack
*old
;
2334 if (ATTR_IND_SIMPLIFIED_P (exp
))
2337 rtl_obstack
= temp_obstack
;
2338 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2340 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2342 return attr_copy_rtx (x
);
2345 /* Returns true if S1 is a subset of S2. */
2348 attr_alt_subset_p (rtx s1
, rtx s2
)
2350 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2353 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2356 return !(XINT (s1
, 0) & XINT (s2
, 0));
2362 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2369 /* Returns true if S1 is a subset of complement of S2. */
2372 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2374 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2377 return !(XINT (s1
, 0) & XINT (s2
, 0));
2380 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2383 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2393 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2396 attr_alt_intersection (rtx s1
, rtx s2
)
2398 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2400 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2403 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2406 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2409 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2412 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2417 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2422 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2425 attr_alt_union (rtx s1
, rtx s2
)
2427 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2429 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2432 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2435 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2438 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2441 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2447 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2451 /* Return EQ_ATTR_ALT expression representing complement of S. */
2454 attr_alt_complement (rtx s
)
2456 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2458 XINT (result
, 0) = XINT (s
, 0);
2459 XINT (result
, 1) = 1 - XINT (s
, 1);
2464 /* Return EQ_ATTR_ALT expression representing set containing elements set
2468 mk_attr_alt (uint64_t e
)
2470 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2472 XINT (result
, 0) = e
;
2473 XINT (result
, 1) = 0;
2478 /* Given an expression, see if it can be simplified for a particular insn
2479 code based on the values of other attributes being tested. This can
2480 eliminate nested get_attr_... calls.
2482 Note that if an endless recursion is specified in the patterns, the
2483 optimization will loop. However, it will do so in precisely the cases where
2484 an infinite recursion loop could occur during compilation. It's better that
2488 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2491 struct attr_desc
*attr
;
2492 struct attr_value
*av
;
2493 struct insn_ent
*ie
;
2494 struct attr_value_list
*iv
;
2497 bool left_alt
, right_alt
;
2499 /* Don't re-simplify something we already simplified. */
2500 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2503 switch (GET_CODE (exp
))
2506 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2507 if (left
== false_rtx
)
2509 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2510 if (right
== false_rtx
)
2513 if (GET_CODE (left
) == EQ_ATTR_ALT
2514 && GET_CODE (right
) == EQ_ATTR_ALT
)
2516 exp
= attr_alt_intersection (left
, right
);
2517 return simplify_test_exp (exp
, insn_code
, insn_index
);
2520 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2521 present on both sides, apply the distributive law since this will
2522 yield simplifications. */
2523 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2524 && compute_alternative_mask (left
, IOR
)
2525 && compute_alternative_mask (right
, IOR
))
2527 if (GET_CODE (left
) == IOR
)
2528 std::swap (left
, right
);
2530 newexp
= attr_rtx (IOR
,
2531 attr_rtx (AND
, left
, XEXP (right
, 0)),
2532 attr_rtx (AND
, left
, XEXP (right
, 1)));
2534 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2537 /* Try with the term on both sides. */
2538 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2539 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2540 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2542 if (left
== false_rtx
|| right
== false_rtx
)
2544 else if (left
== true_rtx
)
2548 else if (right
== true_rtx
)
2552 /* See if all or all but one of the insn's alternatives are specified
2553 in this tree. Optimize if so. */
2555 if (GET_CODE (left
) == NOT
)
2556 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2557 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2559 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2562 if (GET_CODE (right
) == NOT
)
2563 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2564 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2566 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2567 && XINT (right
, 1));
2570 && (GET_CODE (left
) == AND
2572 || GET_CODE (right
) == AND
2575 i
= compute_alternative_mask (exp
, AND
);
2576 if (i
& ~insn_alternatives
[insn_code
])
2577 fatal ("invalid alternative specified for pattern number %d",
2580 /* If all alternatives are excluded, this is false. */
2581 i
^= insn_alternatives
[insn_code
];
2584 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2586 /* If just one excluded, AND a comparison with that one to the
2587 front of the tree. The others will be eliminated by
2588 optimization. We do not want to do this if the insn has one
2589 alternative and we have tested none of them! */
2590 left
= make_alternative_compare (i
);
2591 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2592 newexp
= attr_rtx (AND
, left
, right
);
2594 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2598 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2600 newexp
= attr_rtx (AND
, left
, right
);
2601 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2606 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2607 if (left
== true_rtx
)
2609 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2610 if (right
== true_rtx
)
2613 if (GET_CODE (left
) == EQ_ATTR_ALT
2614 && GET_CODE (right
) == EQ_ATTR_ALT
)
2616 exp
= attr_alt_union (left
, right
);
2617 return simplify_test_exp (exp
, insn_code
, insn_index
);
2620 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2621 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2622 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2624 if (right
== true_rtx
|| left
== true_rtx
)
2626 else if (left
== false_rtx
)
2630 else if (right
== false_rtx
)
2635 /* Test for simple cases where the distributive law is useful. I.e.,
2636 convert (ior (and (x) (y))
2642 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2643 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2645 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2647 left
= XEXP (left
, 0);
2649 newexp
= attr_rtx (AND
, left
, right
);
2650 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2654 convert (ior (and (y) (x))
2656 to (and (ior (y) (z))
2658 Note that we want the common term to stay at the end.
2661 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2662 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2664 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2667 right
= XEXP (right
, 1);
2668 newexp
= attr_rtx (AND
, left
, right
);
2669 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2672 /* See if all or all but one of the insn's alternatives are specified
2673 in this tree. Optimize if so. */
2675 else if (insn_code
>= 0
2676 && (GET_CODE (left
) == IOR
2677 || (GET_CODE (left
) == EQ_ATTR_ALT
2679 || (GET_CODE (left
) == EQ_ATTR
2680 && XSTR (left
, 0) == alternative_name
)
2681 || GET_CODE (right
) == IOR
2682 || (GET_CODE (right
) == EQ_ATTR_ALT
2683 && !XINT (right
, 1))
2684 || (GET_CODE (right
) == EQ_ATTR
2685 && XSTR (right
, 0) == alternative_name
)))
2687 i
= compute_alternative_mask (exp
, IOR
);
2688 if (i
& ~insn_alternatives
[insn_code
])
2689 fatal ("invalid alternative specified for pattern number %d",
2692 /* If all alternatives are included, this is true. */
2693 i
^= insn_alternatives
[insn_code
];
2696 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2698 /* If just one excluded, IOR a comparison with that one to the
2699 front of the tree. The others will be eliminated by
2700 optimization. We do not want to do this if the insn has one
2701 alternative and we have tested none of them! */
2702 left
= make_alternative_compare (i
);
2703 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2704 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2706 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2710 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2712 newexp
= attr_rtx (IOR
, left
, right
);
2713 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2718 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2720 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2721 insn_code
, insn_index
);
2725 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2726 if (GET_CODE (left
) == NOT
)
2727 return XEXP (left
, 0);
2729 if (left
== false_rtx
)
2731 if (left
== true_rtx
)
2734 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2736 exp
= attr_alt_complement (left
);
2737 return simplify_test_exp (exp
, insn_code
, insn_index
);
2740 /* Try to apply De`Morgan's laws. */
2741 if (GET_CODE (left
) == IOR
)
2743 newexp
= attr_rtx (AND
,
2744 attr_rtx (NOT
, XEXP (left
, 0)),
2745 attr_rtx (NOT
, XEXP (left
, 1)));
2747 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2749 else if (GET_CODE (left
) == AND
)
2751 newexp
= attr_rtx (IOR
,
2752 attr_rtx (NOT
, XEXP (left
, 0)),
2753 attr_rtx (NOT
, XEXP (left
, 1)));
2755 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2757 else if (left
!= XEXP (exp
, 0))
2759 newexp
= attr_rtx (NOT
, left
);
2765 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2769 if (XSTR (exp
, 0) == alternative_name
)
2771 newexp
= mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
2775 /* Look at the value for this insn code in the specified attribute.
2776 We normally can replace this comparison with the condition that
2777 would give this insn the values being tested for. */
2779 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2784 if (insn_code_values
)
2786 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2787 if (iv
->attr
== attr
)
2795 for (av
= attr
->first_value
; av
; av
= av
->next
)
2796 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2797 if (ie
->def
->insn_code
== insn_code
)
2804 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2805 insn_code
, insn_index
);
2806 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2807 if (attr_rtx_cost (x
) < 7)
2817 /* We have already simplified this expression. Simplifying it again
2818 won't buy anything unless we weren't given a valid insn code
2819 to process (i.e., we are canonicalizing something.). */
2821 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2822 return copy_rtx_unchanging (newexp
);
2827 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2828 otherwise return 0. */
2831 tests_attr_p (rtx p
, struct attr_desc
*attr
)
2836 if (GET_CODE (p
) == EQ_ATTR
)
2838 if (XSTR (p
, 0) != attr
->name
)
2843 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2844 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2845 for (i
= 0; i
< ie
; i
++)
2850 if (tests_attr_p (XEXP (p
, i
), attr
))
2855 je
= XVECLEN (p
, i
);
2856 for (j
= 0; j
< je
; ++j
)
2857 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2866 /* Calculate a topological sorting of all attributes so that
2867 all attributes only depend on attributes in front of it.
2868 Place the result in *RET (which is a pointer to an array of
2869 attr_desc pointers), and return the size of that array. */
2872 get_attr_order (struct attr_desc
***ret
)
2876 struct attr_desc
*attr
;
2877 struct attr_desc
**all
, **sorted
;
2879 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2880 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2882 all
= XNEWVEC (struct attr_desc
*, num
);
2883 sorted
= XNEWVEC (struct attr_desc
*, num
);
2884 handled
= XCNEWVEC (char, num
);
2886 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2887 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2891 for (i
= 0; i
< num
; i
++)
2892 if (all
[i
]->is_const
)
2893 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2895 /* We have only few attributes hence we can live with the inner
2896 loop being O(n^2), unlike the normal fast variants of topological
2900 for (i
= 0; i
< num
; i
++)
2903 /* Let's see if I depends on anything interesting. */
2905 for (k
= 0; k
< num
; k
++)
2908 struct attr_value
*av
;
2909 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2910 if (av
->num_insns
!= 0)
2911 if (tests_attr_p (av
->value
, all
[k
]))
2915 /* Something in I depends on K. */
2920 /* Nothing in I depended on anything intersting, so
2923 sorted
[j
++] = all
[i
];
2929 for (j
= 0; j
< num
; j
++)
2931 struct attr_desc
*attr2
;
2932 struct attr_value
*av
;
2935 fprintf (stderr
, "%s depends on: ", attr
->name
);
2936 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2937 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2938 if (!attr2
->is_const
)
2939 for (av
= attr
->first_value
; av
; av
= av
->next
)
2940 if (av
->num_insns
!= 0)
2941 if (tests_attr_p (av
->value
, attr2
))
2943 fprintf (stderr
, "%s, ", attr2
->name
);
2946 fprintf (stderr
, "\n");
2954 /* Optimize the attribute lists by seeing if we can determine conditional
2955 values from the known values of other attributes. This will save subroutine
2956 calls during the compilation. NUM_INSN_CODES is the number of unique
2957 instruction codes. */
2960 optimize_attrs (int num_insn_codes
)
2962 struct attr_desc
*attr
;
2963 struct attr_value
*av
;
2964 struct insn_ent
*ie
;
2967 struct attr_value_list
*ivbuf
;
2968 struct attr_value_list
*iv
;
2969 struct attr_desc
**topsort
;
2972 /* For each insn code, make a list of all the insn_ent's for it,
2973 for all values for all attributes. */
2975 if (num_insn_ents
== 0)
2978 /* Make 2 extra elements, for "code" values -2 and -1. */
2979 insn_code_values
= XCNEWVEC (struct attr_value_list
*, num_insn_codes
+ 2);
2981 /* Offset the table address so we can index by -2 or -1. */
2982 insn_code_values
+= 2;
2984 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2986 /* Create the chain of insn*attr values such that we see dependend
2987 attributes after their dependencies. As we use a stack via the
2988 next pointers start from the end of the topological order. */
2989 topnum
= get_attr_order (&topsort
);
2990 for (i
= topnum
- 1; i
>= 0; i
--)
2991 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
2992 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2994 iv
->attr
= topsort
[i
];
2997 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2998 insn_code_values
[ie
->def
->insn_code
] = iv
;
3003 /* Sanity check on num_insn_ents. */
3004 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
3006 /* Process one insn code at a time. */
3007 for (i
= -2; i
< num_insn_codes
; i
++)
3009 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3010 We use it to mean "already simplified for this insn". */
3011 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3012 clear_struct_flag (iv
->av
->value
);
3014 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3016 struct obstack
*old
= rtl_obstack
;
3021 if (GET_CODE (av
->value
) != COND
)
3024 rtl_obstack
= temp_obstack
;
3026 while (GET_CODE (newexp
) == COND
)
3028 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
3029 ie
->def
->insn_index
);
3030 if (newexp2
== newexp
)
3036 /* If we created a new value for this instruction, and it's
3037 cheaper than the old value, and overall cheap, use that
3038 one as specific value for the current instruction.
3039 The last test is to avoid exploding the get_attr_ function
3040 sizes for no much gain. */
3041 if (newexp
!= av
->value
3042 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
3043 && attr_rtx_cost (newexp
) < 26
3046 newexp
= attr_copy_rtx (newexp
);
3047 remove_insn_ent (av
, ie
);
3048 av
= get_attr_value (ie
->def
->loc
, newexp
, attr
,
3049 ie
->def
->insn_code
);
3051 insert_insn_ent (av
, ie
);
3057 free (insn_code_values
- 2);
3058 insn_code_values
= NULL
;
3061 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3064 clear_struct_flag (rtx x
)
3071 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3072 if (ATTR_IND_SIMPLIFIED_P (x
))
3075 code
= GET_CODE (x
);
3094 /* Compare the elements. If any pair of corresponding elements
3095 fail to match, return 0 for the whole things. */
3097 fmt
= GET_RTX_FORMAT (code
);
3098 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3104 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3105 clear_struct_flag (XVECEXP (x
, i
, j
));
3109 clear_struct_flag (XEXP (x
, i
));
3115 /* Add attribute value NAME to the beginning of ATTR's list. */
3118 add_attr_value (struct attr_desc
*attr
, const char *name
)
3120 struct attr_value
*av
;
3122 av
= oballoc (struct attr_value
);
3123 av
->value
= attr_rtx (CONST_STRING
, name
);
3124 av
->next
= attr
->first_value
;
3125 attr
->first_value
= av
;
3126 av
->first_insn
= NULL
;
3128 av
->has_asm_insn
= 0;
3131 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3134 gen_attr (md_rtx_info
*info
)
3136 struct enum_type
*et
;
3137 struct enum_value
*ev
;
3138 struct attr_desc
*attr
;
3139 const char *name_ptr
;
3141 rtx def
= info
->def
;
3143 /* Make a new attribute structure. Check for duplicate by looking at
3144 attr->default_val, since it is initialized by this routine. */
3145 attr
= find_attr (&XSTR (def
, 0), 1);
3146 if (attr
->default_val
)
3148 error_at (info
->loc
, "duplicate definition for attribute %s",
3150 message_at (attr
->loc
, "previous definition");
3153 attr
->loc
= info
->loc
;
3155 if (GET_CODE (def
) == DEFINE_ENUM_ATTR
)
3157 attr
->enum_name
= XSTR (def
, 1);
3158 et
= lookup_enum_type (XSTR (def
, 1));
3159 if (!et
|| !et
->md_p
)
3160 error_at (info
->loc
, "No define_enum called `%s' defined",
3163 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3164 add_attr_value (attr
, ev
->name
);
3166 else if (*XSTR (def
, 1) == '\0')
3167 attr
->is_numeric
= 1;
3170 name_ptr
= XSTR (def
, 1);
3171 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3172 add_attr_value (attr
, p
);
3175 if (GET_CODE (XEXP (def
, 2)) == CONST
)
3178 if (attr
->is_numeric
)
3179 error_at (info
->loc
,
3180 "constant attributes may not take numeric values");
3182 /* Get rid of the CONST node. It is allowed only at top-level. */
3183 XEXP (def
, 2) = XEXP (XEXP (def
, 2), 0);
3186 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3187 error_at (info
->loc
, "`length' attribute must take numeric values");
3189 /* Set up the default value. */
3190 XEXP (def
, 2) = check_attr_value (info
->loc
, XEXP (def
, 2), attr
);
3191 attr
->default_val
= get_attr_value (info
->loc
, XEXP (def
, 2), attr
, -2);
3194 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3195 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3196 number of alternatives as this should be checked elsewhere. */
3199 count_alternatives (rtx exp
)
3204 if (GET_CODE (exp
) == MATCH_OPERAND
)
3205 return n_comma_elts (XSTR (exp
, 2));
3207 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3208 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3213 n
= count_alternatives (XEXP (exp
, i
));
3220 if (XVEC (exp
, i
) != NULL
)
3221 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3223 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3232 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3233 `alternative' attribute. */
3236 compares_alternatives_p (rtx exp
)
3241 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3244 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3245 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3250 if (compares_alternatives_p (XEXP (exp
, i
)))
3255 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3256 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3264 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3267 gen_insn (md_rtx_info
*info
)
3269 struct insn_def
*id
;
3270 rtx def
= info
->def
;
3272 id
= oballoc (struct insn_def
);
3276 id
->loc
= info
->loc
;
3278 switch (GET_CODE (def
))
3281 id
->insn_code
= info
->index
;
3282 id
->insn_index
= insn_index_number
;
3283 id
->num_alternatives
= count_alternatives (def
);
3284 if (id
->num_alternatives
== 0)
3285 id
->num_alternatives
= 1;
3289 case DEFINE_PEEPHOLE
:
3290 id
->insn_code
= info
->index
;
3291 id
->insn_index
= insn_index_number
;
3292 id
->num_alternatives
= count_alternatives (def
);
3293 if (id
->num_alternatives
== 0)
3294 id
->num_alternatives
= 1;
3298 case DEFINE_ASM_ATTRIBUTES
:
3300 id
->insn_index
= -1;
3301 id
->num_alternatives
= 1;
3303 got_define_asm_attributes
= 1;
3311 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3312 true or annul false is specified, and make a `struct delay_desc'. */
3315 gen_delay (md_rtx_info
*info
)
3317 struct delay_desc
*delay
;
3320 rtx def
= info
->def
;
3321 if (XVECLEN (def
, 1) % 3 != 0)
3323 error_at (info
->loc
, "number of elements in DEFINE_DELAY must"
3324 " be multiple of three");
3328 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3330 if (XVECEXP (def
, 1, i
+ 1))
3331 have_annul_true
= 1;
3332 if (XVECEXP (def
, 1, i
+ 2))
3333 have_annul_false
= 1;
3336 delay
= oballoc (struct delay_desc
);
3338 delay
->num
= ++num_delays
;
3339 delay
->next
= delays
;
3340 delay
->loc
= info
->loc
;
3344 /* Names of attributes that could be possibly cached. */
3345 static const char *cached_attrs
[32];
3346 /* Number of such attributes. */
3347 static int cached_attr_count
;
3348 /* Bitmasks of possibly cached attributes. */
3349 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3350 static unsigned int attrs_to_cache
;
3351 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3353 /* Finds non-const attributes that could be possibly cached.
3354 When create is TRUE, fills in cached_attrs array.
3355 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3359 find_attrs_to_cache (rtx exp
, bool create
)
3363 struct attr_desc
*attr
;
3368 switch (GET_CODE (exp
))
3371 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3372 find_attrs_to_cache (XEXP (exp
, 0), create
);
3376 name
= XSTR (exp
, 0);
3377 if (name
== alternative_name
)
3379 for (i
= 0; i
< cached_attr_count
; i
++)
3380 if (name
== cached_attrs
[i
])
3382 if ((attrs_seen_once
& (1U << i
)) != 0)
3383 attrs_seen_more_than_once
|= (1U << i
);
3385 attrs_seen_once
|= (1U << i
);
3390 attr
= find_attr (&name
, 0);
3394 if (cached_attr_count
== 32)
3396 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3397 attrs_seen_once
|= (1U << cached_attr_count
);
3398 cached_attr_count
++;
3403 find_attrs_to_cache (XEXP (exp
, 0), create
);
3404 find_attrs_to_cache (XEXP (exp
, 1), create
);
3408 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3409 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3417 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3418 We use AND and IOR both for logical and bit-wise operations, so
3419 interpret them as logical unless they are inside a comparison expression. */
3421 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3422 #define FLG_BITWISE 1
3423 /* Set if cached attribute will be known initialized in else block after
3424 this condition. This is true for LHS of toplevel && and || and
3425 even for RHS of ||, but not for RHS of &&. */
3427 /* Set if cached attribute will be known initialized in then block after
3428 this condition. This is true for LHS of toplevel && and || and
3429 even for RHS of &&, but not for RHS of ||. */
3430 #define FLG_INSIDE 4
3431 /* Cleared when an operand of &&. */
3432 #define FLG_OUTSIDE_AND 8
3435 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
)
3437 int comparison_operator
= 0;
3439 struct attr_desc
*attr
;
3441 /* In order not to worry about operator precedence, surround our part of
3442 the expression with parentheses. */
3444 fprintf (outf
, "(");
3445 code
= GET_CODE (exp
);
3448 /* Binary operators. */
3451 fprintf (outf
, "(unsigned) ");
3457 comparison_operator
= FLG_BITWISE
;
3459 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3460 case AND
: case IOR
: case XOR
:
3461 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3462 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3464 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3465 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3466 flags
| comparison_operator
);
3471 flags
&= ~FLG_OUTSIDE_AND
;
3472 if (GET_CODE (XEXP (exp
, 0)) == code
3473 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3474 || (GET_CODE (XEXP (exp
, 0)) == NOT
3475 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3477 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3479 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3484 fprintf (outf
, " == ");
3487 fprintf (outf
, " != ");
3490 fprintf (outf
, " >= ");
3493 fprintf (outf
, " > ");
3496 fprintf (outf
, " >= (unsigned) ");
3499 fprintf (outf
, " > (unsigned) ");
3502 fprintf (outf
, " <= ");
3505 fprintf (outf
, " < ");
3508 fprintf (outf
, " <= (unsigned) ");
3511 fprintf (outf
, " < (unsigned) ");
3514 fprintf (outf
, " + ");
3517 fprintf (outf
, " - ");
3520 fprintf (outf
, " * ");
3523 fprintf (outf
, " / ");
3526 fprintf (outf
, " %% ");
3529 if (flags
& FLG_BITWISE
)
3530 fprintf (outf
, " & ");
3532 fprintf (outf
, " && ");
3535 if (flags
& FLG_BITWISE
)
3536 fprintf (outf
, " | ");
3538 fprintf (outf
, " || ");
3541 fprintf (outf
, " ^ ");
3544 fprintf (outf
, " << ");
3548 fprintf (outf
, " >> ");
3556 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3557 cached_x is only known to be initialized in then block. */
3558 flags
&= ~FLG_AFTER
;
3560 else if (code
== IOR
)
3562 if (flags
& FLG_OUTSIDE_AND
)
3563 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3564 cached_x is only known to be initialized in else block
3565 and else if conditions. */
3566 flags
&= ~FLG_INSIDE
;
3568 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3570 cached_x is not know to be initialized anywhere. */
3571 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3573 if ((code
== AND
|| code
== IOR
)
3574 && (GET_CODE (XEXP (exp
, 1)) == code
3575 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3576 || (GET_CODE (XEXP (exp
, 1)) == NOT
3577 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3579 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
);
3581 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3582 flags
| comparison_operator
);
3586 /* Special-case (not (eq_attrq "alternative" "x")) */
3587 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3589 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3591 fprintf (outf
, "which_alternative != %s",
3592 XSTR (XEXP (exp
, 0), 1));
3596 fprintf (outf
, "! ");
3598 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3602 /* Otherwise, fall through to normal unary operator. */
3604 /* Unary operators. */
3609 if (flags
& FLG_BITWISE
)
3610 fprintf (outf
, "~ ");
3612 fprintf (outf
, "! ");
3615 fprintf (outf
, "abs ");
3618 fprintf (outf
, "-");
3624 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3625 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3630 int set
= XINT (exp
, 0), bit
= 0;
3632 if (flags
& FLG_BITWISE
)
3633 fatal ("EQ_ATTR_ALT not valid inside comparison");
3636 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3638 if (!(set
& (set
- 1)))
3640 if (!(set
& 0xffff))
3663 fprintf (outf
, "which_alternative %s= %d",
3664 XINT (exp
, 1) ? "!" : "=", bit
);
3668 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3669 XINT (exp
, 1) ? "!" : "", set
);
3674 /* Comparison test of an attribute with a value. Most of these will
3675 have been removed by optimization. Handle "alternative"
3676 specially and give error if EQ_ATTR present inside a comparison. */
3678 if (flags
& FLG_BITWISE
)
3679 fatal ("EQ_ATTR not valid inside comparison");
3681 if (XSTR (exp
, 0) == alternative_name
)
3683 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3687 attr
= find_attr (&XSTR (exp
, 0), 0);
3690 /* Now is the time to expand the value of a constant attribute. */
3693 write_test_expr (outf
,
3694 evaluate_eq_attr (exp
, attr
,
3695 attr
->default_val
->value
,
3702 for (i
= 0; i
< cached_attr_count
; i
++)
3703 if (attr
->name
== cached_attrs
[i
])
3705 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3706 fprintf (outf
, "cached_%s", attr
->name
);
3707 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3709 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3710 attr
->name
, attr
->name
);
3711 if (flags
& FLG_AFTER
)
3712 attrs_cached_after
|= (1U << i
);
3713 if (flags
& FLG_INSIDE
)
3714 attrs_cached_inside
|= (1U << i
);
3715 attrs_cached
|= (1U << i
);
3718 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3719 fprintf (outf
, " == ");
3720 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3724 /* Comparison test of flags for define_delays. */
3726 if (flags
& FLG_BITWISE
)
3727 fatal ("ATTR_FLAG not valid inside comparison");
3728 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3731 /* See if an operand matches a predicate. */
3733 /* If only a mode is given, just ensure the mode matches the operand.
3734 If neither a mode nor predicate is given, error. */
3735 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3737 if (GET_MODE (exp
) == VOIDmode
)
3738 fatal ("null MATCH_OPERAND specified as test");
3740 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3741 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3744 fprintf (outf
, "%s (operands[%d], %smode)",
3745 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3748 /* Constant integer. */
3750 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3754 fprint_c_condition (outf
, XSTR (exp
, 0));
3755 if (flags
& FLG_BITWISE
)
3756 fprintf (outf
, " != 0");
3759 /* A random C expression. */
3761 fprint_c_condition (outf
, XSTR (exp
, 0));
3764 /* The address of the branch target. */
3767 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3768 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3772 /* The address of the current insn. We implement this actually as the
3773 address of the current insn for backward branches, but the last
3774 address of the next insn for forward branches, and both with
3775 adjustments that account for the worst-case possible stretching of
3776 intervening alignments between this insn and its destination. */
3777 fprintf (outf
, "insn_current_reference_address (insn)");
3781 fprintf (outf
, "%s", XSTR (exp
, 0));
3785 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3786 fprintf (outf
, " ? ");
3787 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3788 fprintf (outf
, " : ");
3789 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3793 fatal ("bad RTX code `%s' in attribute calculation\n",
3794 GET_RTX_NAME (code
));
3797 fprintf (outf
, ")");
3798 return attrs_cached
;
3801 /* Given an attribute value, return the maximum CONST_STRING argument
3802 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3805 max_attr_value (rtx exp
, int *unknownp
)
3810 switch (GET_CODE (exp
))
3813 current_max
= atoi (XSTR (exp
, 0));
3817 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3818 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3820 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3821 if (n
> current_max
)
3827 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3828 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3829 if (n
> current_max
)
3835 current_max
= INT_MAX
;
3842 /* Given an attribute value, return the minimum CONST_STRING argument
3843 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3846 min_attr_value (rtx exp
, int *unknownp
)
3851 switch (GET_CODE (exp
))
3854 current_min
= atoi (XSTR (exp
, 0));
3858 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3859 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3861 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3862 if (n
< current_min
)
3868 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3869 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3870 if (n
< current_min
)
3876 current_min
= INT_MAX
;
3883 /* Given an attribute value, return the result of ORing together all
3884 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3885 if the numeric value is not known. */
3888 or_attr_value (rtx exp
, int *unknownp
)
3893 switch (GET_CODE (exp
))
3896 current_or
= atoi (XSTR (exp
, 0));
3900 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3901 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3902 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3906 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3907 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3919 /* Scan an attribute value, possibly a conditional, and record what actions
3920 will be required to do any conditional tests in it.
3923 `must_extract' if we need to extract the insn operands
3924 `must_constrain' if we must compute `which_alternative'
3925 `address_used' if an address expression was used
3926 `length_used' if an (eq_attr "length" ...) was used
3930 walk_attr_value (rtx exp
)
3939 code
= GET_CODE (exp
);
3943 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3944 /* Since this is an arbitrary expression, it can look at anything.
3945 However, constant expressions do not depend on any particular
3947 must_extract
= must_constrain
= 1;
3956 must_extract
= must_constrain
= 1;
3960 if (XSTR (exp
, 0) == alternative_name
)
3961 must_extract
= must_constrain
= 1;
3962 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3982 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3987 walk_attr_value (XEXP (exp
, i
));
3991 if (XVEC (exp
, i
) != NULL
)
3992 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3993 walk_attr_value (XVECEXP (exp
, i
, j
));
3998 /* Write out a function to obtain the attribute for a given INSN. */
4001 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
4003 struct attr_value
*av
, *common_av
;
4006 /* Find the most used attribute value. Handle that as the `default' of the
4007 switch we will generate. */
4008 common_av
= find_most_used (attr
);
4010 /* Write out start of function, then all values with explicit `case' lines,
4011 then a `default', then the value with the most uses. */
4012 if (attr
->enum_name
)
4013 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4014 else if (!attr
->is_numeric
)
4015 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4017 fprintf (outf
, "int\n");
4019 /* If the attribute name starts with a star, the remainder is the name of
4020 the subroutine to use, instead of `get_attr_...'. */
4021 if (attr
->name
[0] == '*')
4022 fprintf (outf
, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4023 else if (attr
->is_const
== 0)
4024 fprintf (outf
, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4027 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4028 fprintf (outf
, "{\n");
4030 for (av
= attr
->first_value
; av
; av
= av
->next
)
4031 if (av
->num_insns
== 1)
4032 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4033 true_rtx
, av
->first_insn
->def
->insn_code
,
4034 av
->first_insn
->def
->insn_index
, 0);
4035 else if (av
->num_insns
!= 0)
4036 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4037 true_rtx
, -2, 0, 0);
4039 fprintf (outf
, "}\n\n");
4043 fprintf (outf
, "{\n");
4045 /* Find attributes that are worth caching in the conditions. */
4046 cached_attr_count
= 0;
4047 attrs_seen_more_than_once
= 0;
4048 for (av
= attr
->first_value
; av
; av
= av
->next
)
4050 attrs_seen_once
= 0;
4051 find_attrs_to_cache (av
->value
, true);
4053 /* Remove those that aren't worth caching from the array. */
4054 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4055 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4057 const char *name
= cached_attrs
[i
];
4058 struct attr_desc
*cached_attr
;
4060 cached_attrs
[j
] = name
;
4061 cached_attr
= find_attr (&name
, 0);
4062 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4063 if (cached_attr
->enum_name
)
4064 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4065 else if (!cached_attr
->is_numeric
)
4066 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4068 fprintf (outf
, " int");
4069 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4072 cached_attr_count
= j
;
4073 if (cached_attr_count
)
4074 fprintf (outf
, "\n");
4076 fprintf (outf
, " switch (recog_memoized (insn))\n");
4077 fprintf (outf
, " {\n");
4079 for (av
= attr
->first_value
; av
; av
= av
->next
)
4080 if (av
!= common_av
)
4081 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4083 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4084 fprintf (outf
, " }\n}\n\n");
4085 cached_attr_count
= 0;
4088 /* Given an AND tree of known true terms (because we are inside an `if' with
4089 that as the condition or are in an `else' clause) and an expression,
4090 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4091 the bulk of the work. */
4094 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4098 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4100 if (GET_CODE (known_true
) == AND
)
4102 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4103 insn_code
, insn_index
);
4104 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4105 insn_code
, insn_index
);
4110 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4116 /* Write out a series of tests and assignment statements to perform tests and
4117 sets of an attribute value. We are passed an indentation amount and prefix
4118 and suffix strings to write around each attribute value (e.g., "return"
4122 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
4123 const char *prefix
, const char *suffix
, rtx known_true
,
4124 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4126 if (GET_CODE (value
) == COND
)
4128 /* Assume the default value will be the default of the COND unless we
4129 find an always true expression. */
4130 rtx default_val
= XEXP (value
, 1);
4131 rtx our_known_true
= known_true
;
4136 if (cached_attr_count
)
4138 attrs_seen_once
= 0;
4139 attrs_seen_more_than_once
= 0;
4140 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4141 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4142 attrs_to_cache
|= attrs_seen_more_than_once
;
4145 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4150 /* Reset our_known_true after some time to not accumulate
4151 too much cruft (slowing down genattrtab). */
4153 our_known_true
= known_true
;
4154 testexp
= eliminate_known_true (our_known_true
,
4155 XVECEXP (value
, 0, i
),
4156 insn_code
, insn_index
);
4157 newexp
= attr_rtx (NOT
, testexp
);
4158 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4159 insn_code
, insn_index
);
4161 /* If the test expression is always true or if the next `known_true'
4162 expression is always false, this is the last case, so break
4163 out and let this value be the `else' case. */
4164 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4166 default_val
= XVECEXP (value
, 0, i
+ 1);
4170 /* Compute the expression to pass to our recursive call as being
4172 inner_true
= insert_right_side (AND
, our_known_true
,
4173 testexp
, insn_code
, insn_index
);
4175 /* If this is always false, skip it. */
4176 if (inner_true
== false_rtx
)
4179 attrs_cached_inside
= attrs_cached
;
4180 attrs_cached_after
= attrs_cached
;
4181 write_indent (outf
, indent
);
4182 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4184 write_test_expr (outf
, testexp
, attrs_cached
,
4185 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4186 attrs_cached
= attrs_cached_after
;
4187 fprintf (outf
, "\n");
4188 write_indent (outf
, indent
+ 2);
4189 fprintf (outf
, "{\n");
4191 write_attr_set (outf
, attr
, indent
+ 4,
4192 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4193 inner_true
, insn_code
, insn_index
,
4194 attrs_cached_inside
);
4195 write_indent (outf
, indent
+ 2);
4196 fprintf (outf
, "}\n");
4197 our_known_true
= newexp
;
4202 write_indent (outf
, indent
);
4203 fprintf (outf
, "else\n");
4204 write_indent (outf
, indent
+ 2);
4205 fprintf (outf
, "{\n");
4208 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4209 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4214 write_indent (outf
, indent
+ 2);
4215 fprintf (outf
, "}\n");
4220 write_indent (outf
, indent
);
4221 fprintf (outf
, "%s ", prefix
);
4222 write_attr_value (outf
, attr
, value
);
4223 fprintf (outf
, "%s\n", suffix
);
4227 /* Write a series of case statements for every instruction in list IE.
4228 INDENT is the amount of indentation to write before each case. */
4231 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4233 for (; ie
!= 0; ie
= ie
->next
)
4234 if (ie
->def
->insn_code
!= -1)
4236 write_indent (outf
, indent
);
4237 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4238 fprintf (outf
, "case %d: /* define_peephole, %s:%d */\n",
4239 ie
->def
->insn_code
, ie
->def
->loc
.filename
,
4240 ie
->def
->loc
.lineno
);
4242 fprintf (outf
, "case %d: /* %s */\n",
4243 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4247 /* Write out the computation for one attribute value. */
4250 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4251 int write_case_lines
, const char *prefix
, const char *suffix
,
4252 int indent
, rtx known_true
)
4254 if (av
->num_insns
== 0)
4257 if (av
->has_asm_insn
)
4259 write_indent (outf
, indent
);
4260 fprintf (outf
, "case -1:\n");
4261 write_indent (outf
, indent
+ 2);
4262 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4263 write_indent (outf
, indent
+ 2);
4264 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4265 write_indent (outf
, indent
+ 2);
4266 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4269 if (write_case_lines
)
4270 write_insn_cases (outf
, av
->first_insn
, indent
);
4273 write_indent (outf
, indent
);
4274 fprintf (outf
, "default:\n");
4277 /* See what we have to do to output this value. */
4278 must_extract
= must_constrain
= address_used
= 0;
4279 walk_attr_value (av
->value
);
4283 write_indent (outf
, indent
+ 2);
4284 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4286 else if (must_extract
)
4288 write_indent (outf
, indent
+ 2);
4289 fprintf (outf
, "extract_insn_cached (insn);\n");
4293 if (av
->num_insns
== 1)
4294 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4295 known_true
, av
->first_insn
->def
->insn_code
,
4296 av
->first_insn
->def
->insn_index
, 0);
4298 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4299 known_true
, -2, 0, 0);
4301 if (strncmp (prefix
, "return", 6))
4303 write_indent (outf
, indent
+ 2);
4304 fprintf (outf
, "break;\n");
4306 fprintf (outf
, "\n");
4309 /* Utilities to write in various forms. */
4312 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4314 if (attr
->is_numeric
)
4318 fprintf (outf
, "%d", num
);
4320 if (num
> 9 || num
< 0)
4321 fprintf (outf
, " /* %#x */", num
);
4325 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4326 fprintf (outf
, "_");
4327 write_upcase (outf
, s
);
4332 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4336 switch (GET_CODE (value
))
4339 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4343 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4347 fprint_c_condition (outf
, XSTR (value
, 0));
4352 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4353 if (attr
->enum_name
)
4354 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4355 else if (!attr
->is_numeric
)
4356 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4357 else if (!attr2
->is_numeric
)
4358 fprintf (outf
, "(int)");
4360 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4361 (attr2
->is_const
? "" : "insn"));
4382 write_attr_value (outf
, attr
, XEXP (value
, 0));
4386 write_attr_value (outf
, attr
, XEXP (value
, 1));
4395 write_upcase (FILE *outf
, const char *str
)
4399 /* The argument of TOUPPER should not have side effects. */
4400 fputc (TOUPPER (*str
), outf
);
4406 write_indent (FILE *outf
, int indent
)
4408 for (; indent
> 8; indent
-= 8)
4409 fprintf (outf
, "\t");
4411 for (; indent
; indent
--)
4412 fprintf (outf
, " ");
4415 /* If the target does not have annul-true or annul-false delay slots, this
4416 function will create a dummy eligible_for function on OUTF which always
4417 returns false. KIND will be annul_true or annul_false. */
4420 write_dummy_eligible_delay (FILE *outf
, const char *kind
)
4422 /* Write function prelude. */
4424 fprintf (outf
, "int\n");
4425 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4426 " int slot ATTRIBUTE_UNUSED,\n"
4427 " rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4428 " int flags ATTRIBUTE_UNUSED)\n",
4430 fprintf (outf
, "{\n");
4431 fprintf (outf
, " return 0;\n");
4432 fprintf (outf
, "}\n\n");
4435 /* Write a subroutine that is given an insn that requires a delay slot, a
4436 delay slot ordinal, and a candidate insn. It returns nonzero if the
4437 candidate can be placed in the specified delay slot of the insn.
4439 We can write as many as three subroutines. `eligible_for_delay'
4440 handles normal delay slots, `eligible_for_annul_true' indicates that
4441 the specified insn can be annulled if the branch is true, and likewise
4442 for `eligible_for_annul_false'.
4444 KIND is a string distinguishing these three cases ("delay", "annul_true",
4445 or "annul_false"). */
4448 write_eligible_delay (FILE *outf
, const char *kind
)
4450 struct delay_desc
*delay
;
4454 struct attr_desc
*attr
;
4455 struct attr_value
*av
, *common_av
;
4458 /* Compute the maximum number of delay slots required. We use the delay
4459 ordinal times this number plus one, plus the slot number as an index into
4460 the appropriate predicate to test. */
4462 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4463 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4464 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4466 /* Write function prelude. */
4468 fprintf (outf
, "int\n");
4469 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4470 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4472 fprintf (outf
, "{\n");
4473 fprintf (outf
, " rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4474 fprintf (outf
, "\n");
4475 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4476 fprintf (outf
, "\n");
4477 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4478 converts a compound instruction into a loop. */
4479 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4480 fprintf (outf
, " return 0;\n");
4481 fprintf (outf
, "\n");
4483 /* If more than one delay type, find out which type the delay insn is. */
4487 attr
= find_attr (&delay_type_str
, 0);
4489 common_av
= find_most_used (attr
);
4491 fprintf (outf
, " insn = delay_insn;\n");
4492 fprintf (outf
, " switch (recog_memoized (insn))\n");
4493 fprintf (outf
, " {\n");
4495 sprintf (str
, " * %d;\n break;", max_slots
);
4496 for (av
= attr
->first_value
; av
; av
= av
->next
)
4497 if (av
!= common_av
)
4498 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4500 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4501 fprintf (outf
, " }\n\n");
4503 /* Ensure matched. Otherwise, shouldn't have been called. */
4504 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4507 /* If just one type of delay slot, write simple switch. */
4508 if (num_delays
== 1 && max_slots
== 1)
4510 fprintf (outf
, " insn = candidate_insn;\n");
4511 fprintf (outf
, " switch (recog_memoized (insn))\n");
4512 fprintf (outf
, " {\n");
4514 attr
= find_attr (&delay_1_0_str
, 0);
4516 common_av
= find_most_used (attr
);
4518 for (av
= attr
->first_value
; av
; av
= av
->next
)
4519 if (av
!= common_av
)
4520 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4522 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4523 fprintf (outf
, " }\n");
4528 /* Write a nested CASE. The first indicates which condition we need to
4529 test, and the inner CASE tests the condition. */
4530 fprintf (outf
, " insn = candidate_insn;\n");
4531 fprintf (outf
, " switch (slot)\n");
4532 fprintf (outf
, " {\n");
4534 for (delay
= delays
; delay
; delay
= delay
->next
)
4535 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4537 fprintf (outf
, " case %d:\n",
4538 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4539 fprintf (outf
, " switch (recog_memoized (insn))\n");
4540 fprintf (outf
, "\t{\n");
4542 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4544 attr
= find_attr (&pstr
, 0);
4546 common_av
= find_most_used (attr
);
4548 for (av
= attr
->first_value
; av
; av
= av
->next
)
4549 if (av
!= common_av
)
4550 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4552 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4553 fprintf (outf
, " }\n");
4556 fprintf (outf
, " default:\n");
4557 fprintf (outf
, " gcc_unreachable ();\n");
4558 fprintf (outf
, " }\n");
4561 fprintf (outf
, "}\n\n");
4564 /* This page contains miscellaneous utility routines. */
4566 /* Given a pointer to a (char *), return a malloc'ed string containing the
4567 next comma-separated element. Advance the pointer to after the string
4568 scanned, or the end-of-string. Return NULL if at end of string. */
4571 next_comma_elt (const char **pstr
)
4575 start
= scan_comma_elt (pstr
);
4580 return attr_string (start
, *pstr
- start
);
4583 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4584 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4585 replaced by a pointer to a canonical copy of the string. */
4587 static struct attr_desc
*
4588 find_attr (const char **name_p
, int create
)
4590 struct attr_desc
*attr
;
4592 const char *name
= *name_p
;
4594 /* Before we resort to using `strcmp', see if the string address matches
4595 anywhere. In most cases, it should have been canonicalized to do so. */
4596 if (name
== alternative_name
)
4599 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4600 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4601 if (name
== attr
->name
)
4604 /* Otherwise, do it the slow way. */
4605 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4606 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4608 *name_p
= attr
->name
;
4615 attr
= oballoc (struct attr_desc
);
4616 attr
->name
= DEF_ATTR_STRING (name
);
4617 attr
->enum_name
= 0;
4618 attr
->first_value
= attr
->default_val
= NULL
;
4619 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4620 attr
->next
= attrs
[index
];
4621 attrs
[index
] = attr
;
4623 *name_p
= attr
->name
;
4628 /* Create internal attribute with the given default value. */
4631 make_internal_attr (const char *name
, rtx value
, int special
)
4633 struct attr_desc
*attr
;
4635 attr
= find_attr (&name
, 1);
4636 gcc_assert (!attr
->default_val
);
4638 attr
->is_numeric
= 1;
4640 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4641 attr
->default_val
= get_attr_value (file_location ("<internal>", 0),
4645 /* Find the most used value of an attribute. */
4647 static struct attr_value
*
4648 find_most_used (struct attr_desc
*attr
)
4650 struct attr_value
*av
;
4651 struct attr_value
*most_used
;
4657 for (av
= attr
->first_value
; av
; av
= av
->next
)
4658 if (av
->num_insns
> nuses
)
4659 nuses
= av
->num_insns
, most_used
= av
;
4664 /* Return (attr_value "n") */
4667 make_numeric_value (int n
)
4669 static rtx int_values
[20];
4673 gcc_assert (n
>= 0);
4675 if (n
< 20 && int_values
[n
])
4676 return int_values
[n
];
4678 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4679 exp
= attr_rtx (CONST_STRING
, p
);
4682 int_values
[n
] = exp
;
4688 copy_rtx_unchanging (rtx orig
)
4690 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4693 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4697 /* Determine if an insn has a constant number of delay slots, i.e., the
4698 number of delay slots is not a function of the length of the insn. */
4701 write_const_num_delay_slots (FILE *outf
)
4703 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4704 struct attr_value
*av
;
4708 fprintf (outf
, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4709 fprintf (outf
, "{\n");
4710 fprintf (outf
, " switch (recog_memoized (insn))\n");
4711 fprintf (outf
, " {\n");
4713 for (av
= attr
->first_value
; av
; av
= av
->next
)
4716 walk_attr_value (av
->value
);
4718 write_insn_cases (outf
, av
->first_insn
, 4);
4721 fprintf (outf
, " default:\n");
4722 fprintf (outf
, " return 1;\n");
4723 fprintf (outf
, " }\n}\n\n");
4727 /* Synthetic attributes used by insn-automata.c and the scheduler.
4728 These are primarily concerned with (define_insn_reservation)
4733 struct insn_reserv
*next
;
4736 int default_latency
;
4739 /* Sequence number of this insn. */
4742 /* Whether a (define_bypass) construct names this insn in its
4747 static struct insn_reserv
*all_insn_reservs
= 0;
4748 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4749 static size_t n_insn_reservs
;
4751 /* Store information from a DEFINE_INSN_RESERVATION for future
4752 attribute generation. */
4754 gen_insn_reserv (md_rtx_info
*info
)
4756 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4757 rtx def
= info
->def
;
4759 struct attr_desc attr
;
4760 memset (&attr
, 0, sizeof (attr
));
4761 attr
.name
= DEF_ATTR_STRING (XSTR (def
, 0));
4762 attr
.loc
= info
->loc
;
4764 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4765 decl
->default_latency
= XINT (def
, 1);
4766 decl
->condexp
= check_attr_test (info
->loc
, XEXP (def
, 2), &attr
);
4767 decl
->insn_num
= n_insn_reservs
;
4768 decl
->bypassed
= false;
4771 *last_insn_reserv_p
= decl
;
4772 last_insn_reserv_p
= &decl
->next
;
4776 /* Store information from a DEFINE_BYPASS for future attribute
4777 generation. The only thing we care about is the list of output
4778 insns, which will later be used to tag reservation structures with
4779 a 'bypassed' bit. */
4783 struct bypass_list
*next
;
4784 const char *pattern
;
4787 static struct bypass_list
*all_bypasses
;
4788 static size_t n_bypasses
;
4789 static size_t n_bypassed
;
4792 gen_bypass_1 (const char *s
, size_t len
)
4794 struct bypass_list
*b
;
4799 s
= attr_string (s
, len
);
4800 for (b
= all_bypasses
; b
; b
= b
->next
)
4801 if (s
== b
->pattern
)
4802 return; /* already got that one */
4804 b
= oballoc (struct bypass_list
);
4806 b
->next
= all_bypasses
;
4812 gen_bypass (md_rtx_info
*info
)
4814 const char *p
, *base
;
4816 rtx def
= info
->def
;
4817 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4820 gen_bypass_1 (base
, p
- base
);
4823 while (ISSPACE (*p
));
4826 gen_bypass_1 (base
, p
- base
);
4829 /* Find and mark all of the bypassed insns. */
4831 process_bypasses (void)
4833 struct bypass_list
*b
;
4834 struct insn_reserv
*r
;
4838 /* The reservation list is likely to be much longer than the bypass
4840 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4841 for (b
= all_bypasses
; b
; b
= b
->next
)
4842 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4850 /* Check that attribute NAME is used in define_insn_reservation condition
4851 EXP. Return true if it is. */
4853 check_tune_attr (const char *name
, rtx exp
)
4855 switch (GET_CODE (exp
))
4858 if (check_tune_attr (name
, XEXP (exp
, 0)))
4860 return check_tune_attr (name
, XEXP (exp
, 1));
4863 return (check_tune_attr (name
, XEXP (exp
, 0))
4864 && check_tune_attr (name
, XEXP (exp
, 1)));
4867 return XSTR (exp
, 0) == name
;
4874 /* Try to find a const attribute (usually cpu or tune) that is used
4875 in all define_insn_reservation conditions. */
4876 static struct attr_desc
*
4877 find_tune_attr (rtx exp
)
4879 struct attr_desc
*attr
;
4881 switch (GET_CODE (exp
))
4885 attr
= find_tune_attr (XEXP (exp
, 0));
4888 return find_tune_attr (XEXP (exp
, 1));
4891 if (XSTR (exp
, 0) == alternative_name
)
4894 attr
= find_attr (&XSTR (exp
, 0), 0);
4897 if (attr
->is_const
&& !attr
->is_special
)
4899 struct insn_reserv
*decl
;
4901 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4902 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4913 /* Create all of the attributes that describe automaton properties.
4914 Write the DFA and latency function prototypes to the files that
4915 need to have them, and write the init_sched_attrs(). */
4918 make_automaton_attrs (void)
4921 struct insn_reserv
*decl
;
4922 rtx code_exp
, lats_exp
, byps_exp
;
4923 struct attr_desc
*tune_attr
;
4925 if (n_insn_reservs
== 0)
4928 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4929 if (tune_attr
!= NULL
)
4931 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4932 struct attr_value
*val
;
4935 gcc_assert (tune_attr
->is_const
4936 && !tune_attr
->is_special
4937 && !tune_attr
->is_numeric
);
4939 /* Write the prototypes for all DFA functions. */
4940 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4942 if (val
== tune_attr
->default_val
)
4944 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4946 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4947 XSTR (val
->value
, 0));
4949 fprintf (dfa_file
, "\n");
4951 /* Write the prototypes for all latency functions. */
4952 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4954 if (val
== tune_attr
->default_val
)
4956 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4957 fprintf (latency_file
,
4958 "extern int insn_default_latency_%s (rtx_insn *);\n",
4959 XSTR (val
->value
, 0));
4961 fprintf (latency_file
, "\n");
4963 /* Write the prototypes for all automaton functions. */
4964 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4966 if (val
== tune_attr
->default_val
)
4968 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4970 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4971 "extern int insn_default_latency_%s (rtx_insn *);\n",
4972 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4974 fprintf (attr_file
, "\n");
4975 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4976 fprintf (attr_file
, "int (*insn_default_latency) (rtx_insn *);\n");
4977 fprintf (attr_file
, "\n");
4978 fprintf (attr_file
, "void\n");
4979 fprintf (attr_file
, "init_sched_attrs (void)\n");
4980 fprintf (attr_file
, "{\n");
4982 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4986 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
4988 if (val
== tune_attr
->default_val
)
4990 for (decl
= all_insn_reservs
, i
= 0;
4996 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
4997 if (condexp
== false_rtx
)
4999 if (condexp
== true_rtx
)
5001 condexps
[i
] = condexp
;
5002 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
5003 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
5007 code_exp
= rtx_alloc (COND
);
5008 lats_exp
= rtx_alloc (COND
);
5011 XVEC (code_exp
, 0) = rtvec_alloc (j
);
5012 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
5016 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
5017 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
5021 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5022 XEXP (lats_exp
, 1) = make_numeric_value (0);
5029 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
5030 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
5032 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
5033 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5036 name
= XNEWVEC (char,
5037 sizeof ("*internal_dfa_insn_code_")
5038 + strlen (XSTR (val
->value
, 0)));
5039 strcpy (name
, "*internal_dfa_insn_code_");
5040 strcat (name
, XSTR (val
->value
, 0));
5041 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5042 strcpy (name
, "*insn_default_latency_");
5043 strcat (name
, XSTR (val
->value
, 0));
5044 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5049 fprintf (attr_file
, " if (");
5053 fprintf (attr_file
, " else if (");
5054 write_test_expr (attr_file
, test
, 0, 0);
5055 fprintf (attr_file
, ")\n");
5056 fprintf (attr_file
, " {\n");
5057 fprintf (attr_file
, " internal_dfa_insn_code\n");
5058 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5059 XSTR (val
->value
, 0));
5060 fprintf (attr_file
, " insn_default_latency\n");
5061 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5062 XSTR (val
->value
, 0));
5063 fprintf (attr_file
, " }\n");
5066 fprintf (attr_file
, " else\n");
5067 fprintf (attr_file
, " gcc_unreachable ();\n");
5068 fprintf (attr_file
, "}\n");
5069 fprintf (attr_file
, "\n");
5071 XDELETEVEC (condexps
);
5075 code_exp
= rtx_alloc (COND
);
5076 lats_exp
= rtx_alloc (COND
);
5078 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5079 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5081 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5082 XEXP (lats_exp
, 1) = make_numeric_value (0);
5084 for (decl
= all_insn_reservs
, i
= 0;
5086 decl
= decl
->next
, i
+= 2)
5088 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5089 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5091 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5092 XVECEXP (lats_exp
, 0, i
+1)
5093 = make_numeric_value (decl
->default_latency
);
5095 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5096 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5099 if (n_bypasses
== 0)
5100 byps_exp
= make_numeric_value (0);
5103 process_bypasses ();
5105 byps_exp
= rtx_alloc (COND
);
5106 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypassed
* 2);
5107 XEXP (byps_exp
, 1) = make_numeric_value (0);
5108 for (decl
= all_insn_reservs
, i
= 0;
5113 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5114 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5119 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5123 write_header (FILE *outf
)
5125 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5126 " from the machine description file `md'. */\n\n");
5128 fprintf (outf
, "#include \"config.h\"\n");
5129 fprintf (outf
, "#include \"system.h\"\n");
5130 fprintf (outf
, "#include \"coretypes.h\"\n");
5131 fprintf (outf
, "#include \"backend.h\"\n");
5132 fprintf (outf
, "#include \"predict.h\"\n");
5133 fprintf (outf
, "#include \"tree.h\"\n");
5134 fprintf (outf
, "#include \"rtl.h\"\n");
5135 fprintf (outf
, "#include \"alias.h\"\n");
5136 fprintf (outf
, "#include \"options.h\"\n");
5137 fprintf (outf
, "#include \"varasm.h\"\n");
5138 fprintf (outf
, "#include \"stor-layout.h\"\n");
5139 fprintf (outf
, "#include \"calls.h\"\n");
5140 fprintf (outf
, "#include \"insn-attr.h\"\n");
5141 fprintf (outf
, "#include \"tm_p.h\"\n");
5142 fprintf (outf
, "#include \"insn-config.h\"\n");
5143 fprintf (outf
, "#include \"recog.h\"\n");
5144 fprintf (outf
, "#include \"regs.h\"\n");
5145 fprintf (outf
, "#include \"real.h\"\n");
5146 fprintf (outf
, "#include \"output.h\"\n");
5147 fprintf (outf
, "#include \"toplev.h\"\n");
5148 fprintf (outf
, "#include \"flags.h\"\n");
5149 fprintf (outf
, "#include \"emit-rtl.h\"\n");
5150 fprintf (outf
, "\n");
5151 fprintf (outf
, "#define operands recog_data.operand\n\n");
5155 open_outfile (const char *file_name
)
5158 outf
= fopen (file_name
, "w");
5160 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5161 write_header (outf
);
5166 handle_arg (const char *arg
)
5171 attr_file_name
= &arg
[2];
5174 dfa_file_name
= &arg
[2];
5177 latency_file_name
= &arg
[2];
5185 main (int argc
, char **argv
)
5187 struct attr_desc
*attr
;
5188 struct insn_def
*id
;
5191 progname
= "genattrtab";
5193 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5194 return FATAL_EXIT_CODE
;
5196 attr_file
= open_outfile (attr_file_name
);
5197 dfa_file
= open_outfile (dfa_file_name
);
5198 latency_file
= open_outfile (latency_file_name
);
5200 obstack_init (hash_obstack
);
5201 obstack_init (temp_obstack
);
5203 /* Set up true and false rtx's */
5204 true_rtx
= rtx_alloc (CONST_INT
);
5205 XWINT (true_rtx
, 0) = 1;
5206 false_rtx
= rtx_alloc (CONST_INT
);
5207 XWINT (false_rtx
, 0) = 0;
5208 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5209 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5211 alternative_name
= DEF_ATTR_STRING ("alternative");
5212 length_str
= DEF_ATTR_STRING ("length");
5213 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5214 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5215 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5217 /* Read the machine description. */
5220 while (read_md_rtx (&info
))
5222 switch (GET_CODE (info
.def
))
5225 case DEFINE_PEEPHOLE
:
5226 case DEFINE_ASM_ATTRIBUTES
:
5231 case DEFINE_ENUM_ATTR
:
5239 case DEFINE_INSN_RESERVATION
:
5240 gen_insn_reserv (&info
);
5250 if (GET_CODE (info
.def
) != DEFINE_ASM_ATTRIBUTES
)
5251 insn_index_number
++;
5255 return FATAL_EXIT_CODE
;
5257 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5258 if (! got_define_asm_attributes
)
5261 info
.def
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5262 XVEC (info
.def
, 0) = rtvec_alloc (0);
5263 info
.loc
= file_location ("<internal>", 0);
5268 /* Expand DEFINE_DELAY information into new attribute. */
5271 /* Make `insn_alternatives'. */
5272 int num_insn_codes
= get_num_insn_codes ();
5273 insn_alternatives
= oballocvec (uint64_t, num_insn_codes
);
5274 for (id
= defs
; id
; id
= id
->next
)
5275 if (id
->insn_code
>= 0)
5276 insn_alternatives
[id
->insn_code
]
5277 = (((uint64_t) 1) << id
->num_alternatives
) - 1;
5279 /* Make `insn_n_alternatives'. */
5280 insn_n_alternatives
= oballocvec (int, num_insn_codes
);
5281 for (id
= defs
; id
; id
= id
->next
)
5282 if (id
->insn_code
>= 0)
5283 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5285 /* Construct extra attributes for automata. */
5286 make_automaton_attrs ();
5288 /* Prepare to write out attribute subroutines by checking everything stored
5289 away and building the attribute cases. */
5293 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5294 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5295 attr
->default_val
->value
5296 = check_attr_value (attr
->loc
, attr
->default_val
->value
, attr
);
5299 return FATAL_EXIT_CODE
;
5301 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5302 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5305 /* Construct extra attributes for `length'. */
5306 make_length_attrs ();
5308 /* Perform any possible optimizations to speed up compilation. */
5309 optimize_attrs (num_insn_codes
);
5311 /* Now write out all the `gen_attr_...' routines. Do these before the
5312 special routines so that they get defined before they are used. */
5314 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5315 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5319 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5320 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5322 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5323 outf
= latency_file
;
5326 #undef IS_ATTR_GROUP
5328 if (! attr
->is_special
&& ! attr
->is_const
)
5329 write_attr_get (outf
, attr
);
5332 /* Write out delay eligibility information, if DEFINE_DELAY present.
5333 (The function to compute the number of delay slots will be written
5335 write_eligible_delay (attr_file
, "delay");
5336 if (have_annul_true
)
5337 write_eligible_delay (attr_file
, "annul_true");
5339 write_dummy_eligible_delay (attr_file
, "annul_true");
5340 if (have_annul_false
)
5341 write_eligible_delay (attr_file
, "annul_false");
5343 write_dummy_eligible_delay (attr_file
, "annul_false");
5345 /* Write out constant delay slot info. */
5346 write_const_num_delay_slots (attr_file
);
5348 write_length_unit_log (attr_file
);
5350 if (fclose (attr_file
) != 0)
5351 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5352 if (fclose (dfa_file
) != 0)
5353 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5354 if (fclose (latency_file
) != 0)
5355 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5357 return SUCCESS_EXIT_CODE
;