1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991-2015 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 for an attribute, ensure it is validly formed.
733 IS_CONST indicates whether the expression is constant for each compiler
734 run (a constant expression may not test any particular insn).
736 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
737 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
738 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
740 Update the string address in EQ_ATTR expression to be the same used
741 in the attribute (or `alternative_name') to speed up subsequent
742 `find_attr' calls and eliminate most `strcmp' calls.
744 Return the new expression, if any. */
747 check_attr_test (rtx exp
, int is_const
, file_location loc
)
749 struct attr_desc
*attr
;
750 struct attr_value
*av
;
751 const char *name_ptr
, *p
;
754 switch (GET_CODE (exp
))
757 /* Handle negation test. */
758 if (XSTR (exp
, 1)[0] == '!')
759 return check_attr_test (attr_rtx (NOT
,
760 attr_eq (XSTR (exp
, 0),
764 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
766 attr
= find_attr (&XSTR (exp
, 0), 0);
769 if (! strcmp (XSTR (exp
, 0), "alternative"))
770 return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
772 fatal_at (loc
, "unknown attribute `%s' in EQ_ATTR",
776 if (is_const
&& ! attr
->is_const
)
777 fatal_at (loc
, "constant expression uses insn attribute `%s'"
778 " in EQ_ATTR", XSTR (exp
, 0));
780 /* Copy this just to make it permanent,
781 so expressions using it can be permanent too. */
782 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
784 /* It shouldn't be possible to simplify the value given to a
785 constant attribute, so don't expand this until it's time to
786 write the test expression. */
788 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
790 if (attr
->is_numeric
)
792 for (p
= XSTR (exp
, 1); *p
; p
++)
794 fatal_at (loc
, "attribute `%s' takes only numeric values",
799 for (av
= attr
->first_value
; av
; av
= av
->next
)
800 if (GET_CODE (av
->value
) == CONST_STRING
801 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
805 fatal_at (loc
, "unknown value `%s' for `%s' attribute",
806 XSTR (exp
, 1), XSTR (exp
, 0));
811 if (! strcmp (XSTR (exp
, 0), "alternative"))
815 name_ptr
= XSTR (exp
, 1);
816 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
817 set
|= ((uint64_t) 1) << atoi (p
);
819 return mk_attr_alt (set
);
823 /* Make an IOR tree of the possible values. */
825 name_ptr
= XSTR (exp
, 1);
826 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
828 newexp
= attr_eq (XSTR (exp
, 0), p
);
829 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
832 return check_attr_test (orexp
, is_const
, loc
);
841 /* Either TRUE or FALSE. */
849 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, loc
);
850 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, loc
);
854 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, loc
);
858 exp
= attr_rtx (MATCH_TEST
, XSTR (exp
, 0));
859 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
864 fatal_at (loc
, "RTL operator \"%s\" not valid in constant attribute"
865 " test", 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
, "RTL operator \"%s\" not valid in attribute test",
893 GET_RTX_NAME (GET_CODE (exp
)));
899 /* Given an expression, ensure that it is validly formed and that all named
900 attribute values are valid for the given attribute. Issue a fatal error
903 Return a perhaps modified replacement expression for the value. */
906 check_attr_value (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 for numeric attribute %s",
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 (attr
->loc
, "unknown value `%s' for `%s' attribute",
957 XSTR (exp
, 0), attr
->name
);
961 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), attr
->is_const
,
963 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
964 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
972 if (!attr
->is_numeric
)
974 error_at (attr
->loc
, "invalid operation `%s' for non-numeric"
975 " attribute value", GET_RTX_NAME (GET_CODE (exp
)));
982 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
983 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
992 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
996 if (XVECLEN (exp
, 0) % 2 != 0)
998 error_at (attr
->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 (XVECEXP (exp
, 0, i
),
1005 attr
->is_const
, attr
->loc
);
1006 XVECEXP (exp
, 0, i
+ 1)
1007 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1010 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1015 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1017 error_at (attr
->loc
, "unknown attribute `%s' in ATTR",
1019 else if (attr
->is_const
&& ! attr2
->is_const
)
1020 error_at (attr
->loc
,
1021 "non-constant attribute `%s' referenced from `%s'",
1022 XSTR (exp
, 0), attr
->name
);
1023 else if (attr
->is_numeric
!= attr2
->is_numeric
)
1024 error_at (attr
->loc
,
1025 "numeric attribute mismatch calling `%s' from `%s'",
1026 XSTR (exp
, 0), attr
->name
);
1031 /* A constant SYMBOL_REF is valid as a constant attribute test and
1032 is expanded later by make_canonical into a COND. In a non-constant
1033 attribute test, it is left be. */
1034 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1037 error_at (attr
->loc
, "invalid operation `%s' for attribute value",
1038 GET_RTX_NAME (GET_CODE (exp
)));
1045 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1046 It becomes a COND with each test being (eq_attr "alternative" "n") */
1049 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1051 int num_alt
= id
->num_alternatives
;
1055 if (XVECLEN (exp
, 1) != num_alt
)
1057 error_at (id
->loc
, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1058 " was %d expected %d", XVECLEN (exp
, 1), num_alt
);
1062 /* Make a COND with all tests but the last. Select the last value via the
1064 condexp
= rtx_alloc (COND
);
1065 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1067 for (i
= 0; i
< num_alt
- 1; i
++)
1070 p
= attr_numeral (i
);
1072 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1073 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1076 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1078 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1081 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1082 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1085 convert_set_attr (rtx exp
, struct insn_def
*id
)
1088 const char *name_ptr
;
1092 /* See how many alternative specified. */
1093 n
= n_comma_elts (XSTR (exp
, 1));
1095 return attr_rtx (SET
,
1096 attr_rtx (ATTR
, XSTR (exp
, 0)),
1097 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1099 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1100 XSTR (newexp
, 0) = XSTR (exp
, 0);
1101 XVEC (newexp
, 1) = rtvec_alloc (n
);
1103 /* Process each comma-separated name. */
1104 name_ptr
= XSTR (exp
, 1);
1106 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1107 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1109 return convert_set_attr_alternative (newexp
, id
);
1112 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1113 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1119 struct insn_def
*id
;
1120 struct attr_desc
*attr
;
1124 for (id
= defs
; id
; id
= id
->next
)
1126 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1129 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1131 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1132 switch (GET_CODE (value
))
1135 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1137 error_at (id
->loc
, "bad attribute set");
1142 case SET_ATTR_ALTERNATIVE
:
1143 value
= convert_set_attr_alternative (value
, id
);
1147 value
= convert_set_attr (value
, id
);
1151 error_at (id
->loc
, "invalid attribute code %s",
1152 GET_RTX_NAME (GET_CODE (value
)));
1155 if (value
== NULL_RTX
)
1158 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1160 error_at (id
->loc
, "unknown attribute %s",
1161 XSTR (XEXP (value
, 0), 0));
1165 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1166 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1171 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1172 expressions by converting them into a COND. This removes cases from this
1173 program. Also, replace an attribute value of "*" with the default attribute
1174 value. LOC is the location to use for error reporting. */
1177 make_canonical (file_location loc
, struct attr_desc
*attr
, rtx exp
)
1182 switch (GET_CODE (exp
))
1185 exp
= make_numeric_value (INTVAL (exp
));
1189 if (! strcmp (XSTR (exp
, 0), "*"))
1191 if (attr
->default_val
== 0)
1192 fatal_at (loc
, "(attr_value \"*\") used in invalid context");
1193 exp
= attr
->default_val
->value
;
1196 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1201 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1203 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1204 This makes the COND something that won't be considered an arbitrary
1205 expression by walk_attr_value. */
1206 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1207 exp
= check_attr_value (exp
, attr
);
1211 newexp
= rtx_alloc (COND
);
1212 XVEC (newexp
, 0) = rtvec_alloc (2);
1213 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1214 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1216 XEXP (newexp
, 1) = XEXP (exp
, 2);
1219 /* Fall through to COND case since this is now a COND. */
1226 /* First, check for degenerate COND. */
1227 if (XVECLEN (exp
, 0) == 0)
1228 return make_canonical (loc
, attr
, XEXP (exp
, 1));
1229 defval
= XEXP (exp
, 1) = make_canonical (loc
, attr
, XEXP (exp
, 1));
1231 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1233 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1234 XVECEXP (exp
, 0, i
+ 1)
1235 = make_canonical (loc
, attr
, XVECEXP (exp
, 0, i
+ 1));
1236 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1252 copy_boolean (rtx exp
)
1254 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1255 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1256 copy_boolean (XEXP (exp
, 1)));
1257 if (GET_CODE (exp
) == MATCH_OPERAND
)
1259 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1260 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1262 else if (GET_CODE (exp
) == EQ_ATTR
)
1264 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1265 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1271 /* Given a value and an attribute description, return a `struct attr_value *'
1272 that represents that value. This is either an existing structure, if the
1273 value has been previously encountered, or a newly-created structure.
1275 `insn_code' is the code of an insn whose attribute has the specified
1276 value (-2 if not processing an insn). We ensure that all insns for
1277 a given value have the same number of alternatives if the value checks
1278 alternatives. LOC is the location to use for error reporting. */
1280 static struct attr_value
*
1281 get_attr_value (file_location loc
, rtx value
, struct attr_desc
*attr
,
1284 struct attr_value
*av
;
1285 uint64_t num_alt
= 0;
1287 value
= make_canonical (loc
, attr
, value
);
1288 if (compares_alternatives_p (value
))
1290 if (insn_code
< 0 || insn_alternatives
== NULL
)
1291 fatal_at (loc
, "(eq_attr \"alternatives\" ...) used in non-insn"
1294 num_alt
= insn_alternatives
[insn_code
];
1297 for (av
= attr
->first_value
; av
; av
= av
->next
)
1298 if (rtx_equal_p (value
, av
->value
)
1299 && (num_alt
== 0 || av
->first_insn
== NULL
1300 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1303 av
= oballoc (struct attr_value
);
1305 av
->next
= attr
->first_value
;
1306 attr
->first_value
= av
;
1307 av
->first_insn
= NULL
;
1309 av
->has_asm_insn
= 0;
1314 /* After all DEFINE_DELAYs have been read in, create internal attributes
1315 to generate the required routines.
1317 First, we compute the number of delay slots for each insn (as a COND of
1318 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1319 delay type is specified, we compute a similar function giving the
1320 DEFINE_DELAY ordinal for each insn.
1322 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1323 tells whether a given insn can be in that delay slot.
1325 Normal attribute filling and optimization expands these to contain the
1326 information needed to handle delay slots. */
1329 expand_delays (void)
1331 struct delay_desc
*delay
;
1337 /* First, generate data for `num_delay_slots' function. */
1339 condexp
= rtx_alloc (COND
);
1340 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1341 XEXP (condexp
, 1) = make_numeric_value (0);
1343 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1345 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1346 XVECEXP (condexp
, 0, i
+ 1)
1347 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1350 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1352 /* If more than one delay type, do the same for computing the delay type. */
1355 condexp
= rtx_alloc (COND
);
1356 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1357 XEXP (condexp
, 1) = make_numeric_value (0);
1359 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1361 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1362 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1365 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1368 /* For each delay possibility and delay slot, compute an eligibility
1369 attribute for non-annulled insns and for each type of annulled (annul
1370 if true and annul if false). */
1371 for (delay
= delays
; delay
; delay
= delay
->next
)
1373 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1375 condexp
= XVECEXP (delay
->def
, 1, i
);
1377 condexp
= false_rtx
;
1378 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1379 make_numeric_value (1), make_numeric_value (0));
1381 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1382 "*delay_%d_%d", delay
->num
, i
/ 3);
1383 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1385 if (have_annul_true
)
1387 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1388 if (condexp
== 0) condexp
= false_rtx
;
1389 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1390 make_numeric_value (1),
1391 make_numeric_value (0));
1392 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1393 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1394 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1397 if (have_annul_false
)
1399 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1400 if (condexp
== 0) condexp
= false_rtx
;
1401 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1402 make_numeric_value (1),
1403 make_numeric_value (0));
1404 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1405 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1406 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1412 /* Once all attributes and insns have been read and checked, we construct for
1413 each attribute value a list of all the insns that have that value for
1417 fill_attr (struct attr_desc
*attr
)
1419 struct attr_value
*av
;
1420 struct insn_ent
*ie
;
1421 struct insn_def
*id
;
1425 /* Don't fill constant attributes. The value is independent of
1426 any particular insn. */
1430 for (id
= defs
; id
; id
= id
->next
)
1432 /* If no value is specified for this insn for this attribute, use the
1435 if (XVEC (id
->def
, id
->vec_idx
))
1436 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1437 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1439 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1442 av
= attr
->default_val
;
1444 av
= get_attr_value (id
->loc
, value
, attr
, id
->insn_code
);
1446 ie
= oballoc (struct insn_ent
);
1448 insert_insn_ent (av
, ie
);
1452 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1453 test that checks relative positions of insns (uses MATCH_DUP or PC).
1454 If so, replace it with what is obtained by passing the expression to
1455 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1456 recursively on each value (including the default value). Otherwise,
1457 return the value returned by NO_ADDRESS_FN applied to EXP. */
1460 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1461 rtx (*address_fn
) (rtx
))
1466 if (GET_CODE (exp
) == COND
)
1468 /* See if any tests use addresses. */
1470 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1471 walk_attr_value (XVECEXP (exp
, 0, i
));
1474 return (*address_fn
) (exp
);
1476 /* Make a new copy of this COND, replacing each element. */
1477 newexp
= rtx_alloc (COND
);
1478 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1479 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1481 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1482 XVECEXP (newexp
, 0, i
+ 1)
1483 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1484 no_address_fn
, address_fn
);
1487 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1488 no_address_fn
, address_fn
);
1493 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1496 walk_attr_value (XEXP (exp
, 0));
1498 return (*address_fn
) (exp
);
1500 return attr_rtx (IF_THEN_ELSE
,
1501 substitute_address (XEXP (exp
, 0),
1502 no_address_fn
, address_fn
),
1503 substitute_address (XEXP (exp
, 1),
1504 no_address_fn
, address_fn
),
1505 substitute_address (XEXP (exp
, 2),
1506 no_address_fn
, address_fn
));
1509 return (*no_address_fn
) (exp
);
1512 /* Make new attributes from the `length' attribute. The following are made,
1513 each corresponding to a function called from `shorten_branches' or
1516 *insn_default_length This is the length of the insn to be returned
1517 by `get_attr_length' before `shorten_branches'
1518 has been called. In each case where the length
1519 depends on relative addresses, the largest
1520 possible is used. This routine is also used
1521 to compute the initial size of the insn.
1523 *insn_variable_length_p This returns 1 if the insn's length depends
1524 on relative addresses, zero otherwise.
1526 *insn_current_length This is only called when it is known that the
1527 insn has a variable length and returns the
1528 current length, based on relative addresses.
1532 make_length_attrs (void)
1534 static const char *new_names
[] =
1536 "*insn_default_length",
1538 "*insn_variable_length_p",
1539 "*insn_current_length"
1541 static rtx (*const no_address_fn
[]) (rtx
)
1542 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1543 static rtx (*const address_fn
[]) (rtx
)
1544 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1546 struct attr_desc
*length_attr
, *new_attr
;
1547 struct attr_value
*av
, *new_av
;
1548 struct insn_ent
*ie
, *new_ie
;
1550 /* See if length attribute is defined. If so, it must be numeric. Make
1551 it special so we don't output anything for it. */
1552 length_attr
= find_attr (&length_str
, 0);
1553 if (length_attr
== 0)
1556 if (! length_attr
->is_numeric
)
1557 fatal_at (length_attr
->loc
, "length attribute must be numeric");
1559 length_attr
->is_const
= 0;
1560 length_attr
->is_special
= 1;
1562 /* Make each new attribute, in turn. */
1563 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1565 make_internal_attr (new_names
[i
],
1566 substitute_address (length_attr
->default_val
->value
,
1567 no_address_fn
[i
], address_fn
[i
]),
1569 new_attr
= find_attr (&new_names
[i
], 0);
1570 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1571 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1573 new_av
= get_attr_value (ie
->def
->loc
,
1574 substitute_address (av
->value
,
1577 new_attr
, ie
->def
->insn_code
);
1578 new_ie
= oballoc (struct insn_ent
);
1579 new_ie
->def
= ie
->def
;
1580 insert_insn_ent (new_av
, new_ie
);
1585 /* Utility functions called from above routine. */
1588 identity_fn (rtx exp
)
1594 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1596 return make_numeric_value (0);
1600 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1602 return make_numeric_value (1);
1609 return make_numeric_value (max_attr_value (exp
, &unknown
));
1616 return make_numeric_value (min_attr_value (exp
, &unknown
));
1620 write_length_unit_log (FILE *outf
)
1622 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1623 struct attr_value
*av
;
1624 struct insn_ent
*ie
;
1625 unsigned int length_unit_log
, length_or
;
1630 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1631 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1632 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1633 length_or
|= or_attr_value (av
->value
, &unknown
);
1636 if (length_attr
== NULL
|| unknown
)
1637 length_unit_log
= 0;
1640 length_or
= ~length_or
;
1641 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1644 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1647 /* Compute approximate cost of the expression. Used to decide whether
1648 expression is cheap enough for inline. */
1650 attr_rtx_cost (rtx x
)
1656 code
= GET_CODE (x
);
1669 /* Alternatives don't result into function call. */
1670 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1677 const char *fmt
= GET_RTX_FORMAT (code
);
1678 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1684 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1685 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1688 cost
+= attr_rtx_cost (XEXP (x
, i
));
1698 /* Take a COND expression and see if any of the conditions in it can be
1699 simplified. If any are known true or known false for the particular insn
1700 code, the COND can be further simplified.
1702 Also call ourselves on any COND operations that are values of this COND.
1704 We do not modify EXP; rather, we make and return a new rtx. */
1707 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1710 /* We store the desired contents here,
1711 then build a new expression if they don't match EXP. */
1712 rtx defval
= XEXP (exp
, 1);
1713 rtx new_defval
= XEXP (exp
, 1);
1714 int len
= XVECLEN (exp
, 0);
1715 rtx
*tests
= XNEWVEC (rtx
, len
);
1719 /* This lets us free all storage allocated below, if appropriate. */
1720 obstack_finish (rtl_obstack
);
1722 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1724 /* See if default value needs simplification. */
1725 if (GET_CODE (defval
) == COND
)
1726 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1728 /* Simplify the subexpressions, and see what tests we can get rid of. */
1730 for (i
= 0; i
< len
; i
+= 2)
1732 rtx newtest
, newval
;
1734 /* Simplify this test. */
1735 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1738 newval
= tests
[i
+ 1];
1739 /* See if this value may need simplification. */
1740 if (GET_CODE (newval
) == COND
)
1741 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1743 /* Look for ways to delete or combine this test. */
1744 if (newtest
== true_rtx
)
1746 /* If test is true, make this value the default
1747 and discard this + any following tests. */
1749 defval
= tests
[i
+ 1];
1750 new_defval
= newval
;
1753 else if (newtest
== false_rtx
)
1755 /* If test is false, discard it and its value. */
1756 for (j
= i
; j
< len
- 2; j
++)
1757 tests
[j
] = tests
[j
+ 2];
1762 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1764 /* If this value and the value for the prev test are the same,
1768 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1769 insn_code
, insn_index
);
1771 /* Delete this test/value. */
1772 for (j
= i
; j
< len
- 2; j
++)
1773 tests
[j
] = tests
[j
+ 2];
1779 tests
[i
+ 1] = newval
;
1782 /* If the last test in a COND has the same value
1783 as the default value, that test isn't needed. */
1785 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1788 /* See if we changed anything. */
1789 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1792 for (i
= 0; i
< len
; i
++)
1793 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1801 if (GET_CODE (defval
) == COND
)
1802 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1810 rtx newexp
= rtx_alloc (COND
);
1812 XVEC (newexp
, 0) = rtvec_alloc (len
);
1813 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1814 XEXP (newexp
, 1) = new_defval
;
1821 /* Remove an insn entry from an attribute value. */
1824 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1826 struct insn_ent
*previe
;
1828 if (av
->first_insn
== ie
)
1829 av
->first_insn
= ie
->next
;
1832 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1834 previe
->next
= ie
->next
;
1838 if (ie
->def
->insn_code
== -1)
1839 av
->has_asm_insn
= 0;
1844 /* Insert an insn entry in an attribute value list. */
1847 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1849 ie
->next
= av
->first_insn
;
1850 av
->first_insn
= ie
;
1852 if (ie
->def
->insn_code
== -1)
1853 av
->has_asm_insn
= 1;
1858 /* This is a utility routine to take an expression that is a tree of either
1859 AND or IOR expressions and insert a new term. The new term will be
1860 inserted at the right side of the first node whose code does not match
1861 the root. A new node will be created with the root's code. Its left
1862 side will be the old right side and its right side will be the new
1865 If the `term' is itself a tree, all its leaves will be inserted. */
1868 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1872 /* Avoid consing in some special cases. */
1873 if (code
== AND
&& term
== true_rtx
)
1875 if (code
== AND
&& term
== false_rtx
)
1877 if (code
== AND
&& exp
== true_rtx
)
1879 if (code
== AND
&& exp
== false_rtx
)
1881 if (code
== IOR
&& term
== true_rtx
)
1883 if (code
== IOR
&& term
== false_rtx
)
1885 if (code
== IOR
&& exp
== true_rtx
)
1887 if (code
== IOR
&& exp
== false_rtx
)
1889 if (attr_equal_p (exp
, term
))
1892 if (GET_CODE (term
) == code
)
1894 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1895 insn_code
, insn_index
);
1896 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1897 insn_code
, insn_index
);
1902 if (GET_CODE (exp
) == code
)
1904 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1905 term
, insn_code
, insn_index
);
1906 if (new_rtx
!= XEXP (exp
, 1))
1907 /* Make a copy of this expression and call recursively. */
1908 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1914 /* Insert the new term. */
1915 newexp
= attr_rtx (code
, exp
, term
);
1918 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1921 /* If we have an expression which AND's a bunch of
1922 (not (eq_attrq "alternative" "n"))
1923 terms, we may have covered all or all but one of the possible alternatives.
1924 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1926 This routine is passed an expression and either AND or IOR. It returns a
1927 bitmask indicating which alternatives are mentioned within EXP. */
1930 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1933 if (GET_CODE (exp
) == code
)
1934 return compute_alternative_mask (XEXP (exp
, 0), code
)
1935 | compute_alternative_mask (XEXP (exp
, 1), code
);
1937 else if (code
== AND
&& GET_CODE (exp
) == NOT
1938 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1939 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1940 string
= XSTR (XEXP (exp
, 0), 1);
1942 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1943 && XSTR (exp
, 0) == alternative_name
)
1944 string
= XSTR (exp
, 1);
1946 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1948 if (code
== AND
&& XINT (exp
, 1))
1949 return XINT (exp
, 0);
1951 if (code
== IOR
&& !XINT (exp
, 1))
1952 return XINT (exp
, 0);
1960 return ((uint64_t) 1) << (string
[0] - '0');
1961 return ((uint64_t) 1) << atoi (string
);
1964 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1965 attribute with the value represented by that bit. */
1968 make_alternative_compare (uint64_t mask
)
1970 return mk_attr_alt (mask
);
1973 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1974 of "attr" for this insn code. From that value, we can compute a test
1975 showing when the EQ_ATTR will be true. This routine performs that
1976 computation. If a test condition involves an address, we leave the EQ_ATTR
1977 intact because addresses are only valid for the `length' attribute.
1979 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1980 it refers. VALUE is the value of that attribute for the insn
1981 corresponding to INSN_CODE and INSN_INDEX. */
1984 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1985 int insn_code
, int insn_index
)
1992 while (GET_CODE (value
) == ATTR
)
1994 struct attr_value
*av
= NULL
;
1996 attr
= find_attr (&XSTR (value
, 0), 0);
1998 if (insn_code_values
)
2000 struct attr_value_list
*iv
;
2001 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2002 if (iv
->attr
== attr
)
2010 struct insn_ent
*ie
;
2011 for (av
= attr
->first_value
; av
; av
= av
->next
)
2012 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2013 if (ie
->def
->insn_code
== insn_code
)
2023 switch (GET_CODE (value
))
2026 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2037 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2038 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
2039 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
2040 for (p
= string
; *p
; p
++)
2043 newexp
= attr_rtx (EQ
, value
,
2044 attr_rtx (SYMBOL_REF
,
2045 DEF_ATTR_STRING (string
)));
2050 /* We construct an IOR of all the cases for which the
2051 requested attribute value is present. Since we start with
2052 FALSE, if it is not present, FALSE will be returned.
2054 Each case is the AND of the NOT's of the previous conditions with the
2055 current condition; in the default case the current condition is TRUE.
2057 For each possible COND value, call ourselves recursively.
2059 The extra TRUE and FALSE expressions will be eliminated by another
2060 call to the simplification routine. */
2065 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2067 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2068 insn_code
, insn_index
);
2070 right
= insert_right_side (AND
, andexp
, this_cond
,
2071 insn_code
, insn_index
);
2072 right
= insert_right_side (AND
, right
,
2073 evaluate_eq_attr (exp
, attr
,
2076 insn_code
, insn_index
),
2077 insn_code
, insn_index
);
2078 orexp
= insert_right_side (IOR
, orexp
, right
,
2079 insn_code
, insn_index
);
2081 /* Add this condition into the AND expression. */
2082 newexp
= attr_rtx (NOT
, this_cond
);
2083 andexp
= insert_right_side (AND
, andexp
, newexp
,
2084 insn_code
, insn_index
);
2087 /* Handle the default case. */
2088 right
= insert_right_side (AND
, andexp
,
2089 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2090 insn_code
, insn_index
),
2091 insn_code
, insn_index
);
2092 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2099 /* If uses an address, must return original expression. But set the
2100 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2103 walk_attr_value (newexp
);
2107 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2108 return copy_rtx_unchanging (exp
);
2115 /* This routine is called when an AND of a term with a tree of AND's is
2116 encountered. If the term or its complement is present in the tree, it
2117 can be replaced with TRUE or FALSE, respectively.
2119 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2120 be true and hence are complementary.
2122 There is one special case: If we see
2123 (and (not (eq_attr "att" "v1"))
2124 (eq_attr "att" "v2"))
2125 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2126 replace the term, not anything in the AND tree. So we pass a pointer to
2130 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2135 int left_eliminates_term
, right_eliminates_term
;
2137 if (GET_CODE (exp
) == AND
)
2139 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2140 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2141 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2143 newexp
= attr_rtx (AND
, left
, right
);
2145 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2149 else if (GET_CODE (exp
) == IOR
)
2151 /* For the IOR case, we do the same as above, except that we can
2152 only eliminate `term' if both sides of the IOR would do so. */
2154 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2155 left_eliminates_term
= (temp
== true_rtx
);
2158 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2159 right_eliminates_term
= (temp
== true_rtx
);
2161 if (left_eliminates_term
&& right_eliminates_term
)
2164 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2166 newexp
= attr_rtx (IOR
, left
, right
);
2168 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2172 /* Check for simplifications. Do some extra checking here since this
2173 routine is called so many times. */
2178 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2181 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2184 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2186 if (attr_alt_subset_p (*pterm
, exp
))
2189 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2192 if (attr_alt_subset_p (exp
, *pterm
))
2198 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2200 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2203 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2209 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2210 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2212 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2215 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2221 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2222 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2224 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2227 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2233 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2235 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2239 else if (GET_CODE (exp
) == NOT
)
2241 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2245 else if (GET_CODE (*pterm
) == NOT
)
2247 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2251 else if (attr_equal_p (exp
, *pterm
))
2257 /* Similar to `simplify_and_tree', but for IOR trees. */
2260 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2265 int left_eliminates_term
, right_eliminates_term
;
2267 if (GET_CODE (exp
) == IOR
)
2269 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2270 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2271 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2273 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2275 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2279 else if (GET_CODE (exp
) == AND
)
2281 /* For the AND case, we do the same as above, except that we can
2282 only eliminate `term' if both sides of the AND would do so. */
2284 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2285 left_eliminates_term
= (temp
== false_rtx
);
2288 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2289 right_eliminates_term
= (temp
== false_rtx
);
2291 if (left_eliminates_term
&& right_eliminates_term
)
2294 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2296 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2298 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2302 if (attr_equal_p (exp
, *pterm
))
2305 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2308 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2311 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2312 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2313 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2316 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2317 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2318 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2324 /* Simplify test expression and use temporary obstack in order to avoid
2325 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2326 and avoid unnecessary copying if possible. */
2329 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2332 struct obstack
*old
;
2333 if (ATTR_IND_SIMPLIFIED_P (exp
))
2336 rtl_obstack
= temp_obstack
;
2337 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2339 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2341 return attr_copy_rtx (x
);
2344 /* Returns true if S1 is a subset of S2. */
2347 attr_alt_subset_p (rtx s1
, rtx s2
)
2349 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2352 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2355 return !(XINT (s1
, 0) & XINT (s2
, 0));
2361 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2368 /* Returns true if S1 is a subset of complement of S2. */
2371 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2373 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2376 return !(XINT (s1
, 0) & XINT (s2
, 0));
2379 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2382 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2392 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2395 attr_alt_intersection (rtx s1
, rtx s2
)
2397 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2399 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2402 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2405 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2408 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2411 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2416 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2421 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2424 attr_alt_union (rtx s1
, rtx s2
)
2426 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2428 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2431 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2434 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2437 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2440 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2446 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2450 /* Return EQ_ATTR_ALT expression representing complement of S. */
2453 attr_alt_complement (rtx s
)
2455 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2457 XINT (result
, 0) = XINT (s
, 0);
2458 XINT (result
, 1) = 1 - XINT (s
, 1);
2463 /* Return EQ_ATTR_ALT expression representing set containing elements set
2467 mk_attr_alt (uint64_t e
)
2469 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2471 XINT (result
, 0) = e
;
2472 XINT (result
, 1) = 0;
2477 /* Given an expression, see if it can be simplified for a particular insn
2478 code based on the values of other attributes being tested. This can
2479 eliminate nested get_attr_... calls.
2481 Note that if an endless recursion is specified in the patterns, the
2482 optimization will loop. However, it will do so in precisely the cases where
2483 an infinite recursion loop could occur during compilation. It's better that
2487 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2490 struct attr_desc
*attr
;
2491 struct attr_value
*av
;
2492 struct insn_ent
*ie
;
2493 struct attr_value_list
*iv
;
2496 bool left_alt
, right_alt
;
2498 /* Don't re-simplify something we already simplified. */
2499 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2502 switch (GET_CODE (exp
))
2505 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2506 if (left
== false_rtx
)
2508 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2509 if (right
== false_rtx
)
2512 if (GET_CODE (left
) == EQ_ATTR_ALT
2513 && GET_CODE (right
) == EQ_ATTR_ALT
)
2515 exp
= attr_alt_intersection (left
, right
);
2516 return simplify_test_exp (exp
, insn_code
, insn_index
);
2519 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2520 present on both sides, apply the distributive law since this will
2521 yield simplifications. */
2522 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2523 && compute_alternative_mask (left
, IOR
)
2524 && compute_alternative_mask (right
, IOR
))
2526 if (GET_CODE (left
) == IOR
)
2527 std::swap (left
, right
);
2529 newexp
= attr_rtx (IOR
,
2530 attr_rtx (AND
, left
, XEXP (right
, 0)),
2531 attr_rtx (AND
, left
, XEXP (right
, 1)));
2533 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2536 /* Try with the term on both sides. */
2537 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2538 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2539 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2541 if (left
== false_rtx
|| right
== false_rtx
)
2543 else if (left
== true_rtx
)
2547 else if (right
== true_rtx
)
2551 /* See if all or all but one of the insn's alternatives are specified
2552 in this tree. Optimize if so. */
2554 if (GET_CODE (left
) == NOT
)
2555 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2556 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2558 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2561 if (GET_CODE (right
) == NOT
)
2562 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2563 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2565 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2566 && XINT (right
, 1));
2569 && (GET_CODE (left
) == AND
2571 || GET_CODE (right
) == AND
2574 i
= compute_alternative_mask (exp
, AND
);
2575 if (i
& ~insn_alternatives
[insn_code
])
2576 fatal ("invalid alternative specified for pattern number %d",
2579 /* If all alternatives are excluded, this is false. */
2580 i
^= insn_alternatives
[insn_code
];
2583 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2585 /* If just one excluded, AND a comparison with that one to the
2586 front of the tree. The others will be eliminated by
2587 optimization. We do not want to do this if the insn has one
2588 alternative and we have tested none of them! */
2589 left
= make_alternative_compare (i
);
2590 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2591 newexp
= attr_rtx (AND
, left
, right
);
2593 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2597 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2599 newexp
= attr_rtx (AND
, left
, right
);
2600 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2605 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2606 if (left
== true_rtx
)
2608 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2609 if (right
== true_rtx
)
2612 if (GET_CODE (left
) == EQ_ATTR_ALT
2613 && GET_CODE (right
) == EQ_ATTR_ALT
)
2615 exp
= attr_alt_union (left
, right
);
2616 return simplify_test_exp (exp
, insn_code
, insn_index
);
2619 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2620 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2621 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2623 if (right
== true_rtx
|| left
== true_rtx
)
2625 else if (left
== false_rtx
)
2629 else if (right
== false_rtx
)
2634 /* Test for simple cases where the distributive law is useful. I.e.,
2635 convert (ior (and (x) (y))
2641 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2642 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2644 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2646 left
= XEXP (left
, 0);
2648 newexp
= attr_rtx (AND
, left
, right
);
2649 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2653 convert (ior (and (y) (x))
2655 to (and (ior (y) (z))
2657 Note that we want the common term to stay at the end.
2660 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2661 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2663 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2666 right
= XEXP (right
, 1);
2667 newexp
= attr_rtx (AND
, left
, right
);
2668 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2671 /* See if all or all but one of the insn's alternatives are specified
2672 in this tree. Optimize if so. */
2674 else if (insn_code
>= 0
2675 && (GET_CODE (left
) == IOR
2676 || (GET_CODE (left
) == EQ_ATTR_ALT
2678 || (GET_CODE (left
) == EQ_ATTR
2679 && XSTR (left
, 0) == alternative_name
)
2680 || GET_CODE (right
) == IOR
2681 || (GET_CODE (right
) == EQ_ATTR_ALT
2682 && !XINT (right
, 1))
2683 || (GET_CODE (right
) == EQ_ATTR
2684 && XSTR (right
, 0) == alternative_name
)))
2686 i
= compute_alternative_mask (exp
, IOR
);
2687 if (i
& ~insn_alternatives
[insn_code
])
2688 fatal ("invalid alternative specified for pattern number %d",
2691 /* If all alternatives are included, this is true. */
2692 i
^= insn_alternatives
[insn_code
];
2695 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2697 /* If just one excluded, IOR a comparison with that one to the
2698 front of the tree. The others will be eliminated by
2699 optimization. We do not want to do this if the insn has one
2700 alternative and we have tested none of them! */
2701 left
= make_alternative_compare (i
);
2702 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2703 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2705 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2709 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2711 newexp
= attr_rtx (IOR
, left
, right
);
2712 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2717 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2719 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2720 insn_code
, insn_index
);
2724 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2725 if (GET_CODE (left
) == NOT
)
2726 return XEXP (left
, 0);
2728 if (left
== false_rtx
)
2730 if (left
== true_rtx
)
2733 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2735 exp
= attr_alt_complement (left
);
2736 return simplify_test_exp (exp
, insn_code
, insn_index
);
2739 /* Try to apply De`Morgan's laws. */
2740 if (GET_CODE (left
) == IOR
)
2742 newexp
= attr_rtx (AND
,
2743 attr_rtx (NOT
, XEXP (left
, 0)),
2744 attr_rtx (NOT
, XEXP (left
, 1)));
2746 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2748 else if (GET_CODE (left
) == AND
)
2750 newexp
= attr_rtx (IOR
,
2751 attr_rtx (NOT
, XEXP (left
, 0)),
2752 attr_rtx (NOT
, XEXP (left
, 1)));
2754 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2756 else if (left
!= XEXP (exp
, 0))
2758 newexp
= attr_rtx (NOT
, left
);
2764 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2768 if (XSTR (exp
, 0) == alternative_name
)
2770 newexp
= mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
2774 /* Look at the value for this insn code in the specified attribute.
2775 We normally can replace this comparison with the condition that
2776 would give this insn the values being tested for. */
2778 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2783 if (insn_code_values
)
2785 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2786 if (iv
->attr
== attr
)
2794 for (av
= attr
->first_value
; av
; av
= av
->next
)
2795 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2796 if (ie
->def
->insn_code
== insn_code
)
2803 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2804 insn_code
, insn_index
);
2805 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2806 if (attr_rtx_cost (x
) < 7)
2816 /* We have already simplified this expression. Simplifying it again
2817 won't buy anything unless we weren't given a valid insn code
2818 to process (i.e., we are canonicalizing something.). */
2820 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2821 return copy_rtx_unchanging (newexp
);
2826 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2827 otherwise return 0. */
2830 tests_attr_p (rtx p
, struct attr_desc
*attr
)
2835 if (GET_CODE (p
) == EQ_ATTR
)
2837 if (XSTR (p
, 0) != attr
->name
)
2842 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2843 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2844 for (i
= 0; i
< ie
; i
++)
2849 if (tests_attr_p (XEXP (p
, i
), attr
))
2854 je
= XVECLEN (p
, i
);
2855 for (j
= 0; j
< je
; ++j
)
2856 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2865 /* Calculate a topological sorting of all attributes so that
2866 all attributes only depend on attributes in front of it.
2867 Place the result in *RET (which is a pointer to an array of
2868 attr_desc pointers), and return the size of that array. */
2871 get_attr_order (struct attr_desc
***ret
)
2875 struct attr_desc
*attr
;
2876 struct attr_desc
**all
, **sorted
;
2878 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2879 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2881 all
= XNEWVEC (struct attr_desc
*, num
);
2882 sorted
= XNEWVEC (struct attr_desc
*, num
);
2883 handled
= XCNEWVEC (char, num
);
2885 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2886 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2890 for (i
= 0; i
< num
; i
++)
2891 if (all
[i
]->is_const
)
2892 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2894 /* We have only few attributes hence we can live with the inner
2895 loop being O(n^2), unlike the normal fast variants of topological
2899 for (i
= 0; i
< num
; i
++)
2902 /* Let's see if I depends on anything interesting. */
2904 for (k
= 0; k
< num
; k
++)
2907 struct attr_value
*av
;
2908 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2909 if (av
->num_insns
!= 0)
2910 if (tests_attr_p (av
->value
, all
[k
]))
2914 /* Something in I depends on K. */
2919 /* Nothing in I depended on anything intersting, so
2922 sorted
[j
++] = all
[i
];
2928 for (j
= 0; j
< num
; j
++)
2930 struct attr_desc
*attr2
;
2931 struct attr_value
*av
;
2934 fprintf (stderr
, "%s depends on: ", attr
->name
);
2935 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2936 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2937 if (!attr2
->is_const
)
2938 for (av
= attr
->first_value
; av
; av
= av
->next
)
2939 if (av
->num_insns
!= 0)
2940 if (tests_attr_p (av
->value
, attr2
))
2942 fprintf (stderr
, "%s, ", attr2
->name
);
2945 fprintf (stderr
, "\n");
2953 /* Optimize the attribute lists by seeing if we can determine conditional
2954 values from the known values of other attributes. This will save subroutine
2955 calls during the compilation. NUM_INSN_CODES is the number of unique
2956 instruction codes. */
2959 optimize_attrs (int num_insn_codes
)
2961 struct attr_desc
*attr
;
2962 struct attr_value
*av
;
2963 struct insn_ent
*ie
;
2966 struct attr_value_list
*ivbuf
;
2967 struct attr_value_list
*iv
;
2968 struct attr_desc
**topsort
;
2971 /* For each insn code, make a list of all the insn_ent's for it,
2972 for all values for all attributes. */
2974 if (num_insn_ents
== 0)
2977 /* Make 2 extra elements, for "code" values -2 and -1. */
2978 insn_code_values
= XCNEWVEC (struct attr_value_list
*, num_insn_codes
+ 2);
2980 /* Offset the table address so we can index by -2 or -1. */
2981 insn_code_values
+= 2;
2983 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2985 /* Create the chain of insn*attr values such that we see dependend
2986 attributes after their dependencies. As we use a stack via the
2987 next pointers start from the end of the topological order. */
2988 topnum
= get_attr_order (&topsort
);
2989 for (i
= topnum
- 1; i
>= 0; i
--)
2990 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
2991 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2993 iv
->attr
= topsort
[i
];
2996 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2997 insn_code_values
[ie
->def
->insn_code
] = iv
;
3002 /* Sanity check on num_insn_ents. */
3003 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
3005 /* Process one insn code at a time. */
3006 for (i
= -2; i
< num_insn_codes
; i
++)
3008 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3009 We use it to mean "already simplified for this insn". */
3010 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3011 clear_struct_flag (iv
->av
->value
);
3013 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3015 struct obstack
*old
= rtl_obstack
;
3020 if (GET_CODE (av
->value
) != COND
)
3023 rtl_obstack
= temp_obstack
;
3025 while (GET_CODE (newexp
) == COND
)
3027 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
3028 ie
->def
->insn_index
);
3029 if (newexp2
== newexp
)
3035 /* If we created a new value for this instruction, and it's
3036 cheaper than the old value, and overall cheap, use that
3037 one as specific value for the current instruction.
3038 The last test is to avoid exploding the get_attr_ function
3039 sizes for no much gain. */
3040 if (newexp
!= av
->value
3041 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
3042 && attr_rtx_cost (newexp
) < 26
3045 newexp
= attr_copy_rtx (newexp
);
3046 remove_insn_ent (av
, ie
);
3047 av
= get_attr_value (ie
->def
->loc
, newexp
, attr
,
3048 ie
->def
->insn_code
);
3050 insert_insn_ent (av
, ie
);
3056 free (insn_code_values
- 2);
3057 insn_code_values
= NULL
;
3060 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3063 clear_struct_flag (rtx x
)
3070 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3071 if (ATTR_IND_SIMPLIFIED_P (x
))
3074 code
= GET_CODE (x
);
3093 /* Compare the elements. If any pair of corresponding elements
3094 fail to match, return 0 for the whole things. */
3096 fmt
= GET_RTX_FORMAT (code
);
3097 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3103 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3104 clear_struct_flag (XVECEXP (x
, i
, j
));
3108 clear_struct_flag (XEXP (x
, i
));
3114 /* Add attribute value NAME to the beginning of ATTR's list. */
3117 add_attr_value (struct attr_desc
*attr
, const char *name
)
3119 struct attr_value
*av
;
3121 av
= oballoc (struct attr_value
);
3122 av
->value
= attr_rtx (CONST_STRING
, name
);
3123 av
->next
= attr
->first_value
;
3124 attr
->first_value
= av
;
3125 av
->first_insn
= NULL
;
3127 av
->has_asm_insn
= 0;
3130 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3133 gen_attr (md_rtx_info
*info
)
3135 struct enum_type
*et
;
3136 struct enum_value
*ev
;
3137 struct attr_desc
*attr
;
3138 const char *name_ptr
;
3140 rtx def
= info
->def
;
3142 /* Make a new attribute structure. Check for duplicate by looking at
3143 attr->default_val, since it is initialized by this routine. */
3144 attr
= find_attr (&XSTR (def
, 0), 1);
3145 if (attr
->default_val
)
3147 error_at (info
->loc
, "duplicate definition for attribute %s",
3149 message_at (attr
->loc
, "previous definition");
3152 attr
->loc
= info
->loc
;
3154 if (GET_CODE (def
) == DEFINE_ENUM_ATTR
)
3156 attr
->enum_name
= XSTR (def
, 1);
3157 et
= lookup_enum_type (XSTR (def
, 1));
3158 if (!et
|| !et
->md_p
)
3159 error_at (info
->loc
, "No define_enum called `%s' defined",
3162 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3163 add_attr_value (attr
, ev
->name
);
3165 else if (*XSTR (def
, 1) == '\0')
3166 attr
->is_numeric
= 1;
3169 name_ptr
= XSTR (def
, 1);
3170 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3171 add_attr_value (attr
, p
);
3174 if (GET_CODE (XEXP (def
, 2)) == CONST
)
3177 if (attr
->is_numeric
)
3178 error_at (info
->loc
,
3179 "constant attributes may not take numeric values");
3181 /* Get rid of the CONST node. It is allowed only at top-level. */
3182 XEXP (def
, 2) = XEXP (XEXP (def
, 2), 0);
3185 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3186 error_at (info
->loc
, "`length' attribute must take numeric values");
3188 /* Set up the default value. */
3189 XEXP (def
, 2) = check_attr_value (XEXP (def
, 2), attr
);
3190 attr
->default_val
= get_attr_value (info
->loc
, XEXP (def
, 2), attr
, -2);
3193 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3194 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3195 number of alternatives as this should be checked elsewhere. */
3198 count_alternatives (rtx exp
)
3203 if (GET_CODE (exp
) == MATCH_OPERAND
)
3204 return n_comma_elts (XSTR (exp
, 2));
3206 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3207 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3212 n
= count_alternatives (XEXP (exp
, i
));
3219 if (XVEC (exp
, i
) != NULL
)
3220 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3222 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3231 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3232 `alternative' attribute. */
3235 compares_alternatives_p (rtx exp
)
3240 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3243 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3244 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3249 if (compares_alternatives_p (XEXP (exp
, i
)))
3254 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3255 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3263 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3266 gen_insn (md_rtx_info
*info
)
3268 struct insn_def
*id
;
3269 rtx def
= info
->def
;
3271 id
= oballoc (struct insn_def
);
3275 id
->loc
= info
->loc
;
3277 switch (GET_CODE (def
))
3280 id
->insn_code
= info
->index
;
3281 id
->insn_index
= insn_index_number
;
3282 id
->num_alternatives
= count_alternatives (def
);
3283 if (id
->num_alternatives
== 0)
3284 id
->num_alternatives
= 1;
3288 case DEFINE_PEEPHOLE
:
3289 id
->insn_code
= info
->index
;
3290 id
->insn_index
= insn_index_number
;
3291 id
->num_alternatives
= count_alternatives (def
);
3292 if (id
->num_alternatives
== 0)
3293 id
->num_alternatives
= 1;
3297 case DEFINE_ASM_ATTRIBUTES
:
3299 id
->insn_index
= -1;
3300 id
->num_alternatives
= 1;
3302 got_define_asm_attributes
= 1;
3310 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3311 true or annul false is specified, and make a `struct delay_desc'. */
3314 gen_delay (md_rtx_info
*info
)
3316 struct delay_desc
*delay
;
3319 rtx def
= info
->def
;
3320 if (XVECLEN (def
, 1) % 3 != 0)
3322 error_at (info
->loc
, "number of elements in DEFINE_DELAY must"
3323 " be multiple of three");
3327 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3329 if (XVECEXP (def
, 1, i
+ 1))
3330 have_annul_true
= 1;
3331 if (XVECEXP (def
, 1, i
+ 2))
3332 have_annul_false
= 1;
3335 delay
= oballoc (struct delay_desc
);
3337 delay
->num
= ++num_delays
;
3338 delay
->next
= delays
;
3339 delay
->loc
= info
->loc
;
3343 /* Names of attributes that could be possibly cached. */
3344 static const char *cached_attrs
[32];
3345 /* Number of such attributes. */
3346 static int cached_attr_count
;
3347 /* Bitmasks of possibly cached attributes. */
3348 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3349 static unsigned int attrs_to_cache
;
3350 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3352 /* Finds non-const attributes that could be possibly cached.
3353 When create is TRUE, fills in cached_attrs array.
3354 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3358 find_attrs_to_cache (rtx exp
, bool create
)
3362 struct attr_desc
*attr
;
3367 switch (GET_CODE (exp
))
3370 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3371 find_attrs_to_cache (XEXP (exp
, 0), create
);
3375 name
= XSTR (exp
, 0);
3376 if (name
== alternative_name
)
3378 for (i
= 0; i
< cached_attr_count
; i
++)
3379 if (name
== cached_attrs
[i
])
3381 if ((attrs_seen_once
& (1U << i
)) != 0)
3382 attrs_seen_more_than_once
|= (1U << i
);
3384 attrs_seen_once
|= (1U << i
);
3389 attr
= find_attr (&name
, 0);
3393 if (cached_attr_count
== 32)
3395 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3396 attrs_seen_once
|= (1U << cached_attr_count
);
3397 cached_attr_count
++;
3402 find_attrs_to_cache (XEXP (exp
, 0), create
);
3403 find_attrs_to_cache (XEXP (exp
, 1), create
);
3407 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3408 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3416 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3417 We use AND and IOR both for logical and bit-wise operations, so
3418 interpret them as logical unless they are inside a comparison expression. */
3420 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3421 #define FLG_BITWISE 1
3422 /* Set if cached attribute will be known initialized in else block after
3423 this condition. This is true for LHS of toplevel && and || and
3424 even for RHS of ||, but not for RHS of &&. */
3426 /* Set if cached attribute will be known initialized in then block after
3427 this condition. This is true for LHS of toplevel && and || and
3428 even for RHS of &&, but not for RHS of ||. */
3429 #define FLG_INSIDE 4
3430 /* Cleared when an operand of &&. */
3431 #define FLG_OUTSIDE_AND 8
3434 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
)
3436 int comparison_operator
= 0;
3438 struct attr_desc
*attr
;
3440 /* In order not to worry about operator precedence, surround our part of
3441 the expression with parentheses. */
3443 fprintf (outf
, "(");
3444 code
= GET_CODE (exp
);
3447 /* Binary operators. */
3450 fprintf (outf
, "(unsigned) ");
3456 comparison_operator
= FLG_BITWISE
;
3458 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3459 case AND
: case IOR
: case XOR
:
3460 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3461 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3463 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3464 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3465 flags
| comparison_operator
);
3470 flags
&= ~FLG_OUTSIDE_AND
;
3471 if (GET_CODE (XEXP (exp
, 0)) == code
3472 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3473 || (GET_CODE (XEXP (exp
, 0)) == NOT
3474 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3476 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3478 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3483 fprintf (outf
, " == ");
3486 fprintf (outf
, " != ");
3489 fprintf (outf
, " >= ");
3492 fprintf (outf
, " > ");
3495 fprintf (outf
, " >= (unsigned) ");
3498 fprintf (outf
, " > (unsigned) ");
3501 fprintf (outf
, " <= ");
3504 fprintf (outf
, " < ");
3507 fprintf (outf
, " <= (unsigned) ");
3510 fprintf (outf
, " < (unsigned) ");
3513 fprintf (outf
, " + ");
3516 fprintf (outf
, " - ");
3519 fprintf (outf
, " * ");
3522 fprintf (outf
, " / ");
3525 fprintf (outf
, " %% ");
3528 if (flags
& FLG_BITWISE
)
3529 fprintf (outf
, " & ");
3531 fprintf (outf
, " && ");
3534 if (flags
& FLG_BITWISE
)
3535 fprintf (outf
, " | ");
3537 fprintf (outf
, " || ");
3540 fprintf (outf
, " ^ ");
3543 fprintf (outf
, " << ");
3547 fprintf (outf
, " >> ");
3555 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3556 cached_x is only known to be initialized in then block. */
3557 flags
&= ~FLG_AFTER
;
3559 else if (code
== IOR
)
3561 if (flags
& FLG_OUTSIDE_AND
)
3562 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3563 cached_x is only known to be initialized in else block
3564 and else if conditions. */
3565 flags
&= ~FLG_INSIDE
;
3567 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3569 cached_x is not know to be initialized anywhere. */
3570 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3572 if ((code
== AND
|| code
== IOR
)
3573 && (GET_CODE (XEXP (exp
, 1)) == code
3574 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3575 || (GET_CODE (XEXP (exp
, 1)) == NOT
3576 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3578 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
);
3580 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3581 flags
| comparison_operator
);
3585 /* Special-case (not (eq_attrq "alternative" "x")) */
3586 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3588 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3590 fprintf (outf
, "which_alternative != %s",
3591 XSTR (XEXP (exp
, 0), 1));
3595 fprintf (outf
, "! ");
3597 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3601 /* Otherwise, fall through to normal unary operator. */
3603 /* Unary operators. */
3608 if (flags
& FLG_BITWISE
)
3609 fprintf (outf
, "~ ");
3611 fprintf (outf
, "! ");
3614 fprintf (outf
, "abs ");
3617 fprintf (outf
, "-");
3623 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3624 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3629 int set
= XINT (exp
, 0), bit
= 0;
3631 if (flags
& FLG_BITWISE
)
3632 fatal ("EQ_ATTR_ALT not valid inside comparison");
3635 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3637 if (!(set
& (set
- 1)))
3639 if (!(set
& 0xffff))
3662 fprintf (outf
, "which_alternative %s= %d",
3663 XINT (exp
, 1) ? "!" : "=", bit
);
3667 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3668 XINT (exp
, 1) ? "!" : "", set
);
3673 /* Comparison test of an attribute with a value. Most of these will
3674 have been removed by optimization. Handle "alternative"
3675 specially and give error if EQ_ATTR present inside a comparison. */
3677 if (flags
& FLG_BITWISE
)
3678 fatal ("EQ_ATTR not valid inside comparison");
3680 if (XSTR (exp
, 0) == alternative_name
)
3682 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3686 attr
= find_attr (&XSTR (exp
, 0), 0);
3689 /* Now is the time to expand the value of a constant attribute. */
3692 write_test_expr (outf
,
3693 evaluate_eq_attr (exp
, attr
,
3694 attr
->default_val
->value
,
3701 for (i
= 0; i
< cached_attr_count
; i
++)
3702 if (attr
->name
== cached_attrs
[i
])
3704 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3705 fprintf (outf
, "cached_%s", attr
->name
);
3706 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3708 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3709 attr
->name
, attr
->name
);
3710 if (flags
& FLG_AFTER
)
3711 attrs_cached_after
|= (1U << i
);
3712 if (flags
& FLG_INSIDE
)
3713 attrs_cached_inside
|= (1U << i
);
3714 attrs_cached
|= (1U << i
);
3717 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3718 fprintf (outf
, " == ");
3719 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3723 /* Comparison test of flags for define_delays. */
3725 if (flags
& FLG_BITWISE
)
3726 fatal ("ATTR_FLAG not valid inside comparison");
3727 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3730 /* See if an operand matches a predicate. */
3732 /* If only a mode is given, just ensure the mode matches the operand.
3733 If neither a mode nor predicate is given, error. */
3734 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3736 if (GET_MODE (exp
) == VOIDmode
)
3737 fatal ("null MATCH_OPERAND specified as test");
3739 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3740 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3743 fprintf (outf
, "%s (operands[%d], %smode)",
3744 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3747 /* Constant integer. */
3749 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3753 fprint_c_condition (outf
, XSTR (exp
, 0));
3754 if (flags
& FLG_BITWISE
)
3755 fprintf (outf
, " != 0");
3758 /* A random C expression. */
3760 fprint_c_condition (outf
, XSTR (exp
, 0));
3763 /* The address of the branch target. */
3766 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3767 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3771 /* The address of the current insn. We implement this actually as the
3772 address of the current insn for backward branches, but the last
3773 address of the next insn for forward branches, and both with
3774 adjustments that account for the worst-case possible stretching of
3775 intervening alignments between this insn and its destination. */
3776 fprintf (outf
, "insn_current_reference_address (insn)");
3780 fprintf (outf
, "%s", XSTR (exp
, 0));
3784 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3785 fprintf (outf
, " ? ");
3786 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3787 fprintf (outf
, " : ");
3788 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3792 fatal ("bad RTX code `%s' in attribute calculation\n",
3793 GET_RTX_NAME (code
));
3796 fprintf (outf
, ")");
3797 return attrs_cached
;
3800 /* Given an attribute value, return the maximum CONST_STRING argument
3801 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3804 max_attr_value (rtx exp
, int *unknownp
)
3809 switch (GET_CODE (exp
))
3812 current_max
= atoi (XSTR (exp
, 0));
3816 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3817 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3819 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3820 if (n
> current_max
)
3826 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3827 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3828 if (n
> current_max
)
3834 current_max
= INT_MAX
;
3841 /* Given an attribute value, return the minimum CONST_STRING argument
3842 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3845 min_attr_value (rtx exp
, int *unknownp
)
3850 switch (GET_CODE (exp
))
3853 current_min
= atoi (XSTR (exp
, 0));
3857 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3858 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3860 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3861 if (n
< current_min
)
3867 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3868 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3869 if (n
< current_min
)
3875 current_min
= INT_MAX
;
3882 /* Given an attribute value, return the result of ORing together all
3883 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3884 if the numeric value is not known. */
3887 or_attr_value (rtx exp
, int *unknownp
)
3892 switch (GET_CODE (exp
))
3895 current_or
= atoi (XSTR (exp
, 0));
3899 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3900 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3901 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3905 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3906 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3918 /* Scan an attribute value, possibly a conditional, and record what actions
3919 will be required to do any conditional tests in it.
3922 `must_extract' if we need to extract the insn operands
3923 `must_constrain' if we must compute `which_alternative'
3924 `address_used' if an address expression was used
3925 `length_used' if an (eq_attr "length" ...) was used
3929 walk_attr_value (rtx exp
)
3938 code
= GET_CODE (exp
);
3942 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3943 /* Since this is an arbitrary expression, it can look at anything.
3944 However, constant expressions do not depend on any particular
3946 must_extract
= must_constrain
= 1;
3955 must_extract
= must_constrain
= 1;
3959 if (XSTR (exp
, 0) == alternative_name
)
3960 must_extract
= must_constrain
= 1;
3961 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3981 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3986 walk_attr_value (XEXP (exp
, i
));
3990 if (XVEC (exp
, i
) != NULL
)
3991 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3992 walk_attr_value (XVECEXP (exp
, i
, j
));
3997 /* Write out a function to obtain the attribute for a given INSN. */
4000 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
4002 struct attr_value
*av
, *common_av
;
4005 /* Find the most used attribute value. Handle that as the `default' of the
4006 switch we will generate. */
4007 common_av
= find_most_used (attr
);
4009 /* Write out start of function, then all values with explicit `case' lines,
4010 then a `default', then the value with the most uses. */
4011 if (attr
->enum_name
)
4012 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4013 else if (!attr
->is_numeric
)
4014 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4016 fprintf (outf
, "int\n");
4018 /* If the attribute name starts with a star, the remainder is the name of
4019 the subroutine to use, instead of `get_attr_...'. */
4020 if (attr
->name
[0] == '*')
4021 fprintf (outf
, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4022 else if (attr
->is_const
== 0)
4023 fprintf (outf
, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4026 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4027 fprintf (outf
, "{\n");
4029 for (av
= attr
->first_value
; av
; av
= av
->next
)
4030 if (av
->num_insns
== 1)
4031 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4032 true_rtx
, av
->first_insn
->def
->insn_code
,
4033 av
->first_insn
->def
->insn_index
, 0);
4034 else if (av
->num_insns
!= 0)
4035 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4036 true_rtx
, -2, 0, 0);
4038 fprintf (outf
, "}\n\n");
4042 fprintf (outf
, "{\n");
4044 /* Find attributes that are worth caching in the conditions. */
4045 cached_attr_count
= 0;
4046 attrs_seen_more_than_once
= 0;
4047 for (av
= attr
->first_value
; av
; av
= av
->next
)
4049 attrs_seen_once
= 0;
4050 find_attrs_to_cache (av
->value
, true);
4052 /* Remove those that aren't worth caching from the array. */
4053 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4054 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4056 const char *name
= cached_attrs
[i
];
4057 struct attr_desc
*cached_attr
;
4059 cached_attrs
[j
] = name
;
4060 cached_attr
= find_attr (&name
, 0);
4061 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4062 if (cached_attr
->enum_name
)
4063 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4064 else if (!cached_attr
->is_numeric
)
4065 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4067 fprintf (outf
, " int");
4068 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4071 cached_attr_count
= j
;
4072 if (cached_attr_count
)
4073 fprintf (outf
, "\n");
4075 fprintf (outf
, " switch (recog_memoized (insn))\n");
4076 fprintf (outf
, " {\n");
4078 for (av
= attr
->first_value
; av
; av
= av
->next
)
4079 if (av
!= common_av
)
4080 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4082 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4083 fprintf (outf
, " }\n}\n\n");
4084 cached_attr_count
= 0;
4087 /* Given an AND tree of known true terms (because we are inside an `if' with
4088 that as the condition or are in an `else' clause) and an expression,
4089 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4090 the bulk of the work. */
4093 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4097 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4099 if (GET_CODE (known_true
) == AND
)
4101 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4102 insn_code
, insn_index
);
4103 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4104 insn_code
, insn_index
);
4109 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4115 /* Write out a series of tests and assignment statements to perform tests and
4116 sets of an attribute value. We are passed an indentation amount and prefix
4117 and suffix strings to write around each attribute value (e.g., "return"
4121 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
4122 const char *prefix
, const char *suffix
, rtx known_true
,
4123 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4125 if (GET_CODE (value
) == COND
)
4127 /* Assume the default value will be the default of the COND unless we
4128 find an always true expression. */
4129 rtx default_val
= XEXP (value
, 1);
4130 rtx our_known_true
= known_true
;
4135 if (cached_attr_count
)
4137 attrs_seen_once
= 0;
4138 attrs_seen_more_than_once
= 0;
4139 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4140 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4141 attrs_to_cache
|= attrs_seen_more_than_once
;
4144 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4149 /* Reset our_known_true after some time to not accumulate
4150 too much cruft (slowing down genattrtab). */
4152 our_known_true
= known_true
;
4153 testexp
= eliminate_known_true (our_known_true
,
4154 XVECEXP (value
, 0, i
),
4155 insn_code
, insn_index
);
4156 newexp
= attr_rtx (NOT
, testexp
);
4157 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4158 insn_code
, insn_index
);
4160 /* If the test expression is always true or if the next `known_true'
4161 expression is always false, this is the last case, so break
4162 out and let this value be the `else' case. */
4163 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4165 default_val
= XVECEXP (value
, 0, i
+ 1);
4169 /* Compute the expression to pass to our recursive call as being
4171 inner_true
= insert_right_side (AND
, our_known_true
,
4172 testexp
, insn_code
, insn_index
);
4174 /* If this is always false, skip it. */
4175 if (inner_true
== false_rtx
)
4178 attrs_cached_inside
= attrs_cached
;
4179 attrs_cached_after
= attrs_cached
;
4180 write_indent (outf
, indent
);
4181 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4183 write_test_expr (outf
, testexp
, attrs_cached
,
4184 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4185 attrs_cached
= attrs_cached_after
;
4186 fprintf (outf
, "\n");
4187 write_indent (outf
, indent
+ 2);
4188 fprintf (outf
, "{\n");
4190 write_attr_set (outf
, attr
, indent
+ 4,
4191 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4192 inner_true
, insn_code
, insn_index
,
4193 attrs_cached_inside
);
4194 write_indent (outf
, indent
+ 2);
4195 fprintf (outf
, "}\n");
4196 our_known_true
= newexp
;
4201 write_indent (outf
, indent
);
4202 fprintf (outf
, "else\n");
4203 write_indent (outf
, indent
+ 2);
4204 fprintf (outf
, "{\n");
4207 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4208 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4213 write_indent (outf
, indent
+ 2);
4214 fprintf (outf
, "}\n");
4219 write_indent (outf
, indent
);
4220 fprintf (outf
, "%s ", prefix
);
4221 write_attr_value (outf
, attr
, value
);
4222 fprintf (outf
, "%s\n", suffix
);
4226 /* Write a series of case statements for every instruction in list IE.
4227 INDENT is the amount of indentation to write before each case. */
4230 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4232 for (; ie
!= 0; ie
= ie
->next
)
4233 if (ie
->def
->insn_code
!= -1)
4235 write_indent (outf
, indent
);
4236 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4237 fprintf (outf
, "case %d: /* define_peephole, %s:%d */\n",
4238 ie
->def
->insn_code
, ie
->def
->loc
.filename
,
4239 ie
->def
->loc
.lineno
);
4241 fprintf (outf
, "case %d: /* %s */\n",
4242 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4246 /* Write out the computation for one attribute value. */
4249 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4250 int write_case_lines
, const char *prefix
, const char *suffix
,
4251 int indent
, rtx known_true
)
4253 if (av
->num_insns
== 0)
4256 if (av
->has_asm_insn
)
4258 write_indent (outf
, indent
);
4259 fprintf (outf
, "case -1:\n");
4260 write_indent (outf
, indent
+ 2);
4261 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4262 write_indent (outf
, indent
+ 2);
4263 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4264 write_indent (outf
, indent
+ 2);
4265 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4268 if (write_case_lines
)
4269 write_insn_cases (outf
, av
->first_insn
, indent
);
4272 write_indent (outf
, indent
);
4273 fprintf (outf
, "default:\n");
4276 /* See what we have to do to output this value. */
4277 must_extract
= must_constrain
= address_used
= 0;
4278 walk_attr_value (av
->value
);
4282 write_indent (outf
, indent
+ 2);
4283 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4285 else if (must_extract
)
4287 write_indent (outf
, indent
+ 2);
4288 fprintf (outf
, "extract_insn_cached (insn);\n");
4292 if (av
->num_insns
== 1)
4293 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4294 known_true
, av
->first_insn
->def
->insn_code
,
4295 av
->first_insn
->def
->insn_index
, 0);
4297 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4298 known_true
, -2, 0, 0);
4300 if (strncmp (prefix
, "return", 6))
4302 write_indent (outf
, indent
+ 2);
4303 fprintf (outf
, "break;\n");
4305 fprintf (outf
, "\n");
4308 /* Utilities to write in various forms. */
4311 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4313 if (attr
->is_numeric
)
4317 fprintf (outf
, "%d", num
);
4319 if (num
> 9 || num
< 0)
4320 fprintf (outf
, " /* %#x */", num
);
4324 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4325 fprintf (outf
, "_");
4326 write_upcase (outf
, s
);
4331 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4335 switch (GET_CODE (value
))
4338 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4342 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4346 fprint_c_condition (outf
, XSTR (value
, 0));
4351 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4352 if (attr
->enum_name
)
4353 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4354 else if (!attr
->is_numeric
)
4355 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4356 else if (!attr2
->is_numeric
)
4357 fprintf (outf
, "(int)");
4359 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4360 (attr2
->is_const
? "" : "insn"));
4381 write_attr_value (outf
, attr
, XEXP (value
, 0));
4385 write_attr_value (outf
, attr
, XEXP (value
, 1));
4394 write_upcase (FILE *outf
, const char *str
)
4398 /* The argument of TOUPPER should not have side effects. */
4399 fputc (TOUPPER (*str
), outf
);
4405 write_indent (FILE *outf
, int indent
)
4407 for (; indent
> 8; indent
-= 8)
4408 fprintf (outf
, "\t");
4410 for (; indent
; indent
--)
4411 fprintf (outf
, " ");
4414 /* Write a subroutine that is given an insn that requires a delay slot, a
4415 delay slot ordinal, and a candidate insn. It returns nonzero if the
4416 candidate can be placed in the specified delay slot of the insn.
4418 We can write as many as three subroutines. `eligible_for_delay'
4419 handles normal delay slots, `eligible_for_annul_true' indicates that
4420 the specified insn can be annulled if the branch is true, and likewise
4421 for `eligible_for_annul_false'.
4423 KIND is a string distinguishing these three cases ("delay", "annul_true",
4424 or "annul_false"). */
4427 write_eligible_delay (FILE *outf
, const char *kind
)
4429 struct delay_desc
*delay
;
4433 struct attr_desc
*attr
;
4434 struct attr_value
*av
, *common_av
;
4437 /* Compute the maximum number of delay slots required. We use the delay
4438 ordinal times this number plus one, plus the slot number as an index into
4439 the appropriate predicate to test. */
4441 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4442 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4443 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4445 /* Write function prelude. */
4447 fprintf (outf
, "int\n");
4448 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4449 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4451 fprintf (outf
, "{\n");
4452 fprintf (outf
, " rtx_insn *insn;\n");
4453 fprintf (outf
, "\n");
4454 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4455 fprintf (outf
, "\n");
4456 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4457 converts a compound instruction into a loop. */
4458 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4459 fprintf (outf
, " return 0;\n");
4460 fprintf (outf
, "\n");
4462 /* If more than one delay type, find out which type the delay insn is. */
4466 attr
= find_attr (&delay_type_str
, 0);
4468 common_av
= find_most_used (attr
);
4470 fprintf (outf
, " insn = delay_insn;\n");
4471 fprintf (outf
, " switch (recog_memoized (insn))\n");
4472 fprintf (outf
, " {\n");
4474 sprintf (str
, " * %d;\n break;", max_slots
);
4475 for (av
= attr
->first_value
; av
; av
= av
->next
)
4476 if (av
!= common_av
)
4477 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4479 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4480 fprintf (outf
, " }\n\n");
4482 /* Ensure matched. Otherwise, shouldn't have been called. */
4483 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4486 /* If just one type of delay slot, write simple switch. */
4487 if (num_delays
== 1 && max_slots
== 1)
4489 fprintf (outf
, " insn = candidate_insn;\n");
4490 fprintf (outf
, " switch (recog_memoized (insn))\n");
4491 fprintf (outf
, " {\n");
4493 attr
= find_attr (&delay_1_0_str
, 0);
4495 common_av
= find_most_used (attr
);
4497 for (av
= attr
->first_value
; av
; av
= av
->next
)
4498 if (av
!= common_av
)
4499 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4501 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4502 fprintf (outf
, " }\n");
4507 /* Write a nested CASE. The first indicates which condition we need to
4508 test, and the inner CASE tests the condition. */
4509 fprintf (outf
, " insn = candidate_insn;\n");
4510 fprintf (outf
, " switch (slot)\n");
4511 fprintf (outf
, " {\n");
4513 for (delay
= delays
; delay
; delay
= delay
->next
)
4514 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4516 fprintf (outf
, " case %d:\n",
4517 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4518 fprintf (outf
, " switch (recog_memoized (insn))\n");
4519 fprintf (outf
, "\t{\n");
4521 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4523 attr
= find_attr (&pstr
, 0);
4525 common_av
= find_most_used (attr
);
4527 for (av
= attr
->first_value
; av
; av
= av
->next
)
4528 if (av
!= common_av
)
4529 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4531 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4532 fprintf (outf
, " }\n");
4535 fprintf (outf
, " default:\n");
4536 fprintf (outf
, " gcc_unreachable ();\n");
4537 fprintf (outf
, " }\n");
4540 fprintf (outf
, "}\n\n");
4543 /* This page contains miscellaneous utility routines. */
4545 /* Given a pointer to a (char *), return a malloc'ed string containing the
4546 next comma-separated element. Advance the pointer to after the string
4547 scanned, or the end-of-string. Return NULL if at end of string. */
4550 next_comma_elt (const char **pstr
)
4554 start
= scan_comma_elt (pstr
);
4559 return attr_string (start
, *pstr
- start
);
4562 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4563 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4564 replaced by a pointer to a canonical copy of the string. */
4566 static struct attr_desc
*
4567 find_attr (const char **name_p
, int create
)
4569 struct attr_desc
*attr
;
4571 const char *name
= *name_p
;
4573 /* Before we resort to using `strcmp', see if the string address matches
4574 anywhere. In most cases, it should have been canonicalized to do so. */
4575 if (name
== alternative_name
)
4578 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4579 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4580 if (name
== attr
->name
)
4583 /* Otherwise, do it the slow way. */
4584 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4585 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4587 *name_p
= attr
->name
;
4594 attr
= oballoc (struct attr_desc
);
4595 attr
->name
= DEF_ATTR_STRING (name
);
4596 attr
->enum_name
= 0;
4597 attr
->first_value
= attr
->default_val
= NULL
;
4598 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4599 attr
->next
= attrs
[index
];
4600 attrs
[index
] = attr
;
4602 *name_p
= attr
->name
;
4607 /* Create internal attribute with the given default value. */
4610 make_internal_attr (const char *name
, rtx value
, int special
)
4612 struct attr_desc
*attr
;
4614 attr
= find_attr (&name
, 1);
4615 gcc_assert (!attr
->default_val
);
4617 attr
->is_numeric
= 1;
4619 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4620 attr
->default_val
= get_attr_value (file_location ("<internal>", 0),
4624 /* Find the most used value of an attribute. */
4626 static struct attr_value
*
4627 find_most_used (struct attr_desc
*attr
)
4629 struct attr_value
*av
;
4630 struct attr_value
*most_used
;
4636 for (av
= attr
->first_value
; av
; av
= av
->next
)
4637 if (av
->num_insns
> nuses
)
4638 nuses
= av
->num_insns
, most_used
= av
;
4643 /* Return (attr_value "n") */
4646 make_numeric_value (int n
)
4648 static rtx int_values
[20];
4652 gcc_assert (n
>= 0);
4654 if (n
< 20 && int_values
[n
])
4655 return int_values
[n
];
4657 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4658 exp
= attr_rtx (CONST_STRING
, p
);
4661 int_values
[n
] = exp
;
4667 copy_rtx_unchanging (rtx orig
)
4669 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4672 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4676 /* Determine if an insn has a constant number of delay slots, i.e., the
4677 number of delay slots is not a function of the length of the insn. */
4680 write_const_num_delay_slots (FILE *outf
)
4682 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4683 struct attr_value
*av
;
4687 fprintf (outf
, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4688 fprintf (outf
, "{\n");
4689 fprintf (outf
, " switch (recog_memoized (insn))\n");
4690 fprintf (outf
, " {\n");
4692 for (av
= attr
->first_value
; av
; av
= av
->next
)
4695 walk_attr_value (av
->value
);
4697 write_insn_cases (outf
, av
->first_insn
, 4);
4700 fprintf (outf
, " default:\n");
4701 fprintf (outf
, " return 1;\n");
4702 fprintf (outf
, " }\n}\n\n");
4706 /* Synthetic attributes used by insn-automata.c and the scheduler.
4707 These are primarily concerned with (define_insn_reservation)
4712 struct insn_reserv
*next
;
4715 int default_latency
;
4718 /* Sequence number of this insn. */
4721 /* Whether a (define_bypass) construct names this insn in its
4726 static struct insn_reserv
*all_insn_reservs
= 0;
4727 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4728 static size_t n_insn_reservs
;
4730 /* Store information from a DEFINE_INSN_RESERVATION for future
4731 attribute generation. */
4733 gen_insn_reserv (md_rtx_info
*info
)
4735 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4736 rtx def
= info
->def
;
4738 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4739 decl
->default_latency
= XINT (def
, 1);
4740 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, info
->loc
);
4741 decl
->insn_num
= n_insn_reservs
;
4742 decl
->bypassed
= false;
4745 *last_insn_reserv_p
= decl
;
4746 last_insn_reserv_p
= &decl
->next
;
4750 /* Store information from a DEFINE_BYPASS for future attribute
4751 generation. The only thing we care about is the list of output
4752 insns, which will later be used to tag reservation structures with
4753 a 'bypassed' bit. */
4757 struct bypass_list
*next
;
4758 const char *pattern
;
4761 static struct bypass_list
*all_bypasses
;
4762 static size_t n_bypasses
;
4763 static size_t n_bypassed
;
4766 gen_bypass_1 (const char *s
, size_t len
)
4768 struct bypass_list
*b
;
4773 s
= attr_string (s
, len
);
4774 for (b
= all_bypasses
; b
; b
= b
->next
)
4775 if (s
== b
->pattern
)
4776 return; /* already got that one */
4778 b
= oballoc (struct bypass_list
);
4780 b
->next
= all_bypasses
;
4786 gen_bypass (md_rtx_info
*info
)
4788 const char *p
, *base
;
4790 rtx def
= info
->def
;
4791 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4794 gen_bypass_1 (base
, p
- base
);
4797 while (ISSPACE (*p
));
4800 gen_bypass_1 (base
, p
- base
);
4803 /* Find and mark all of the bypassed insns. */
4805 process_bypasses (void)
4807 struct bypass_list
*b
;
4808 struct insn_reserv
*r
;
4812 /* The reservation list is likely to be much longer than the bypass
4814 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4815 for (b
= all_bypasses
; b
; b
= b
->next
)
4816 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4824 /* Check that attribute NAME is used in define_insn_reservation condition
4825 EXP. Return true if it is. */
4827 check_tune_attr (const char *name
, rtx exp
)
4829 switch (GET_CODE (exp
))
4832 if (check_tune_attr (name
, XEXP (exp
, 0)))
4834 return check_tune_attr (name
, XEXP (exp
, 1));
4837 return (check_tune_attr (name
, XEXP (exp
, 0))
4838 && check_tune_attr (name
, XEXP (exp
, 1)));
4841 return XSTR (exp
, 0) == name
;
4848 /* Try to find a const attribute (usually cpu or tune) that is used
4849 in all define_insn_reservation conditions. */
4850 static struct attr_desc
*
4851 find_tune_attr (rtx exp
)
4853 struct attr_desc
*attr
;
4855 switch (GET_CODE (exp
))
4859 attr
= find_tune_attr (XEXP (exp
, 0));
4862 return find_tune_attr (XEXP (exp
, 1));
4865 if (XSTR (exp
, 0) == alternative_name
)
4868 attr
= find_attr (&XSTR (exp
, 0), 0);
4871 if (attr
->is_const
&& !attr
->is_special
)
4873 struct insn_reserv
*decl
;
4875 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4876 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4887 /* Create all of the attributes that describe automaton properties.
4888 Write the DFA and latency function prototypes to the files that
4889 need to have them, and write the init_sched_attrs(). */
4892 make_automaton_attrs (void)
4895 struct insn_reserv
*decl
;
4896 rtx code_exp
, lats_exp
, byps_exp
;
4897 struct attr_desc
*tune_attr
;
4899 if (n_insn_reservs
== 0)
4902 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4903 if (tune_attr
!= NULL
)
4905 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4906 struct attr_value
*val
;
4909 gcc_assert (tune_attr
->is_const
4910 && !tune_attr
->is_special
4911 && !tune_attr
->is_numeric
);
4913 /* Write the prototypes for all DFA functions. */
4914 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4916 if (val
== tune_attr
->default_val
)
4918 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4920 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4921 XSTR (val
->value
, 0));
4923 fprintf (dfa_file
, "\n");
4925 /* Write the prototypes for all latency functions. */
4926 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4928 if (val
== tune_attr
->default_val
)
4930 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4931 fprintf (latency_file
,
4932 "extern int insn_default_latency_%s (rtx_insn *);\n",
4933 XSTR (val
->value
, 0));
4935 fprintf (latency_file
, "\n");
4937 /* Write the prototypes for all automaton functions. */
4938 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4940 if (val
== tune_attr
->default_val
)
4942 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4944 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4945 "extern int insn_default_latency_%s (rtx_insn *);\n",
4946 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4948 fprintf (attr_file
, "\n");
4949 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4950 fprintf (attr_file
, "int (*insn_default_latency) (rtx_insn *);\n");
4951 fprintf (attr_file
, "\n");
4952 fprintf (attr_file
, "void\n");
4953 fprintf (attr_file
, "init_sched_attrs (void)\n");
4954 fprintf (attr_file
, "{\n");
4956 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4960 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
4962 if (val
== tune_attr
->default_val
)
4964 for (decl
= all_insn_reservs
, i
= 0;
4970 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
4971 if (condexp
== false_rtx
)
4973 if (condexp
== true_rtx
)
4975 condexps
[i
] = condexp
;
4976 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
4977 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
4981 code_exp
= rtx_alloc (COND
);
4982 lats_exp
= rtx_alloc (COND
);
4985 XVEC (code_exp
, 0) = rtvec_alloc (j
);
4986 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
4990 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
4991 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
4995 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4996 XEXP (lats_exp
, 1) = make_numeric_value (0);
5003 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
5004 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
5006 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
5007 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5010 name
= XNEWVEC (char,
5011 sizeof ("*internal_dfa_insn_code_")
5012 + strlen (XSTR (val
->value
, 0)));
5013 strcpy (name
, "*internal_dfa_insn_code_");
5014 strcat (name
, XSTR (val
->value
, 0));
5015 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5016 strcpy (name
, "*insn_default_latency_");
5017 strcat (name
, XSTR (val
->value
, 0));
5018 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5023 fprintf (attr_file
, " if (");
5027 fprintf (attr_file
, " else if (");
5028 write_test_expr (attr_file
, test
, 0, 0);
5029 fprintf (attr_file
, ")\n");
5030 fprintf (attr_file
, " {\n");
5031 fprintf (attr_file
, " internal_dfa_insn_code\n");
5032 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5033 XSTR (val
->value
, 0));
5034 fprintf (attr_file
, " insn_default_latency\n");
5035 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5036 XSTR (val
->value
, 0));
5037 fprintf (attr_file
, " }\n");
5040 fprintf (attr_file
, " else\n");
5041 fprintf (attr_file
, " gcc_unreachable ();\n");
5042 fprintf (attr_file
, "}\n");
5043 fprintf (attr_file
, "\n");
5045 XDELETEVEC (condexps
);
5049 code_exp
= rtx_alloc (COND
);
5050 lats_exp
= rtx_alloc (COND
);
5052 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5053 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5055 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5056 XEXP (lats_exp
, 1) = make_numeric_value (0);
5058 for (decl
= all_insn_reservs
, i
= 0;
5060 decl
= decl
->next
, i
+= 2)
5062 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5063 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5065 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5066 XVECEXP (lats_exp
, 0, i
+1)
5067 = make_numeric_value (decl
->default_latency
);
5069 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5070 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5073 if (n_bypasses
== 0)
5074 byps_exp
= make_numeric_value (0);
5077 process_bypasses ();
5079 byps_exp
= rtx_alloc (COND
);
5080 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypassed
* 2);
5081 XEXP (byps_exp
, 1) = make_numeric_value (0);
5082 for (decl
= all_insn_reservs
, i
= 0;
5087 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5088 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5093 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5097 write_header (FILE *outf
)
5099 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5100 " from the machine description file `md'. */\n\n");
5102 fprintf (outf
, "#include \"config.h\"\n");
5103 fprintf (outf
, "#include \"system.h\"\n");
5104 fprintf (outf
, "#include \"coretypes.h\"\n");
5105 fprintf (outf
, "#include \"backend.h\"\n");
5106 fprintf (outf
, "#include \"predict.h\"\n");
5107 fprintf (outf
, "#include \"tree.h\"\n");
5108 fprintf (outf
, "#include \"rtl.h\"\n");
5109 fprintf (outf
, "#include \"alias.h\"\n");
5110 fprintf (outf
, "#include \"options.h\"\n");
5111 fprintf (outf
, "#include \"varasm.h\"\n");
5112 fprintf (outf
, "#include \"stor-layout.h\"\n");
5113 fprintf (outf
, "#include \"calls.h\"\n");
5114 fprintf (outf
, "#include \"insn-attr.h\"\n");
5115 fprintf (outf
, "#include \"tm_p.h\"\n");
5116 fprintf (outf
, "#include \"insn-config.h\"\n");
5117 fprintf (outf
, "#include \"recog.h\"\n");
5118 fprintf (outf
, "#include \"regs.h\"\n");
5119 fprintf (outf
, "#include \"real.h\"\n");
5120 fprintf (outf
, "#include \"output.h\"\n");
5121 fprintf (outf
, "#include \"toplev.h\"\n");
5122 fprintf (outf
, "#include \"flags.h\"\n");
5123 fprintf (outf
, "#include \"emit-rtl.h\"\n");
5124 fprintf (outf
, "\n");
5125 fprintf (outf
, "#define operands recog_data.operand\n\n");
5129 open_outfile (const char *file_name
)
5132 outf
= fopen (file_name
, "w");
5134 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5135 write_header (outf
);
5140 handle_arg (const char *arg
)
5145 attr_file_name
= &arg
[2];
5148 dfa_file_name
= &arg
[2];
5151 latency_file_name
= &arg
[2];
5159 main (int argc
, char **argv
)
5161 struct attr_desc
*attr
;
5162 struct insn_def
*id
;
5165 progname
= "genattrtab";
5167 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5168 return FATAL_EXIT_CODE
;
5170 attr_file
= open_outfile (attr_file_name
);
5171 dfa_file
= open_outfile (dfa_file_name
);
5172 latency_file
= open_outfile (latency_file_name
);
5174 obstack_init (hash_obstack
);
5175 obstack_init (temp_obstack
);
5177 /* Set up true and false rtx's */
5178 true_rtx
= rtx_alloc (CONST_INT
);
5179 XWINT (true_rtx
, 0) = 1;
5180 false_rtx
= rtx_alloc (CONST_INT
);
5181 XWINT (false_rtx
, 0) = 0;
5182 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5183 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5185 alternative_name
= DEF_ATTR_STRING ("alternative");
5186 length_str
= DEF_ATTR_STRING ("length");
5187 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5188 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5189 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5191 /* Read the machine description. */
5194 while (read_md_rtx (&info
))
5196 switch (GET_CODE (info
.def
))
5199 case DEFINE_PEEPHOLE
:
5200 case DEFINE_ASM_ATTRIBUTES
:
5205 case DEFINE_ENUM_ATTR
:
5213 case DEFINE_INSN_RESERVATION
:
5214 gen_insn_reserv (&info
);
5224 if (GET_CODE (info
.def
) != DEFINE_ASM_ATTRIBUTES
)
5225 insn_index_number
++;
5229 return FATAL_EXIT_CODE
;
5231 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5232 if (! got_define_asm_attributes
)
5235 info
.def
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5236 XVEC (info
.def
, 0) = rtvec_alloc (0);
5237 info
.loc
= file_location ("<internal>", 0);
5242 /* Expand DEFINE_DELAY information into new attribute. */
5246 /* Make `insn_alternatives'. */
5247 int num_insn_codes
= get_num_insn_codes ();
5248 insn_alternatives
= oballocvec (uint64_t, num_insn_codes
);
5249 for (id
= defs
; id
; id
= id
->next
)
5250 if (id
->insn_code
>= 0)
5251 insn_alternatives
[id
->insn_code
]
5252 = (((uint64_t) 1) << id
->num_alternatives
) - 1;
5254 /* Make `insn_n_alternatives'. */
5255 insn_n_alternatives
= oballocvec (int, num_insn_codes
);
5256 for (id
= defs
; id
; id
= id
->next
)
5257 if (id
->insn_code
>= 0)
5258 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5260 /* Construct extra attributes for automata. */
5261 make_automaton_attrs ();
5263 /* Prepare to write out attribute subroutines by checking everything stored
5264 away and building the attribute cases. */
5268 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5269 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5270 attr
->default_val
->value
5271 = check_attr_value (attr
->default_val
->value
, attr
);
5274 return FATAL_EXIT_CODE
;
5276 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5277 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5280 /* Construct extra attributes for `length'. */
5281 make_length_attrs ();
5283 /* Perform any possible optimizations to speed up compilation. */
5284 optimize_attrs (num_insn_codes
);
5286 /* Now write out all the `gen_attr_...' routines. Do these before the
5287 special routines so that they get defined before they are used. */
5289 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5290 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5294 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5295 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5297 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5298 outf
= latency_file
;
5301 #undef IS_ATTR_GROUP
5303 if (! attr
->is_special
&& ! attr
->is_const
)
5304 write_attr_get (outf
, attr
);
5307 /* Write out delay eligibility information, if DEFINE_DELAY present.
5308 (The function to compute the number of delay slots will be written
5312 write_eligible_delay (attr_file
, "delay");
5313 if (have_annul_true
)
5314 write_eligible_delay (attr_file
, "annul_true");
5315 if (have_annul_false
)
5316 write_eligible_delay (attr_file
, "annul_false");
5319 /* Write out constant delay slot info. */
5320 write_const_num_delay_slots (attr_file
);
5322 write_length_unit_log (attr_file
);
5324 if (fclose (attr_file
) != 0)
5325 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5326 if (fclose (dfa_file
) != 0)
5327 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5328 if (fclose (latency_file
) != 0)
5329 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5331 return SUCCESS_EXIT_CODE
;