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_code_number
;
215 static int insn_index_number
;
216 static int got_define_asm_attributes
;
217 static int must_extract
;
218 static int must_constrain
;
219 static int address_used
;
220 static int length_used
;
221 static int num_delays
;
222 static int have_annul_true
, have_annul_false
;
223 static int num_insn_ents
;
225 /* Stores, for each insn code, the number of constraint alternatives. */
227 static int *insn_n_alternatives
;
229 /* Stores, for each insn code, a bitmap that has bits on for each possible
232 static uint64_t *insn_alternatives
;
234 /* Used to simplify expressions. */
236 static rtx true_rtx
, false_rtx
;
238 /* Used to reduce calls to `strcmp' */
240 static const char *alternative_name
;
241 static const char *length_str
;
242 static const char *delay_type_str
;
243 static const char *delay_1_0_str
;
244 static const char *num_delay_slots_str
;
246 /* Simplify an expression. Only call the routine if there is something to
248 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
249 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
250 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
252 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
254 /* Forward declarations of functions used before their definitions, only. */
255 static char *attr_string (const char *, int);
256 static char *attr_printf (unsigned int, const char *, ...)
258 static rtx
make_numeric_value (int);
259 static struct attr_desc
*find_attr (const char **, int);
260 static rtx
mk_attr_alt (uint64_t);
261 static char *next_comma_elt (const char **);
262 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
263 static rtx
copy_boolean (rtx
);
264 static int compares_alternatives_p (rtx
);
265 static void make_internal_attr (const char *, rtx
, int);
266 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
267 static void walk_attr_value (rtx
);
268 static int max_attr_value (rtx
, int*);
269 static int min_attr_value (rtx
, int*);
270 static int or_attr_value (rtx
, int*);
271 static rtx
simplify_test_exp (rtx
, int, int);
272 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
273 static rtx
copy_rtx_unchanging (rtx
);
274 static bool attr_alt_subset_p (rtx
, rtx
);
275 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
276 static void clear_struct_flag (rtx
);
277 static void write_attr_valueq (FILE *, struct attr_desc
*, const char *);
278 static struct attr_value
*find_most_used (struct attr_desc
*);
279 static void write_attr_set (FILE *, struct attr_desc
*, int, rtx
,
280 const char *, const char *, rtx
,
281 int, int, unsigned int);
282 static void write_attr_case (FILE *, struct attr_desc
*,
284 int, const char *, const char *, int, rtx
);
285 static void write_attr_value (FILE *, struct attr_desc
*, rtx
);
286 static void write_upcase (FILE *, const char *);
287 static void write_indent (FILE *, int);
288 static rtx
identity_fn (rtx
);
289 static rtx
zero_fn (rtx
);
290 static rtx
one_fn (rtx
);
291 static rtx
max_fn (rtx
);
292 static rtx
min_fn (rtx
);
294 #define oballoc(T) XOBNEW (hash_obstack, T)
295 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
297 /* This gen* file is unique, in that it writes out multiple files.
299 Before GCC 4.8, insn-attrtab.c was written out containing many large
300 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
301 a parallel build, and even made it impossible to build GCC on machines
302 with relatively small RAM space (PR other/29442). Therefore, the
303 atrribute functions/tables are now written out to three separate
304 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
305 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
306 rest goes to ATTR_FILE_NAME. */
308 static const char *attr_file_name
= NULL
;
309 static const char *dfa_file_name
= NULL
;
310 static const char *latency_file_name
= NULL
;
312 static FILE *attr_file
, *dfa_file
, *latency_file
;
314 /* Hash table for sharing RTL and strings. */
316 /* Each hash table slot is a bucket containing a chain of these structures.
317 Strings are given negative hash codes; RTL expressions are given positive
322 struct attr_hash
*next
; /* Next structure in the bucket. */
323 unsigned int hashcode
; /* Hash code of this rtx or string. */
326 char *str
; /* The string (negative hash codes) */
327 rtx rtl
; /* or the RTL recorded here. */
331 /* Now here is the hash table. When recording an RTL, it is added to
332 the slot whose index is the hash code mod the table size. Note
333 that the hash table is used for several kinds of RTL (see attr_rtx)
334 and for strings. While all these live in the same table, they are
335 completely independent, and the hash code is computed differently
338 #define RTL_HASH_SIZE 4093
339 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
341 /* Here is how primitive or already-shared RTL's hash
343 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
345 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
348 attr_hash_add_rtx (unsigned int hashcode
, rtx rtl
)
352 h
= XOBNEW (hash_obstack
, struct attr_hash
);
353 h
->hashcode
= hashcode
;
355 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
356 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
359 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
362 attr_hash_add_string (unsigned int hashcode
, char *str
)
366 h
= XOBNEW (hash_obstack
, struct attr_hash
);
367 h
->hashcode
= -hashcode
;
369 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
370 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
373 /* Generate an RTL expression, but avoid duplicates.
374 Set the ATTR_PERMANENT_P flag for these permanent objects.
376 In some cases we cannot uniquify; then we return an ordinary
377 impermanent rtx with ATTR_PERMANENT_P clear.
381 rtx attr_rtx (code, [element1, ..., elementn]) */
384 attr_rtx_1 (enum rtx_code code
, va_list p
)
386 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
387 unsigned int hashcode
;
389 struct obstack
*old_obstack
= rtl_obstack
;
391 /* For each of several cases, search the hash table for an existing entry.
392 Use that entry if one is found; otherwise create a new RTL and add it
395 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
397 rtx arg0
= va_arg (p
, rtx
);
399 /* A permanent object cannot point to impermanent ones. */
400 if (! ATTR_PERMANENT_P (arg0
))
402 rt_val
= rtx_alloc (code
);
403 XEXP (rt_val
, 0) = arg0
;
407 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
408 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
409 if (h
->hashcode
== hashcode
410 && GET_CODE (h
->u
.rtl
) == code
411 && XEXP (h
->u
.rtl
, 0) == arg0
)
416 rtl_obstack
= hash_obstack
;
417 rt_val
= rtx_alloc (code
);
418 XEXP (rt_val
, 0) = arg0
;
421 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
422 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
423 || GET_RTX_CLASS (code
) == RTX_COMPARE
424 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
426 rtx arg0
= va_arg (p
, rtx
);
427 rtx arg1
= va_arg (p
, rtx
);
429 /* A permanent object cannot point to impermanent ones. */
430 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
432 rt_val
= rtx_alloc (code
);
433 XEXP (rt_val
, 0) = arg0
;
434 XEXP (rt_val
, 1) = arg1
;
438 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
439 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
440 if (h
->hashcode
== hashcode
441 && GET_CODE (h
->u
.rtl
) == code
442 && XEXP (h
->u
.rtl
, 0) == arg0
443 && XEXP (h
->u
.rtl
, 1) == arg1
)
448 rtl_obstack
= hash_obstack
;
449 rt_val
= rtx_alloc (code
);
450 XEXP (rt_val
, 0) = arg0
;
451 XEXP (rt_val
, 1) = arg1
;
454 else if (code
== SYMBOL_REF
455 || (GET_RTX_LENGTH (code
) == 1
456 && GET_RTX_FORMAT (code
)[0] == 's'))
458 char *arg0
= va_arg (p
, char *);
460 arg0
= DEF_ATTR_STRING (arg0
);
462 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
463 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
464 if (h
->hashcode
== hashcode
465 && GET_CODE (h
->u
.rtl
) == code
466 && XSTR (h
->u
.rtl
, 0) == arg0
)
471 rtl_obstack
= hash_obstack
;
472 rt_val
= rtx_alloc (code
);
473 XSTR (rt_val
, 0) = arg0
;
474 if (code
== SYMBOL_REF
)
475 X0EXP (rt_val
, 1) = NULL_RTX
;
478 else if (GET_RTX_LENGTH (code
) == 2
479 && GET_RTX_FORMAT (code
)[0] == 's'
480 && GET_RTX_FORMAT (code
)[1] == 's')
482 char *arg0
= va_arg (p
, char *);
483 char *arg1
= va_arg (p
, char *);
485 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
486 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
487 if (h
->hashcode
== hashcode
488 && GET_CODE (h
->u
.rtl
) == code
489 && XSTR (h
->u
.rtl
, 0) == arg0
490 && XSTR (h
->u
.rtl
, 1) == arg1
)
495 rtl_obstack
= hash_obstack
;
496 rt_val
= rtx_alloc (code
);
497 XSTR (rt_val
, 0) = arg0
;
498 XSTR (rt_val
, 1) = arg1
;
501 else if (code
== CONST_INT
)
503 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
513 int i
; /* Array indices... */
514 const char *fmt
; /* Current rtx's format... */
516 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
518 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
519 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
523 case '0': /* Unused field. */
526 case 'i': /* An integer? */
527 XINT (rt_val
, i
) = va_arg (p
, int);
530 case 'w': /* A wide integer? */
531 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
534 case 's': /* A string? */
535 XSTR (rt_val
, i
) = va_arg (p
, char *);
538 case 'e': /* An expression? */
539 case 'u': /* An insn? Same except when printing. */
540 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
543 case 'E': /* An RTX vector? */
544 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
554 rtl_obstack
= old_obstack
;
555 attr_hash_add_rtx (hashcode
, rt_val
);
556 ATTR_PERMANENT_P (rt_val
) = 1;
561 attr_rtx (enum rtx_code code
, ...)
567 result
= attr_rtx_1 (code
, p
);
572 /* Create a new string printed with the printf line arguments into a space
573 of at most LEN bytes:
575 rtx attr_printf (len, format, [arg1, ..., argn]) */
578 attr_printf (unsigned int len
, const char *fmt
, ...)
585 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
587 vsprintf (str
, fmt
, p
);
590 return DEF_ATTR_STRING (str
);
594 attr_eq (const char *name
, const char *value
)
596 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
602 return XSTR (make_numeric_value (n
), 0);
605 /* Return a permanent (possibly shared) copy of a string STR (not assumed
606 to be null terminated) with LEN bytes. */
609 attr_string (const char *str
, int len
)
612 unsigned int hashcode
;
616 /* Compute the hash code. */
617 hashcode
= (len
+ 1) * 613U + (unsigned) str
[0];
618 for (i
= 1; i
< len
; i
+= 2)
619 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
620 if ((int) hashcode
< 0)
621 hashcode
= -hashcode
;
623 /* Search the table for the string. */
624 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
625 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
626 && !strncmp (h
->u
.str
, str
, len
))
627 return h
->u
.str
; /* <-- return if found. */
629 /* Not found; create a permanent copy and add it to the hash table. */
630 new_str
= XOBNEWVAR (hash_obstack
, char, len
+ 1);
631 memcpy (new_str
, str
, len
);
633 attr_hash_add_string (hashcode
, new_str
);
634 copy_md_ptr_loc (new_str
, str
);
636 return new_str
; /* Return the new string. */
639 /* Check two rtx's for equality of contents,
640 taking advantage of the fact that if both are hashed
641 then they can't be equal unless they are the same object. */
644 attr_equal_p (rtx x
, rtx y
)
646 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
647 && rtx_equal_p (x
, y
)));
650 /* Copy an attribute value expression,
651 descending to all depths, but not copying any
652 permanent hashed subexpressions. */
655 attr_copy_rtx (rtx orig
)
660 const char *format_ptr
;
662 /* No need to copy a permanent object. */
663 if (ATTR_PERMANENT_P (orig
))
666 code
= GET_CODE (orig
);
683 copy
= rtx_alloc (code
);
684 PUT_MODE (copy
, GET_MODE (orig
));
685 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
686 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
687 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
689 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
691 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
693 switch (*format_ptr
++)
696 XEXP (copy
, i
) = XEXP (orig
, i
);
697 if (XEXP (orig
, i
) != NULL
)
698 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
703 XVEC (copy
, i
) = XVEC (orig
, i
);
704 if (XVEC (orig
, i
) != NULL
)
706 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
707 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
708 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
714 XINT (copy
, i
) = XINT (orig
, i
);
718 XWINT (copy
, i
) = XWINT (orig
, i
);
723 XSTR (copy
, i
) = XSTR (orig
, i
);
733 /* Given a test expression for an attribute, ensure it is validly formed.
734 IS_CONST indicates whether the expression is constant for each compiler
735 run (a constant expression may not test any particular insn).
737 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
738 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
739 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
741 Update the string address in EQ_ATTR expression to be the same used
742 in the attribute (or `alternative_name') to speed up subsequent
743 `find_attr' calls and eliminate most `strcmp' calls.
745 Return the new expression, if any. */
748 check_attr_test (rtx exp
, int is_const
, file_location loc
)
750 struct attr_desc
*attr
;
751 struct attr_value
*av
;
752 const char *name_ptr
, *p
;
755 switch (GET_CODE (exp
))
758 /* Handle negation test. */
759 if (XSTR (exp
, 1)[0] == '!')
760 return check_attr_test (attr_rtx (NOT
,
761 attr_eq (XSTR (exp
, 0),
765 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
767 attr
= find_attr (&XSTR (exp
, 0), 0);
770 if (! strcmp (XSTR (exp
, 0), "alternative"))
771 return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
773 fatal_at (loc
, "unknown attribute `%s' in EQ_ATTR",
777 if (is_const
&& ! attr
->is_const
)
778 fatal_at (loc
, "constant expression uses insn attribute `%s'"
779 " in EQ_ATTR", XSTR (exp
, 0));
781 /* Copy this just to make it permanent,
782 so expressions using it can be permanent too. */
783 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
785 /* It shouldn't be possible to simplify the value given to a
786 constant attribute, so don't expand this until it's time to
787 write the test expression. */
789 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
791 if (attr
->is_numeric
)
793 for (p
= XSTR (exp
, 1); *p
; p
++)
795 fatal_at (loc
, "attribute `%s' takes only numeric values",
800 for (av
= attr
->first_value
; av
; av
= av
->next
)
801 if (GET_CODE (av
->value
) == CONST_STRING
802 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
806 fatal_at (loc
, "unknown value `%s' for `%s' attribute",
807 XSTR (exp
, 1), XSTR (exp
, 0));
812 if (! strcmp (XSTR (exp
, 0), "alternative"))
816 name_ptr
= XSTR (exp
, 1);
817 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
818 set
|= ((uint64_t) 1) << atoi (p
);
820 return mk_attr_alt (set
);
824 /* Make an IOR tree of the possible values. */
826 name_ptr
= XSTR (exp
, 1);
827 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
829 newexp
= attr_eq (XSTR (exp
, 0), p
);
830 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
833 return check_attr_test (orexp
, is_const
, loc
);
842 /* Either TRUE or FALSE. */
850 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, loc
);
851 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, loc
);
855 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, loc
);
859 exp
= attr_rtx (MATCH_TEST
, XSTR (exp
, 0));
860 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
865 fatal_at (loc
, "RTL operator \"%s\" not valid in constant attribute"
866 " test", GET_RTX_NAME (GET_CODE (exp
)));
867 /* These cases can't be simplified. */
868 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
871 case LE
: case LT
: case GT
: case GE
:
872 case LEU
: case LTU
: case GTU
: case GEU
:
874 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
875 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
876 exp
= attr_rtx (GET_CODE (exp
),
877 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
878 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
879 /* These cases can't be simplified. */
880 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
886 /* These cases are valid for constant attributes, but can't be
888 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
889 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
893 fatal_at (loc
, "RTL operator \"%s\" not valid in attribute test",
894 GET_RTX_NAME (GET_CODE (exp
)));
900 /* Given an expression, ensure that it is validly formed and that all named
901 attribute values are valid for the given attribute. Issue a fatal error
904 Return a perhaps modified replacement expression for the value. */
907 check_attr_value (rtx exp
, struct attr_desc
*attr
)
909 struct attr_value
*av
;
913 switch (GET_CODE (exp
))
916 if (!attr
->is_numeric
)
919 "CONST_INT not valid for non-numeric attribute %s",
924 if (INTVAL (exp
) < 0)
927 "negative numeric value specified for attribute %s",
934 if (! strcmp (XSTR (exp
, 0), "*"))
937 if (attr
->is_numeric
)
944 "non-numeric value for numeric attribute %s",
951 for (av
= attr
->first_value
; av
; av
= av
->next
)
952 if (GET_CODE (av
->value
) == CONST_STRING
953 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
957 error_at (attr
->loc
, "unknown value `%s' for `%s' attribute",
958 XSTR (exp
, 0), attr
->name
);
962 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), attr
->is_const
,
964 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
965 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
973 if (!attr
->is_numeric
)
975 error_at (attr
->loc
, "invalid operation `%s' for non-numeric"
976 " attribute value", GET_RTX_NAME (GET_CODE (exp
)));
983 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
984 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
993 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
997 if (XVECLEN (exp
, 0) % 2 != 0)
999 error_at (attr
->loc
, "first operand of COND must have even length");
1003 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1005 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1006 attr
->is_const
, attr
->loc
);
1007 XVECEXP (exp
, 0, i
+ 1)
1008 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1011 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1016 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1018 error_at (attr
->loc
, "unknown attribute `%s' in ATTR",
1020 else if (attr
->is_const
&& ! attr2
->is_const
)
1021 error_at (attr
->loc
,
1022 "non-constant attribute `%s' referenced from `%s'",
1023 XSTR (exp
, 0), attr
->name
);
1024 else if (attr
->is_numeric
!= attr2
->is_numeric
)
1025 error_at (attr
->loc
,
1026 "numeric attribute mismatch calling `%s' from `%s'",
1027 XSTR (exp
, 0), attr
->name
);
1032 /* A constant SYMBOL_REF is valid as a constant attribute test and
1033 is expanded later by make_canonical into a COND. In a non-constant
1034 attribute test, it is left be. */
1035 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1038 error_at (attr
->loc
, "invalid operation `%s' for attribute value",
1039 GET_RTX_NAME (GET_CODE (exp
)));
1046 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1047 It becomes a COND with each test being (eq_attr "alternative" "n") */
1050 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1052 int num_alt
= id
->num_alternatives
;
1056 if (XVECLEN (exp
, 1) != num_alt
)
1058 error_at (id
->loc
, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1059 " was %d expected %d", XVECLEN (exp
, 1), num_alt
);
1063 /* Make a COND with all tests but the last. Select the last value via the
1065 condexp
= rtx_alloc (COND
);
1066 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1068 for (i
= 0; i
< num_alt
- 1; i
++)
1071 p
= attr_numeral (i
);
1073 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1074 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1077 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1079 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1082 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1083 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1086 convert_set_attr (rtx exp
, struct insn_def
*id
)
1089 const char *name_ptr
;
1093 /* See how many alternative specified. */
1094 n
= n_comma_elts (XSTR (exp
, 1));
1096 return attr_rtx (SET
,
1097 attr_rtx (ATTR
, XSTR (exp
, 0)),
1098 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1100 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1101 XSTR (newexp
, 0) = XSTR (exp
, 0);
1102 XVEC (newexp
, 1) = rtvec_alloc (n
);
1104 /* Process each comma-separated name. */
1105 name_ptr
= XSTR (exp
, 1);
1107 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1108 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1110 return convert_set_attr_alternative (newexp
, id
);
1113 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1114 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1120 struct insn_def
*id
;
1121 struct attr_desc
*attr
;
1125 for (id
= defs
; id
; id
= id
->next
)
1127 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1130 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1132 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1133 switch (GET_CODE (value
))
1136 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1138 error_at (id
->loc
, "bad attribute set");
1143 case SET_ATTR_ALTERNATIVE
:
1144 value
= convert_set_attr_alternative (value
, id
);
1148 value
= convert_set_attr (value
, id
);
1152 error_at (id
->loc
, "invalid attribute code %s",
1153 GET_RTX_NAME (GET_CODE (value
)));
1156 if (value
== NULL_RTX
)
1159 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1161 error_at (id
->loc
, "unknown attribute %s",
1162 XSTR (XEXP (value
, 0), 0));
1166 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1167 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1172 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1173 expressions by converting them into a COND. This removes cases from this
1174 program. Also, replace an attribute value of "*" with the default attribute
1178 make_canonical (struct attr_desc
*attr
, rtx exp
)
1183 switch (GET_CODE (exp
))
1186 exp
= make_numeric_value (INTVAL (exp
));
1190 if (! strcmp (XSTR (exp
, 0), "*"))
1192 if (attr
->default_val
== 0)
1193 fatal ("(attr_value \"*\") used in invalid context");
1194 exp
= attr
->default_val
->value
;
1197 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1202 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1204 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1205 This makes the COND something that won't be considered an arbitrary
1206 expression by walk_attr_value. */
1207 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1208 exp
= check_attr_value (exp
, attr
);
1212 newexp
= rtx_alloc (COND
);
1213 XVEC (newexp
, 0) = rtvec_alloc (2);
1214 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1215 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1217 XEXP (newexp
, 1) = XEXP (exp
, 2);
1220 /* Fall through to COND case since this is now a COND. */
1227 /* First, check for degenerate COND. */
1228 if (XVECLEN (exp
, 0) == 0)
1229 return make_canonical (attr
, XEXP (exp
, 1));
1230 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1232 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1234 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1235 XVECEXP (exp
, 0, i
+ 1)
1236 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1237 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1253 copy_boolean (rtx exp
)
1255 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1256 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1257 copy_boolean (XEXP (exp
, 1)));
1258 if (GET_CODE (exp
) == MATCH_OPERAND
)
1260 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1261 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1263 else if (GET_CODE (exp
) == EQ_ATTR
)
1265 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1266 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1272 /* Given a value and an attribute description, return a `struct attr_value *'
1273 that represents that value. This is either an existing structure, if the
1274 value has been previously encountered, or a newly-created structure.
1276 `insn_code' is the code of an insn whose attribute has the specified
1277 value (-2 if not processing an insn). We ensure that all insns for
1278 a given value have the same number of alternatives if the value checks
1281 static struct attr_value
*
1282 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1284 struct attr_value
*av
;
1285 uint64_t num_alt
= 0;
1287 value
= make_canonical (attr
, value
);
1288 if (compares_alternatives_p (value
))
1290 if (insn_code
< 0 || insn_alternatives
== NULL
)
1291 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1293 num_alt
= insn_alternatives
[insn_code
];
1296 for (av
= attr
->first_value
; av
; av
= av
->next
)
1297 if (rtx_equal_p (value
, av
->value
)
1298 && (num_alt
== 0 || av
->first_insn
== NULL
1299 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1302 av
= oballoc (struct attr_value
);
1304 av
->next
= attr
->first_value
;
1305 attr
->first_value
= av
;
1306 av
->first_insn
= NULL
;
1308 av
->has_asm_insn
= 0;
1313 /* After all DEFINE_DELAYs have been read in, create internal attributes
1314 to generate the required routines.
1316 First, we compute the number of delay slots for each insn (as a COND of
1317 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1318 delay type is specified, we compute a similar function giving the
1319 DEFINE_DELAY ordinal for each insn.
1321 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1322 tells whether a given insn can be in that delay slot.
1324 Normal attribute filling and optimization expands these to contain the
1325 information needed to handle delay slots. */
1328 expand_delays (void)
1330 struct delay_desc
*delay
;
1336 /* First, generate data for `num_delay_slots' function. */
1338 condexp
= rtx_alloc (COND
);
1339 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1340 XEXP (condexp
, 1) = make_numeric_value (0);
1342 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1344 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1345 XVECEXP (condexp
, 0, i
+ 1)
1346 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1349 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1351 /* If more than one delay type, do the same for computing the delay type. */
1354 condexp
= rtx_alloc (COND
);
1355 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1356 XEXP (condexp
, 1) = make_numeric_value (0);
1358 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1360 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1361 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1364 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1367 /* For each delay possibility and delay slot, compute an eligibility
1368 attribute for non-annulled insns and for each type of annulled (annul
1369 if true and annul if false). */
1370 for (delay
= delays
; delay
; delay
= delay
->next
)
1372 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1374 condexp
= XVECEXP (delay
->def
, 1, i
);
1376 condexp
= false_rtx
;
1377 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1378 make_numeric_value (1), make_numeric_value (0));
1380 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1381 "*delay_%d_%d", delay
->num
, i
/ 3);
1382 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1384 if (have_annul_true
)
1386 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1387 if (condexp
== 0) condexp
= false_rtx
;
1388 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1389 make_numeric_value (1),
1390 make_numeric_value (0));
1391 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1392 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1393 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1396 if (have_annul_false
)
1398 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1399 if (condexp
== 0) condexp
= false_rtx
;
1400 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1401 make_numeric_value (1),
1402 make_numeric_value (0));
1403 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1404 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1405 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1411 /* Once all attributes and insns have been read and checked, we construct for
1412 each attribute value a list of all the insns that have that value for
1416 fill_attr (struct attr_desc
*attr
)
1418 struct attr_value
*av
;
1419 struct insn_ent
*ie
;
1420 struct insn_def
*id
;
1424 /* Don't fill constant attributes. The value is independent of
1425 any particular insn. */
1429 for (id
= defs
; id
; id
= id
->next
)
1431 /* If no value is specified for this insn for this attribute, use the
1434 if (XVEC (id
->def
, id
->vec_idx
))
1435 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1436 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1438 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1441 av
= attr
->default_val
;
1443 av
= get_attr_value (value
, attr
, id
->insn_code
);
1445 ie
= oballoc (struct insn_ent
);
1447 insert_insn_ent (av
, ie
);
1451 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1452 test that checks relative positions of insns (uses MATCH_DUP or PC).
1453 If so, replace it with what is obtained by passing the expression to
1454 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1455 recursively on each value (including the default value). Otherwise,
1456 return the value returned by NO_ADDRESS_FN applied to EXP. */
1459 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1460 rtx (*address_fn
) (rtx
))
1465 if (GET_CODE (exp
) == COND
)
1467 /* See if any tests use addresses. */
1469 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1470 walk_attr_value (XVECEXP (exp
, 0, i
));
1473 return (*address_fn
) (exp
);
1475 /* Make a new copy of this COND, replacing each element. */
1476 newexp
= rtx_alloc (COND
);
1477 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1478 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1480 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1481 XVECEXP (newexp
, 0, i
+ 1)
1482 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1483 no_address_fn
, address_fn
);
1486 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1487 no_address_fn
, address_fn
);
1492 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1495 walk_attr_value (XEXP (exp
, 0));
1497 return (*address_fn
) (exp
);
1499 return attr_rtx (IF_THEN_ELSE
,
1500 substitute_address (XEXP (exp
, 0),
1501 no_address_fn
, address_fn
),
1502 substitute_address (XEXP (exp
, 1),
1503 no_address_fn
, address_fn
),
1504 substitute_address (XEXP (exp
, 2),
1505 no_address_fn
, address_fn
));
1508 return (*no_address_fn
) (exp
);
1511 /* Make new attributes from the `length' attribute. The following are made,
1512 each corresponding to a function called from `shorten_branches' or
1515 *insn_default_length This is the length of the insn to be returned
1516 by `get_attr_length' before `shorten_branches'
1517 has been called. In each case where the length
1518 depends on relative addresses, the largest
1519 possible is used. This routine is also used
1520 to compute the initial size of the insn.
1522 *insn_variable_length_p This returns 1 if the insn's length depends
1523 on relative addresses, zero otherwise.
1525 *insn_current_length This is only called when it is known that the
1526 insn has a variable length and returns the
1527 current length, based on relative addresses.
1531 make_length_attrs (void)
1533 static const char *new_names
[] =
1535 "*insn_default_length",
1537 "*insn_variable_length_p",
1538 "*insn_current_length"
1540 static rtx (*const no_address_fn
[]) (rtx
)
1541 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1542 static rtx (*const address_fn
[]) (rtx
)
1543 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1545 struct attr_desc
*length_attr
, *new_attr
;
1546 struct attr_value
*av
, *new_av
;
1547 struct insn_ent
*ie
, *new_ie
;
1549 /* See if length attribute is defined. If so, it must be numeric. Make
1550 it special so we don't output anything for it. */
1551 length_attr
= find_attr (&length_str
, 0);
1552 if (length_attr
== 0)
1555 if (! length_attr
->is_numeric
)
1556 fatal ("length attribute must be numeric");
1558 length_attr
->is_const
= 0;
1559 length_attr
->is_special
= 1;
1561 /* Make each new attribute, in turn. */
1562 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1564 make_internal_attr (new_names
[i
],
1565 substitute_address (length_attr
->default_val
->value
,
1566 no_address_fn
[i
], address_fn
[i
]),
1568 new_attr
= find_attr (&new_names
[i
], 0);
1569 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1570 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1572 new_av
= get_attr_value (substitute_address (av
->value
,
1575 new_attr
, ie
->def
->insn_code
);
1576 new_ie
= oballoc (struct insn_ent
);
1577 new_ie
->def
= ie
->def
;
1578 insert_insn_ent (new_av
, new_ie
);
1583 /* Utility functions called from above routine. */
1586 identity_fn (rtx exp
)
1592 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1594 return make_numeric_value (0);
1598 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1600 return make_numeric_value (1);
1607 return make_numeric_value (max_attr_value (exp
, &unknown
));
1614 return make_numeric_value (min_attr_value (exp
, &unknown
));
1618 write_length_unit_log (FILE *outf
)
1620 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1621 struct attr_value
*av
;
1622 struct insn_ent
*ie
;
1623 unsigned int length_unit_log
, length_or
;
1628 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1629 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1630 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1631 length_or
|= or_attr_value (av
->value
, &unknown
);
1634 if (length_attr
== NULL
|| unknown
)
1635 length_unit_log
= 0;
1638 length_or
= ~length_or
;
1639 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1642 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1645 /* Compute approximate cost of the expression. Used to decide whether
1646 expression is cheap enough for inline. */
1648 attr_rtx_cost (rtx x
)
1654 code
= GET_CODE (x
);
1667 /* Alternatives don't result into function call. */
1668 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1675 const char *fmt
= GET_RTX_FORMAT (code
);
1676 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1682 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1683 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1686 cost
+= attr_rtx_cost (XEXP (x
, i
));
1696 /* Take a COND expression and see if any of the conditions in it can be
1697 simplified. If any are known true or known false for the particular insn
1698 code, the COND can be further simplified.
1700 Also call ourselves on any COND operations that are values of this COND.
1702 We do not modify EXP; rather, we make and return a new rtx. */
1705 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1708 /* We store the desired contents here,
1709 then build a new expression if they don't match EXP. */
1710 rtx defval
= XEXP (exp
, 1);
1711 rtx new_defval
= XEXP (exp
, 1);
1712 int len
= XVECLEN (exp
, 0);
1713 rtx
*tests
= XNEWVEC (rtx
, len
);
1717 /* This lets us free all storage allocated below, if appropriate. */
1718 obstack_finish (rtl_obstack
);
1720 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1722 /* See if default value needs simplification. */
1723 if (GET_CODE (defval
) == COND
)
1724 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1726 /* Simplify the subexpressions, and see what tests we can get rid of. */
1728 for (i
= 0; i
< len
; i
+= 2)
1730 rtx newtest
, newval
;
1732 /* Simplify this test. */
1733 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1736 newval
= tests
[i
+ 1];
1737 /* See if this value may need simplification. */
1738 if (GET_CODE (newval
) == COND
)
1739 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1741 /* Look for ways to delete or combine this test. */
1742 if (newtest
== true_rtx
)
1744 /* If test is true, make this value the default
1745 and discard this + any following tests. */
1747 defval
= tests
[i
+ 1];
1748 new_defval
= newval
;
1751 else if (newtest
== false_rtx
)
1753 /* If test is false, discard it and its value. */
1754 for (j
= i
; j
< len
- 2; j
++)
1755 tests
[j
] = tests
[j
+ 2];
1760 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1762 /* If this value and the value for the prev test are the same,
1766 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1767 insn_code
, insn_index
);
1769 /* Delete this test/value. */
1770 for (j
= i
; j
< len
- 2; j
++)
1771 tests
[j
] = tests
[j
+ 2];
1777 tests
[i
+ 1] = newval
;
1780 /* If the last test in a COND has the same value
1781 as the default value, that test isn't needed. */
1783 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1786 /* See if we changed anything. */
1787 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1790 for (i
= 0; i
< len
; i
++)
1791 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1799 if (GET_CODE (defval
) == COND
)
1800 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1808 rtx newexp
= rtx_alloc (COND
);
1810 XVEC (newexp
, 0) = rtvec_alloc (len
);
1811 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1812 XEXP (newexp
, 1) = new_defval
;
1819 /* Remove an insn entry from an attribute value. */
1822 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1824 struct insn_ent
*previe
;
1826 if (av
->first_insn
== ie
)
1827 av
->first_insn
= ie
->next
;
1830 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1832 previe
->next
= ie
->next
;
1836 if (ie
->def
->insn_code
== -1)
1837 av
->has_asm_insn
= 0;
1842 /* Insert an insn entry in an attribute value list. */
1845 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1847 ie
->next
= av
->first_insn
;
1848 av
->first_insn
= ie
;
1850 if (ie
->def
->insn_code
== -1)
1851 av
->has_asm_insn
= 1;
1856 /* This is a utility routine to take an expression that is a tree of either
1857 AND or IOR expressions and insert a new term. The new term will be
1858 inserted at the right side of the first node whose code does not match
1859 the root. A new node will be created with the root's code. Its left
1860 side will be the old right side and its right side will be the new
1863 If the `term' is itself a tree, all its leaves will be inserted. */
1866 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1870 /* Avoid consing in some special cases. */
1871 if (code
== AND
&& term
== true_rtx
)
1873 if (code
== AND
&& term
== false_rtx
)
1875 if (code
== AND
&& exp
== true_rtx
)
1877 if (code
== AND
&& exp
== false_rtx
)
1879 if (code
== IOR
&& term
== true_rtx
)
1881 if (code
== IOR
&& term
== false_rtx
)
1883 if (code
== IOR
&& exp
== true_rtx
)
1885 if (code
== IOR
&& exp
== false_rtx
)
1887 if (attr_equal_p (exp
, term
))
1890 if (GET_CODE (term
) == code
)
1892 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1893 insn_code
, insn_index
);
1894 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1895 insn_code
, insn_index
);
1900 if (GET_CODE (exp
) == code
)
1902 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1903 term
, insn_code
, insn_index
);
1904 if (new_rtx
!= XEXP (exp
, 1))
1905 /* Make a copy of this expression and call recursively. */
1906 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1912 /* Insert the new term. */
1913 newexp
= attr_rtx (code
, exp
, term
);
1916 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1919 /* If we have an expression which AND's a bunch of
1920 (not (eq_attrq "alternative" "n"))
1921 terms, we may have covered all or all but one of the possible alternatives.
1922 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1924 This routine is passed an expression and either AND or IOR. It returns a
1925 bitmask indicating which alternatives are mentioned within EXP. */
1928 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1931 if (GET_CODE (exp
) == code
)
1932 return compute_alternative_mask (XEXP (exp
, 0), code
)
1933 | compute_alternative_mask (XEXP (exp
, 1), code
);
1935 else if (code
== AND
&& GET_CODE (exp
) == NOT
1936 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1937 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1938 string
= XSTR (XEXP (exp
, 0), 1);
1940 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1941 && XSTR (exp
, 0) == alternative_name
)
1942 string
= XSTR (exp
, 1);
1944 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1946 if (code
== AND
&& XINT (exp
, 1))
1947 return XINT (exp
, 0);
1949 if (code
== IOR
&& !XINT (exp
, 1))
1950 return XINT (exp
, 0);
1958 return ((uint64_t) 1) << (string
[0] - '0');
1959 return ((uint64_t) 1) << atoi (string
);
1962 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1963 attribute with the value represented by that bit. */
1966 make_alternative_compare (uint64_t mask
)
1968 return mk_attr_alt (mask
);
1971 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1972 of "attr" for this insn code. From that value, we can compute a test
1973 showing when the EQ_ATTR will be true. This routine performs that
1974 computation. If a test condition involves an address, we leave the EQ_ATTR
1975 intact because addresses are only valid for the `length' attribute.
1977 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1978 it refers. VALUE is the value of that attribute for the insn
1979 corresponding to INSN_CODE and INSN_INDEX. */
1982 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1983 int insn_code
, int insn_index
)
1990 while (GET_CODE (value
) == ATTR
)
1992 struct attr_value
*av
= NULL
;
1994 attr
= find_attr (&XSTR (value
, 0), 0);
1996 if (insn_code_values
)
1998 struct attr_value_list
*iv
;
1999 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2000 if (iv
->attr
== attr
)
2008 struct insn_ent
*ie
;
2009 for (av
= attr
->first_value
; av
; av
= av
->next
)
2010 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2011 if (ie
->def
->insn_code
== insn_code
)
2021 switch (GET_CODE (value
))
2024 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2035 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2036 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
2037 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
2038 for (p
= string
; *p
; p
++)
2041 newexp
= attr_rtx (EQ
, value
,
2042 attr_rtx (SYMBOL_REF
,
2043 DEF_ATTR_STRING (string
)));
2048 /* We construct an IOR of all the cases for which the
2049 requested attribute value is present. Since we start with
2050 FALSE, if it is not present, FALSE will be returned.
2052 Each case is the AND of the NOT's of the previous conditions with the
2053 current condition; in the default case the current condition is TRUE.
2055 For each possible COND value, call ourselves recursively.
2057 The extra TRUE and FALSE expressions will be eliminated by another
2058 call to the simplification routine. */
2063 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2065 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2066 insn_code
, insn_index
);
2068 right
= insert_right_side (AND
, andexp
, this_cond
,
2069 insn_code
, insn_index
);
2070 right
= insert_right_side (AND
, right
,
2071 evaluate_eq_attr (exp
, attr
,
2074 insn_code
, insn_index
),
2075 insn_code
, insn_index
);
2076 orexp
= insert_right_side (IOR
, orexp
, right
,
2077 insn_code
, insn_index
);
2079 /* Add this condition into the AND expression. */
2080 newexp
= attr_rtx (NOT
, this_cond
);
2081 andexp
= insert_right_side (AND
, andexp
, newexp
,
2082 insn_code
, insn_index
);
2085 /* Handle the default case. */
2086 right
= insert_right_side (AND
, andexp
,
2087 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2088 insn_code
, insn_index
),
2089 insn_code
, insn_index
);
2090 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2097 /* If uses an address, must return original expression. But set the
2098 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2101 walk_attr_value (newexp
);
2105 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2106 return copy_rtx_unchanging (exp
);
2113 /* This routine is called when an AND of a term with a tree of AND's is
2114 encountered. If the term or its complement is present in the tree, it
2115 can be replaced with TRUE or FALSE, respectively.
2117 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2118 be true and hence are complementary.
2120 There is one special case: If we see
2121 (and (not (eq_attr "att" "v1"))
2122 (eq_attr "att" "v2"))
2123 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2124 replace the term, not anything in the AND tree. So we pass a pointer to
2128 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2133 int left_eliminates_term
, right_eliminates_term
;
2135 if (GET_CODE (exp
) == AND
)
2137 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2138 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2139 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2141 newexp
= attr_rtx (AND
, left
, right
);
2143 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2147 else if (GET_CODE (exp
) == IOR
)
2149 /* For the IOR case, we do the same as above, except that we can
2150 only eliminate `term' if both sides of the IOR would do so. */
2152 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2153 left_eliminates_term
= (temp
== true_rtx
);
2156 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2157 right_eliminates_term
= (temp
== true_rtx
);
2159 if (left_eliminates_term
&& right_eliminates_term
)
2162 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2164 newexp
= attr_rtx (IOR
, left
, right
);
2166 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2170 /* Check for simplifications. Do some extra checking here since this
2171 routine is called so many times. */
2176 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2179 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2182 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2184 if (attr_alt_subset_p (*pterm
, exp
))
2187 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2190 if (attr_alt_subset_p (exp
, *pterm
))
2196 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2198 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2201 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2207 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2208 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2210 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2213 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2219 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2220 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2222 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2225 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2231 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2233 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2237 else if (GET_CODE (exp
) == NOT
)
2239 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2243 else if (GET_CODE (*pterm
) == NOT
)
2245 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2249 else if (attr_equal_p (exp
, *pterm
))
2255 /* Similar to `simplify_and_tree', but for IOR trees. */
2258 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2263 int left_eliminates_term
, right_eliminates_term
;
2265 if (GET_CODE (exp
) == IOR
)
2267 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2268 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2269 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2271 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2273 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2277 else if (GET_CODE (exp
) == AND
)
2279 /* For the AND case, we do the same as above, except that we can
2280 only eliminate `term' if both sides of the AND would do so. */
2282 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2283 left_eliminates_term
= (temp
== false_rtx
);
2286 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2287 right_eliminates_term
= (temp
== false_rtx
);
2289 if (left_eliminates_term
&& right_eliminates_term
)
2292 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2294 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2296 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2300 if (attr_equal_p (exp
, *pterm
))
2303 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2306 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2309 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2310 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2311 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2314 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2315 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2316 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2322 /* Simplify test expression and use temporary obstack in order to avoid
2323 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2324 and avoid unnecessary copying if possible. */
2327 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2330 struct obstack
*old
;
2331 if (ATTR_IND_SIMPLIFIED_P (exp
))
2334 rtl_obstack
= temp_obstack
;
2335 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2337 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2339 return attr_copy_rtx (x
);
2342 /* Returns true if S1 is a subset of S2. */
2345 attr_alt_subset_p (rtx s1
, rtx s2
)
2347 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2350 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2353 return !(XINT (s1
, 0) & XINT (s2
, 0));
2359 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2366 /* Returns true if S1 is a subset of complement of S2. */
2369 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2371 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2374 return !(XINT (s1
, 0) & XINT (s2
, 0));
2377 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2380 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2390 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2393 attr_alt_intersection (rtx s1
, rtx s2
)
2395 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2397 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2400 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2403 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2406 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2409 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2414 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2419 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2422 attr_alt_union (rtx s1
, rtx s2
)
2424 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2426 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2429 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2432 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2435 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2438 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2444 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2448 /* Return EQ_ATTR_ALT expression representing complement of S. */
2451 attr_alt_complement (rtx s
)
2453 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2455 XINT (result
, 0) = XINT (s
, 0);
2456 XINT (result
, 1) = 1 - XINT (s
, 1);
2461 /* Return EQ_ATTR_ALT expression representing set containing elements set
2465 mk_attr_alt (uint64_t e
)
2467 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2469 XINT (result
, 0) = e
;
2470 XINT (result
, 1) = 0;
2475 /* Given an expression, see if it can be simplified for a particular insn
2476 code based on the values of other attributes being tested. This can
2477 eliminate nested get_attr_... calls.
2479 Note that if an endless recursion is specified in the patterns, the
2480 optimization will loop. However, it will do so in precisely the cases where
2481 an infinite recursion loop could occur during compilation. It's better that
2485 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2488 struct attr_desc
*attr
;
2489 struct attr_value
*av
;
2490 struct insn_ent
*ie
;
2491 struct attr_value_list
*iv
;
2494 bool left_alt
, right_alt
;
2496 /* Don't re-simplify something we already simplified. */
2497 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2500 switch (GET_CODE (exp
))
2503 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2504 if (left
== false_rtx
)
2506 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2507 if (right
== false_rtx
)
2510 if (GET_CODE (left
) == EQ_ATTR_ALT
2511 && GET_CODE (right
) == EQ_ATTR_ALT
)
2513 exp
= attr_alt_intersection (left
, right
);
2514 return simplify_test_exp (exp
, insn_code
, insn_index
);
2517 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2518 present on both sides, apply the distributive law since this will
2519 yield simplifications. */
2520 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2521 && compute_alternative_mask (left
, IOR
)
2522 && compute_alternative_mask (right
, IOR
))
2524 if (GET_CODE (left
) == IOR
)
2525 std::swap (left
, right
);
2527 newexp
= attr_rtx (IOR
,
2528 attr_rtx (AND
, left
, XEXP (right
, 0)),
2529 attr_rtx (AND
, left
, XEXP (right
, 1)));
2531 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2534 /* Try with the term on both sides. */
2535 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2536 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2537 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2539 if (left
== false_rtx
|| right
== false_rtx
)
2541 else if (left
== true_rtx
)
2545 else if (right
== true_rtx
)
2549 /* See if all or all but one of the insn's alternatives are specified
2550 in this tree. Optimize if so. */
2552 if (GET_CODE (left
) == NOT
)
2553 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2554 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2556 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2559 if (GET_CODE (right
) == NOT
)
2560 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2561 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2563 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2564 && XINT (right
, 1));
2567 && (GET_CODE (left
) == AND
2569 || GET_CODE (right
) == AND
2572 i
= compute_alternative_mask (exp
, AND
);
2573 if (i
& ~insn_alternatives
[insn_code
])
2574 fatal ("invalid alternative specified for pattern number %d",
2577 /* If all alternatives are excluded, this is false. */
2578 i
^= insn_alternatives
[insn_code
];
2581 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2583 /* If just one excluded, AND a comparison with that one to the
2584 front of the tree. The others will be eliminated by
2585 optimization. We do not want to do this if the insn has one
2586 alternative and we have tested none of them! */
2587 left
= make_alternative_compare (i
);
2588 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2589 newexp
= attr_rtx (AND
, left
, right
);
2591 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2595 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2597 newexp
= attr_rtx (AND
, left
, right
);
2598 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2603 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2604 if (left
== true_rtx
)
2606 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2607 if (right
== true_rtx
)
2610 if (GET_CODE (left
) == EQ_ATTR_ALT
2611 && GET_CODE (right
) == EQ_ATTR_ALT
)
2613 exp
= attr_alt_union (left
, right
);
2614 return simplify_test_exp (exp
, insn_code
, insn_index
);
2617 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2618 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2619 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2621 if (right
== true_rtx
|| left
== true_rtx
)
2623 else if (left
== false_rtx
)
2627 else if (right
== false_rtx
)
2632 /* Test for simple cases where the distributive law is useful. I.e.,
2633 convert (ior (and (x) (y))
2639 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2640 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2642 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2644 left
= XEXP (left
, 0);
2646 newexp
= attr_rtx (AND
, left
, right
);
2647 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2651 convert (ior (and (y) (x))
2653 to (and (ior (y) (z))
2655 Note that we want the common term to stay at the end.
2658 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2659 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2661 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2664 right
= XEXP (right
, 1);
2665 newexp
= attr_rtx (AND
, left
, right
);
2666 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2669 /* See if all or all but one of the insn's alternatives are specified
2670 in this tree. Optimize if so. */
2672 else if (insn_code
>= 0
2673 && (GET_CODE (left
) == IOR
2674 || (GET_CODE (left
) == EQ_ATTR_ALT
2676 || (GET_CODE (left
) == EQ_ATTR
2677 && XSTR (left
, 0) == alternative_name
)
2678 || GET_CODE (right
) == IOR
2679 || (GET_CODE (right
) == EQ_ATTR_ALT
2680 && !XINT (right
, 1))
2681 || (GET_CODE (right
) == EQ_ATTR
2682 && XSTR (right
, 0) == alternative_name
)))
2684 i
= compute_alternative_mask (exp
, IOR
);
2685 if (i
& ~insn_alternatives
[insn_code
])
2686 fatal ("invalid alternative specified for pattern number %d",
2689 /* If all alternatives are included, this is true. */
2690 i
^= insn_alternatives
[insn_code
];
2693 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2695 /* If just one excluded, IOR a comparison with that one to the
2696 front of the tree. The others will be eliminated by
2697 optimization. We do not want to do this if the insn has one
2698 alternative and we have tested none of them! */
2699 left
= make_alternative_compare (i
);
2700 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2701 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2703 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2707 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2709 newexp
= attr_rtx (IOR
, left
, right
);
2710 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2715 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2717 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2718 insn_code
, insn_index
);
2722 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2723 if (GET_CODE (left
) == NOT
)
2724 return XEXP (left
, 0);
2726 if (left
== false_rtx
)
2728 if (left
== true_rtx
)
2731 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2733 exp
= attr_alt_complement (left
);
2734 return simplify_test_exp (exp
, insn_code
, insn_index
);
2737 /* Try to apply De`Morgan's laws. */
2738 if (GET_CODE (left
) == IOR
)
2740 newexp
= attr_rtx (AND
,
2741 attr_rtx (NOT
, XEXP (left
, 0)),
2742 attr_rtx (NOT
, XEXP (left
, 1)));
2744 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2746 else if (GET_CODE (left
) == AND
)
2748 newexp
= attr_rtx (IOR
,
2749 attr_rtx (NOT
, XEXP (left
, 0)),
2750 attr_rtx (NOT
, XEXP (left
, 1)));
2752 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2754 else if (left
!= XEXP (exp
, 0))
2756 newexp
= attr_rtx (NOT
, left
);
2762 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2766 if (XSTR (exp
, 0) == alternative_name
)
2768 newexp
= mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
2772 /* Look at the value for this insn code in the specified attribute.
2773 We normally can replace this comparison with the condition that
2774 would give this insn the values being tested for. */
2776 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2781 if (insn_code_values
)
2783 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2784 if (iv
->attr
== attr
)
2792 for (av
= attr
->first_value
; av
; av
= av
->next
)
2793 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2794 if (ie
->def
->insn_code
== insn_code
)
2801 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2802 insn_code
, insn_index
);
2803 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2804 if (attr_rtx_cost (x
) < 7)
2814 /* We have already simplified this expression. Simplifying it again
2815 won't buy anything unless we weren't given a valid insn code
2816 to process (i.e., we are canonicalizing something.). */
2818 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2819 return copy_rtx_unchanging (newexp
);
2824 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2825 otherwise return 0. */
2828 tests_attr_p (rtx p
, struct attr_desc
*attr
)
2833 if (GET_CODE (p
) == EQ_ATTR
)
2835 if (XSTR (p
, 0) != attr
->name
)
2840 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2841 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2842 for (i
= 0; i
< ie
; i
++)
2847 if (tests_attr_p (XEXP (p
, i
), attr
))
2852 je
= XVECLEN (p
, i
);
2853 for (j
= 0; j
< je
; ++j
)
2854 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2863 /* Calculate a topological sorting of all attributes so that
2864 all attributes only depend on attributes in front of it.
2865 Place the result in *RET (which is a pointer to an array of
2866 attr_desc pointers), and return the size of that array. */
2869 get_attr_order (struct attr_desc
***ret
)
2873 struct attr_desc
*attr
;
2874 struct attr_desc
**all
, **sorted
;
2876 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2877 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2879 all
= XNEWVEC (struct attr_desc
*, num
);
2880 sorted
= XNEWVEC (struct attr_desc
*, num
);
2881 handled
= XCNEWVEC (char, num
);
2883 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2884 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2888 for (i
= 0; i
< num
; i
++)
2889 if (all
[i
]->is_const
)
2890 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2892 /* We have only few attributes hence we can live with the inner
2893 loop being O(n^2), unlike the normal fast variants of topological
2897 for (i
= 0; i
< num
; i
++)
2900 /* Let's see if I depends on anything interesting. */
2902 for (k
= 0; k
< num
; k
++)
2905 struct attr_value
*av
;
2906 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2907 if (av
->num_insns
!= 0)
2908 if (tests_attr_p (av
->value
, all
[k
]))
2912 /* Something in I depends on K. */
2917 /* Nothing in I depended on anything intersting, so
2920 sorted
[j
++] = all
[i
];
2926 for (j
= 0; j
< num
; j
++)
2928 struct attr_desc
*attr2
;
2929 struct attr_value
*av
;
2932 fprintf (stderr
, "%s depends on: ", attr
->name
);
2933 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2934 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2935 if (!attr2
->is_const
)
2936 for (av
= attr
->first_value
; av
; av
= av
->next
)
2937 if (av
->num_insns
!= 0)
2938 if (tests_attr_p (av
->value
, attr2
))
2940 fprintf (stderr
, "%s, ", attr2
->name
);
2943 fprintf (stderr
, "\n");
2951 /* Optimize the attribute lists by seeing if we can determine conditional
2952 values from the known values of other attributes. This will save subroutine
2953 calls during the compilation. */
2956 optimize_attrs (void)
2958 struct attr_desc
*attr
;
2959 struct attr_value
*av
;
2960 struct insn_ent
*ie
;
2963 struct attr_value_list
*ivbuf
;
2964 struct attr_value_list
*iv
;
2965 struct attr_desc
**topsort
;
2968 /* For each insn code, make a list of all the insn_ent's for it,
2969 for all values for all attributes. */
2971 if (num_insn_ents
== 0)
2974 /* Make 2 extra elements, for "code" values -2 and -1. */
2975 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2977 /* Offset the table address so we can index by -2 or -1. */
2978 insn_code_values
+= 2;
2980 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2982 /* Create the chain of insn*attr values such that we see dependend
2983 attributes after their dependencies. As we use a stack via the
2984 next pointers start from the end of the topological order. */
2985 topnum
= get_attr_order (&topsort
);
2986 for (i
= topnum
- 1; i
>= 0; i
--)
2987 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
2988 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2990 iv
->attr
= topsort
[i
];
2993 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2994 insn_code_values
[ie
->def
->insn_code
] = iv
;
2999 /* Sanity check on num_insn_ents. */
3000 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
3002 /* Process one insn code at a time. */
3003 for (i
= -2; i
< insn_code_number
; i
++)
3005 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3006 We use it to mean "already simplified for this insn". */
3007 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3008 clear_struct_flag (iv
->av
->value
);
3010 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3012 struct obstack
*old
= rtl_obstack
;
3017 if (GET_CODE (av
->value
) != COND
)
3020 rtl_obstack
= temp_obstack
;
3022 while (GET_CODE (newexp
) == COND
)
3024 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
3025 ie
->def
->insn_index
);
3026 if (newexp2
== newexp
)
3032 /* If we created a new value for this instruction, and it's
3033 cheaper than the old value, and overall cheap, use that
3034 one as specific value for the current instruction.
3035 The last test is to avoid exploding the get_attr_ function
3036 sizes for no much gain. */
3037 if (newexp
!= av
->value
3038 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
3039 && attr_rtx_cost (newexp
) < 26
3042 newexp
= attr_copy_rtx (newexp
);
3043 remove_insn_ent (av
, ie
);
3044 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
3046 insert_insn_ent (av
, ie
);
3052 free (insn_code_values
- 2);
3053 insn_code_values
= NULL
;
3056 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3059 clear_struct_flag (rtx x
)
3066 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3067 if (ATTR_IND_SIMPLIFIED_P (x
))
3070 code
= GET_CODE (x
);
3089 /* Compare the elements. If any pair of corresponding elements
3090 fail to match, return 0 for the whole things. */
3092 fmt
= GET_RTX_FORMAT (code
);
3093 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3099 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3100 clear_struct_flag (XVECEXP (x
, i
, j
));
3104 clear_struct_flag (XEXP (x
, i
));
3110 /* Add attribute value NAME to the beginning of ATTR's list. */
3113 add_attr_value (struct attr_desc
*attr
, const char *name
)
3115 struct attr_value
*av
;
3117 av
= oballoc (struct attr_value
);
3118 av
->value
= attr_rtx (CONST_STRING
, name
);
3119 av
->next
= attr
->first_value
;
3120 attr
->first_value
= av
;
3121 av
->first_insn
= NULL
;
3123 av
->has_asm_insn
= 0;
3126 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3129 gen_attr (rtx exp
, int lineno
)
3131 struct enum_type
*et
;
3132 struct enum_value
*ev
;
3133 struct attr_desc
*attr
;
3134 const char *name_ptr
;
3137 /* Make a new attribute structure. Check for duplicate by looking at
3138 attr->default_val, since it is initialized by this routine. */
3139 attr
= find_attr (&XSTR (exp
, 0), 1);
3140 if (attr
->default_val
)
3142 error_with_line (lineno
, "duplicate definition for attribute %s",
3144 message_at (attr
->loc
, "previous definition");
3147 attr
->loc
= file_location (read_md_filename
, lineno
);
3149 if (GET_CODE (exp
) == DEFINE_ENUM_ATTR
)
3151 attr
->enum_name
= XSTR (exp
, 1);
3152 et
= lookup_enum_type (XSTR (exp
, 1));
3153 if (!et
|| !et
->md_p
)
3154 error_with_line (lineno
, "No define_enum called `%s' defined",
3157 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3158 add_attr_value (attr
, ev
->name
);
3160 else if (*XSTR (exp
, 1) == '\0')
3161 attr
->is_numeric
= 1;
3164 name_ptr
= XSTR (exp
, 1);
3165 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3166 add_attr_value (attr
, p
);
3169 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3172 if (attr
->is_numeric
)
3173 error_with_line (lineno
,
3174 "constant attributes may not take numeric values");
3176 /* Get rid of the CONST node. It is allowed only at top-level. */
3177 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3180 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3181 error_with_line (lineno
, "`length' attribute must take numeric values");
3183 /* Set up the default value. */
3184 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3185 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3188 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3189 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3190 number of alternatives as this should be checked elsewhere. */
3193 count_alternatives (rtx exp
)
3198 if (GET_CODE (exp
) == MATCH_OPERAND
)
3199 return n_comma_elts (XSTR (exp
, 2));
3201 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3202 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3207 n
= count_alternatives (XEXP (exp
, i
));
3214 if (XVEC (exp
, i
) != NULL
)
3215 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3217 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3226 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3227 `alternative' attribute. */
3230 compares_alternatives_p (rtx exp
)
3235 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3238 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3239 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3244 if (compares_alternatives_p (XEXP (exp
, i
)))
3249 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3250 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3258 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3261 gen_insn (rtx exp
, int lineno
)
3263 struct insn_def
*id
;
3265 id
= oballoc (struct insn_def
);
3269 id
->loc
= file_location (read_md_filename
, lineno
);
3271 switch (GET_CODE (exp
))
3274 id
->insn_code
= insn_code_number
;
3275 id
->insn_index
= insn_index_number
;
3276 id
->num_alternatives
= count_alternatives (exp
);
3277 if (id
->num_alternatives
== 0)
3278 id
->num_alternatives
= 1;
3282 case DEFINE_PEEPHOLE
:
3283 id
->insn_code
= insn_code_number
;
3284 id
->insn_index
= insn_index_number
;
3285 id
->num_alternatives
= count_alternatives (exp
);
3286 if (id
->num_alternatives
== 0)
3287 id
->num_alternatives
= 1;
3291 case DEFINE_ASM_ATTRIBUTES
:
3293 id
->insn_index
= -1;
3294 id
->num_alternatives
= 1;
3296 got_define_asm_attributes
= 1;
3304 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3305 true or annul false is specified, and make a `struct delay_desc'. */
3308 gen_delay (rtx def
, int lineno
)
3310 struct delay_desc
*delay
;
3313 if (XVECLEN (def
, 1) % 3 != 0)
3315 error_with_line (lineno
,
3316 "number of elements in DEFINE_DELAY must"
3317 " be multiple of three");
3321 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3323 if (XVECEXP (def
, 1, i
+ 1))
3324 have_annul_true
= 1;
3325 if (XVECEXP (def
, 1, i
+ 2))
3326 have_annul_false
= 1;
3329 delay
= oballoc (struct delay_desc
);
3331 delay
->num
= ++num_delays
;
3332 delay
->next
= delays
;
3333 delay
->loc
= file_location (read_md_filename
, lineno
);
3337 /* Names of attributes that could be possibly cached. */
3338 static const char *cached_attrs
[32];
3339 /* Number of such attributes. */
3340 static int cached_attr_count
;
3341 /* Bitmasks of possibly cached attributes. */
3342 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3343 static unsigned int attrs_to_cache
;
3344 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3346 /* Finds non-const attributes that could be possibly cached.
3347 When create is TRUE, fills in cached_attrs array.
3348 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3352 find_attrs_to_cache (rtx exp
, bool create
)
3356 struct attr_desc
*attr
;
3361 switch (GET_CODE (exp
))
3364 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3365 find_attrs_to_cache (XEXP (exp
, 0), create
);
3369 name
= XSTR (exp
, 0);
3370 if (name
== alternative_name
)
3372 for (i
= 0; i
< cached_attr_count
; i
++)
3373 if (name
== cached_attrs
[i
])
3375 if ((attrs_seen_once
& (1U << i
)) != 0)
3376 attrs_seen_more_than_once
|= (1U << i
);
3378 attrs_seen_once
|= (1U << i
);
3383 attr
= find_attr (&name
, 0);
3387 if (cached_attr_count
== 32)
3389 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3390 attrs_seen_once
|= (1U << cached_attr_count
);
3391 cached_attr_count
++;
3396 find_attrs_to_cache (XEXP (exp
, 0), create
);
3397 find_attrs_to_cache (XEXP (exp
, 1), create
);
3401 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3402 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3410 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3411 We use AND and IOR both for logical and bit-wise operations, so
3412 interpret them as logical unless they are inside a comparison expression. */
3414 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3415 #define FLG_BITWISE 1
3416 /* Set if cached attribute will be known initialized in else block after
3417 this condition. This is true for LHS of toplevel && and || and
3418 even for RHS of ||, but not for RHS of &&. */
3420 /* Set if cached attribute will be known initialized in then block after
3421 this condition. This is true for LHS of toplevel && and || and
3422 even for RHS of &&, but not for RHS of ||. */
3423 #define FLG_INSIDE 4
3424 /* Cleared when an operand of &&. */
3425 #define FLG_OUTSIDE_AND 8
3428 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
)
3430 int comparison_operator
= 0;
3432 struct attr_desc
*attr
;
3434 /* In order not to worry about operator precedence, surround our part of
3435 the expression with parentheses. */
3437 fprintf (outf
, "(");
3438 code
= GET_CODE (exp
);
3441 /* Binary operators. */
3444 fprintf (outf
, "(unsigned) ");
3450 comparison_operator
= FLG_BITWISE
;
3452 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3453 case AND
: case IOR
: case XOR
:
3454 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3455 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3457 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3458 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3459 flags
| comparison_operator
);
3464 flags
&= ~FLG_OUTSIDE_AND
;
3465 if (GET_CODE (XEXP (exp
, 0)) == code
3466 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3467 || (GET_CODE (XEXP (exp
, 0)) == NOT
3468 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3470 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3472 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3477 fprintf (outf
, " == ");
3480 fprintf (outf
, " != ");
3483 fprintf (outf
, " >= ");
3486 fprintf (outf
, " > ");
3489 fprintf (outf
, " >= (unsigned) ");
3492 fprintf (outf
, " > (unsigned) ");
3495 fprintf (outf
, " <= ");
3498 fprintf (outf
, " < ");
3501 fprintf (outf
, " <= (unsigned) ");
3504 fprintf (outf
, " < (unsigned) ");
3507 fprintf (outf
, " + ");
3510 fprintf (outf
, " - ");
3513 fprintf (outf
, " * ");
3516 fprintf (outf
, " / ");
3519 fprintf (outf
, " %% ");
3522 if (flags
& FLG_BITWISE
)
3523 fprintf (outf
, " & ");
3525 fprintf (outf
, " && ");
3528 if (flags
& FLG_BITWISE
)
3529 fprintf (outf
, " | ");
3531 fprintf (outf
, " || ");
3534 fprintf (outf
, " ^ ");
3537 fprintf (outf
, " << ");
3541 fprintf (outf
, " >> ");
3549 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3550 cached_x is only known to be initialized in then block. */
3551 flags
&= ~FLG_AFTER
;
3553 else if (code
== IOR
)
3555 if (flags
& FLG_OUTSIDE_AND
)
3556 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3557 cached_x is only known to be initialized in else block
3558 and else if conditions. */
3559 flags
&= ~FLG_INSIDE
;
3561 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3563 cached_x is not know to be initialized anywhere. */
3564 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3566 if ((code
== AND
|| code
== IOR
)
3567 && (GET_CODE (XEXP (exp
, 1)) == code
3568 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3569 || (GET_CODE (XEXP (exp
, 1)) == NOT
3570 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3572 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
);
3574 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3575 flags
| comparison_operator
);
3579 /* Special-case (not (eq_attrq "alternative" "x")) */
3580 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3582 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3584 fprintf (outf
, "which_alternative != %s",
3585 XSTR (XEXP (exp
, 0), 1));
3589 fprintf (outf
, "! ");
3591 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3595 /* Otherwise, fall through to normal unary operator. */
3597 /* Unary operators. */
3602 if (flags
& FLG_BITWISE
)
3603 fprintf (outf
, "~ ");
3605 fprintf (outf
, "! ");
3608 fprintf (outf
, "abs ");
3611 fprintf (outf
, "-");
3617 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3618 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3623 int set
= XINT (exp
, 0), bit
= 0;
3625 if (flags
& FLG_BITWISE
)
3626 fatal ("EQ_ATTR_ALT not valid inside comparison");
3629 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3631 if (!(set
& (set
- 1)))
3633 if (!(set
& 0xffff))
3656 fprintf (outf
, "which_alternative %s= %d",
3657 XINT (exp
, 1) ? "!" : "=", bit
);
3661 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3662 XINT (exp
, 1) ? "!" : "", set
);
3667 /* Comparison test of an attribute with a value. Most of these will
3668 have been removed by optimization. Handle "alternative"
3669 specially and give error if EQ_ATTR present inside a comparison. */
3671 if (flags
& FLG_BITWISE
)
3672 fatal ("EQ_ATTR not valid inside comparison");
3674 if (XSTR (exp
, 0) == alternative_name
)
3676 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3680 attr
= find_attr (&XSTR (exp
, 0), 0);
3683 /* Now is the time to expand the value of a constant attribute. */
3686 write_test_expr (outf
,
3687 evaluate_eq_attr (exp
, attr
,
3688 attr
->default_val
->value
,
3695 for (i
= 0; i
< cached_attr_count
; i
++)
3696 if (attr
->name
== cached_attrs
[i
])
3698 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3699 fprintf (outf
, "cached_%s", attr
->name
);
3700 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3702 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3703 attr
->name
, attr
->name
);
3704 if (flags
& FLG_AFTER
)
3705 attrs_cached_after
|= (1U << i
);
3706 if (flags
& FLG_INSIDE
)
3707 attrs_cached_inside
|= (1U << i
);
3708 attrs_cached
|= (1U << i
);
3711 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3712 fprintf (outf
, " == ");
3713 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3717 /* Comparison test of flags for define_delays. */
3719 if (flags
& FLG_BITWISE
)
3720 fatal ("ATTR_FLAG not valid inside comparison");
3721 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3724 /* See if an operand matches a predicate. */
3726 /* If only a mode is given, just ensure the mode matches the operand.
3727 If neither a mode nor predicate is given, error. */
3728 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3730 if (GET_MODE (exp
) == VOIDmode
)
3731 fatal ("null MATCH_OPERAND specified as test");
3733 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3734 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3737 fprintf (outf
, "%s (operands[%d], %smode)",
3738 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3741 /* Constant integer. */
3743 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3747 fprint_c_condition (outf
, XSTR (exp
, 0));
3748 if (flags
& FLG_BITWISE
)
3749 fprintf (outf
, " != 0");
3752 /* A random C expression. */
3754 fprint_c_condition (outf
, XSTR (exp
, 0));
3757 /* The address of the branch target. */
3760 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3761 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3765 /* The address of the current insn. We implement this actually as the
3766 address of the current insn for backward branches, but the last
3767 address of the next insn for forward branches, and both with
3768 adjustments that account for the worst-case possible stretching of
3769 intervening alignments between this insn and its destination. */
3770 fprintf (outf
, "insn_current_reference_address (insn)");
3774 fprintf (outf
, "%s", XSTR (exp
, 0));
3778 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3779 fprintf (outf
, " ? ");
3780 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3781 fprintf (outf
, " : ");
3782 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3786 fatal ("bad RTX code `%s' in attribute calculation\n",
3787 GET_RTX_NAME (code
));
3790 fprintf (outf
, ")");
3791 return attrs_cached
;
3794 /* Given an attribute value, return the maximum CONST_STRING argument
3795 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3798 max_attr_value (rtx exp
, int *unknownp
)
3803 switch (GET_CODE (exp
))
3806 current_max
= atoi (XSTR (exp
, 0));
3810 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3811 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3813 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3814 if (n
> current_max
)
3820 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3821 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3822 if (n
> current_max
)
3828 current_max
= INT_MAX
;
3835 /* Given an attribute value, return the minimum CONST_STRING argument
3836 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3839 min_attr_value (rtx exp
, int *unknownp
)
3844 switch (GET_CODE (exp
))
3847 current_min
= atoi (XSTR (exp
, 0));
3851 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3852 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3854 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3855 if (n
< current_min
)
3861 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3862 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3863 if (n
< current_min
)
3869 current_min
= INT_MAX
;
3876 /* Given an attribute value, return the result of ORing together all
3877 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3878 if the numeric value is not known. */
3881 or_attr_value (rtx exp
, int *unknownp
)
3886 switch (GET_CODE (exp
))
3889 current_or
= atoi (XSTR (exp
, 0));
3893 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3894 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3895 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3899 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3900 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3912 /* Scan an attribute value, possibly a conditional, and record what actions
3913 will be required to do any conditional tests in it.
3916 `must_extract' if we need to extract the insn operands
3917 `must_constrain' if we must compute `which_alternative'
3918 `address_used' if an address expression was used
3919 `length_used' if an (eq_attr "length" ...) was used
3923 walk_attr_value (rtx exp
)
3932 code
= GET_CODE (exp
);
3936 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3937 /* Since this is an arbitrary expression, it can look at anything.
3938 However, constant expressions do not depend on any particular
3940 must_extract
= must_constrain
= 1;
3949 must_extract
= must_constrain
= 1;
3953 if (XSTR (exp
, 0) == alternative_name
)
3954 must_extract
= must_constrain
= 1;
3955 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3975 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3980 walk_attr_value (XEXP (exp
, i
));
3984 if (XVEC (exp
, i
) != NULL
)
3985 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3986 walk_attr_value (XVECEXP (exp
, i
, j
));
3991 /* Write out a function to obtain the attribute for a given INSN. */
3994 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
3996 struct attr_value
*av
, *common_av
;
3999 /* Find the most used attribute value. Handle that as the `default' of the
4000 switch we will generate. */
4001 common_av
= find_most_used (attr
);
4003 /* Write out start of function, then all values with explicit `case' lines,
4004 then a `default', then the value with the most uses. */
4005 if (attr
->enum_name
)
4006 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4007 else if (!attr
->is_numeric
)
4008 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4010 fprintf (outf
, "int\n");
4012 /* If the attribute name starts with a star, the remainder is the name of
4013 the subroutine to use, instead of `get_attr_...'. */
4014 if (attr
->name
[0] == '*')
4015 fprintf (outf
, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4016 else if (attr
->is_const
== 0)
4017 fprintf (outf
, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4020 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4021 fprintf (outf
, "{\n");
4023 for (av
= attr
->first_value
; av
; av
= av
->next
)
4024 if (av
->num_insns
== 1)
4025 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4026 true_rtx
, av
->first_insn
->def
->insn_code
,
4027 av
->first_insn
->def
->insn_index
, 0);
4028 else if (av
->num_insns
!= 0)
4029 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4030 true_rtx
, -2, 0, 0);
4032 fprintf (outf
, "}\n\n");
4036 fprintf (outf
, "{\n");
4038 /* Find attributes that are worth caching in the conditions. */
4039 cached_attr_count
= 0;
4040 attrs_seen_more_than_once
= 0;
4041 for (av
= attr
->first_value
; av
; av
= av
->next
)
4043 attrs_seen_once
= 0;
4044 find_attrs_to_cache (av
->value
, true);
4046 /* Remove those that aren't worth caching from the array. */
4047 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4048 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4050 const char *name
= cached_attrs
[i
];
4051 struct attr_desc
*cached_attr
;
4053 cached_attrs
[j
] = name
;
4054 cached_attr
= find_attr (&name
, 0);
4055 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4056 if (cached_attr
->enum_name
)
4057 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4058 else if (!cached_attr
->is_numeric
)
4059 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4061 fprintf (outf
, " int");
4062 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4065 cached_attr_count
= j
;
4066 if (cached_attr_count
)
4067 fprintf (outf
, "\n");
4069 fprintf (outf
, " switch (recog_memoized (insn))\n");
4070 fprintf (outf
, " {\n");
4072 for (av
= attr
->first_value
; av
; av
= av
->next
)
4073 if (av
!= common_av
)
4074 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4076 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4077 fprintf (outf
, " }\n}\n\n");
4078 cached_attr_count
= 0;
4081 /* Given an AND tree of known true terms (because we are inside an `if' with
4082 that as the condition or are in an `else' clause) and an expression,
4083 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4084 the bulk of the work. */
4087 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4091 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4093 if (GET_CODE (known_true
) == AND
)
4095 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4096 insn_code
, insn_index
);
4097 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4098 insn_code
, insn_index
);
4103 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4109 /* Write out a series of tests and assignment statements to perform tests and
4110 sets of an attribute value. We are passed an indentation amount and prefix
4111 and suffix strings to write around each attribute value (e.g., "return"
4115 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
4116 const char *prefix
, const char *suffix
, rtx known_true
,
4117 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4119 if (GET_CODE (value
) == COND
)
4121 /* Assume the default value will be the default of the COND unless we
4122 find an always true expression. */
4123 rtx default_val
= XEXP (value
, 1);
4124 rtx our_known_true
= known_true
;
4129 if (cached_attr_count
)
4131 attrs_seen_once
= 0;
4132 attrs_seen_more_than_once
= 0;
4133 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4134 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4135 attrs_to_cache
|= attrs_seen_more_than_once
;
4138 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4143 /* Reset our_known_true after some time to not accumulate
4144 too much cruft (slowing down genattrtab). */
4146 our_known_true
= known_true
;
4147 testexp
= eliminate_known_true (our_known_true
,
4148 XVECEXP (value
, 0, i
),
4149 insn_code
, insn_index
);
4150 newexp
= attr_rtx (NOT
, testexp
);
4151 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4152 insn_code
, insn_index
);
4154 /* If the test expression is always true or if the next `known_true'
4155 expression is always false, this is the last case, so break
4156 out and let this value be the `else' case. */
4157 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4159 default_val
= XVECEXP (value
, 0, i
+ 1);
4163 /* Compute the expression to pass to our recursive call as being
4165 inner_true
= insert_right_side (AND
, our_known_true
,
4166 testexp
, insn_code
, insn_index
);
4168 /* If this is always false, skip it. */
4169 if (inner_true
== false_rtx
)
4172 attrs_cached_inside
= attrs_cached
;
4173 attrs_cached_after
= attrs_cached
;
4174 write_indent (outf
, indent
);
4175 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4177 write_test_expr (outf
, testexp
, attrs_cached
,
4178 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4179 attrs_cached
= attrs_cached_after
;
4180 fprintf (outf
, "\n");
4181 write_indent (outf
, indent
+ 2);
4182 fprintf (outf
, "{\n");
4184 write_attr_set (outf
, attr
, indent
+ 4,
4185 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4186 inner_true
, insn_code
, insn_index
,
4187 attrs_cached_inside
);
4188 write_indent (outf
, indent
+ 2);
4189 fprintf (outf
, "}\n");
4190 our_known_true
= newexp
;
4195 write_indent (outf
, indent
);
4196 fprintf (outf
, "else\n");
4197 write_indent (outf
, indent
+ 2);
4198 fprintf (outf
, "{\n");
4201 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4202 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4207 write_indent (outf
, indent
+ 2);
4208 fprintf (outf
, "}\n");
4213 write_indent (outf
, indent
);
4214 fprintf (outf
, "%s ", prefix
);
4215 write_attr_value (outf
, attr
, value
);
4216 fprintf (outf
, "%s\n", suffix
);
4220 /* Write a series of case statements for every instruction in list IE.
4221 INDENT is the amount of indentation to write before each case. */
4224 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4226 for (; ie
!= 0; ie
= ie
->next
)
4227 if (ie
->def
->insn_code
!= -1)
4229 write_indent (outf
, indent
);
4230 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4231 fprintf (outf
, "case %d: /* define_peephole, %s:%d */\n",
4232 ie
->def
->insn_code
, ie
->def
->loc
.filename
,
4233 ie
->def
->loc
.lineno
);
4235 fprintf (outf
, "case %d: /* %s */\n",
4236 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4240 /* Write out the computation for one attribute value. */
4243 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4244 int write_case_lines
, const char *prefix
, const char *suffix
,
4245 int indent
, rtx known_true
)
4247 if (av
->num_insns
== 0)
4250 if (av
->has_asm_insn
)
4252 write_indent (outf
, indent
);
4253 fprintf (outf
, "case -1:\n");
4254 write_indent (outf
, indent
+ 2);
4255 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4256 write_indent (outf
, indent
+ 2);
4257 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4258 write_indent (outf
, indent
+ 2);
4259 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4262 if (write_case_lines
)
4263 write_insn_cases (outf
, av
->first_insn
, indent
);
4266 write_indent (outf
, indent
);
4267 fprintf (outf
, "default:\n");
4270 /* See what we have to do to output this value. */
4271 must_extract
= must_constrain
= address_used
= 0;
4272 walk_attr_value (av
->value
);
4276 write_indent (outf
, indent
+ 2);
4277 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4279 else if (must_extract
)
4281 write_indent (outf
, indent
+ 2);
4282 fprintf (outf
, "extract_insn_cached (insn);\n");
4286 if (av
->num_insns
== 1)
4287 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4288 known_true
, av
->first_insn
->def
->insn_code
,
4289 av
->first_insn
->def
->insn_index
, 0);
4291 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4292 known_true
, -2, 0, 0);
4294 if (strncmp (prefix
, "return", 6))
4296 write_indent (outf
, indent
+ 2);
4297 fprintf (outf
, "break;\n");
4299 fprintf (outf
, "\n");
4302 /* Utilities to write in various forms. */
4305 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4307 if (attr
->is_numeric
)
4311 fprintf (outf
, "%d", num
);
4313 if (num
> 9 || num
< 0)
4314 fprintf (outf
, " /* %#x */", num
);
4318 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4319 fprintf (outf
, "_");
4320 write_upcase (outf
, s
);
4325 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4329 switch (GET_CODE (value
))
4332 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4336 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4340 fprint_c_condition (outf
, XSTR (value
, 0));
4345 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4346 if (attr
->enum_name
)
4347 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4348 else if (!attr
->is_numeric
)
4349 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4350 else if (!attr2
->is_numeric
)
4351 fprintf (outf
, "(int)");
4353 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4354 (attr2
->is_const
? "" : "insn"));
4375 write_attr_value (outf
, attr
, XEXP (value
, 0));
4379 write_attr_value (outf
, attr
, XEXP (value
, 1));
4388 write_upcase (FILE *outf
, const char *str
)
4392 /* The argument of TOUPPER should not have side effects. */
4393 fputc (TOUPPER (*str
), outf
);
4399 write_indent (FILE *outf
, int indent
)
4401 for (; indent
> 8; indent
-= 8)
4402 fprintf (outf
, "\t");
4404 for (; indent
; indent
--)
4405 fprintf (outf
, " ");
4408 /* Write a subroutine that is given an insn that requires a delay slot, a
4409 delay slot ordinal, and a candidate insn. It returns nonzero if the
4410 candidate can be placed in the specified delay slot of the insn.
4412 We can write as many as three subroutines. `eligible_for_delay'
4413 handles normal delay slots, `eligible_for_annul_true' indicates that
4414 the specified insn can be annulled if the branch is true, and likewise
4415 for `eligible_for_annul_false'.
4417 KIND is a string distinguishing these three cases ("delay", "annul_true",
4418 or "annul_false"). */
4421 write_eligible_delay (FILE *outf
, const char *kind
)
4423 struct delay_desc
*delay
;
4427 struct attr_desc
*attr
;
4428 struct attr_value
*av
, *common_av
;
4431 /* Compute the maximum number of delay slots required. We use the delay
4432 ordinal times this number plus one, plus the slot number as an index into
4433 the appropriate predicate to test. */
4435 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4436 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4437 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4439 /* Write function prelude. */
4441 fprintf (outf
, "int\n");
4442 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4443 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4445 fprintf (outf
, "{\n");
4446 fprintf (outf
, " rtx_insn *insn;\n");
4447 fprintf (outf
, "\n");
4448 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4449 fprintf (outf
, "\n");
4450 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4451 converts a compound instruction into a loop. */
4452 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4453 fprintf (outf
, " return 0;\n");
4454 fprintf (outf
, "\n");
4456 /* If more than one delay type, find out which type the delay insn is. */
4460 attr
= find_attr (&delay_type_str
, 0);
4462 common_av
= find_most_used (attr
);
4464 fprintf (outf
, " insn = delay_insn;\n");
4465 fprintf (outf
, " switch (recog_memoized (insn))\n");
4466 fprintf (outf
, " {\n");
4468 sprintf (str
, " * %d;\n break;", max_slots
);
4469 for (av
= attr
->first_value
; av
; av
= av
->next
)
4470 if (av
!= common_av
)
4471 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4473 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4474 fprintf (outf
, " }\n\n");
4476 /* Ensure matched. Otherwise, shouldn't have been called. */
4477 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4480 /* If just one type of delay slot, write simple switch. */
4481 if (num_delays
== 1 && max_slots
== 1)
4483 fprintf (outf
, " insn = candidate_insn;\n");
4484 fprintf (outf
, " switch (recog_memoized (insn))\n");
4485 fprintf (outf
, " {\n");
4487 attr
= find_attr (&delay_1_0_str
, 0);
4489 common_av
= find_most_used (attr
);
4491 for (av
= attr
->first_value
; av
; av
= av
->next
)
4492 if (av
!= common_av
)
4493 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4495 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4496 fprintf (outf
, " }\n");
4501 /* Write a nested CASE. The first indicates which condition we need to
4502 test, and the inner CASE tests the condition. */
4503 fprintf (outf
, " insn = candidate_insn;\n");
4504 fprintf (outf
, " switch (slot)\n");
4505 fprintf (outf
, " {\n");
4507 for (delay
= delays
; delay
; delay
= delay
->next
)
4508 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4510 fprintf (outf
, " case %d:\n",
4511 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4512 fprintf (outf
, " switch (recog_memoized (insn))\n");
4513 fprintf (outf
, "\t{\n");
4515 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4517 attr
= find_attr (&pstr
, 0);
4519 common_av
= find_most_used (attr
);
4521 for (av
= attr
->first_value
; av
; av
= av
->next
)
4522 if (av
!= common_av
)
4523 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4525 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4526 fprintf (outf
, " }\n");
4529 fprintf (outf
, " default:\n");
4530 fprintf (outf
, " gcc_unreachable ();\n");
4531 fprintf (outf
, " }\n");
4534 fprintf (outf
, "}\n\n");
4537 /* This page contains miscellaneous utility routines. */
4539 /* Given a pointer to a (char *), return a malloc'ed string containing the
4540 next comma-separated element. Advance the pointer to after the string
4541 scanned, or the end-of-string. Return NULL if at end of string. */
4544 next_comma_elt (const char **pstr
)
4548 start
= scan_comma_elt (pstr
);
4553 return attr_string (start
, *pstr
- start
);
4556 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4557 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4558 replaced by a pointer to a canonical copy of the string. */
4560 static struct attr_desc
*
4561 find_attr (const char **name_p
, int create
)
4563 struct attr_desc
*attr
;
4565 const char *name
= *name_p
;
4567 /* Before we resort to using `strcmp', see if the string address matches
4568 anywhere. In most cases, it should have been canonicalized to do so. */
4569 if (name
== alternative_name
)
4572 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4573 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4574 if (name
== attr
->name
)
4577 /* Otherwise, do it the slow way. */
4578 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4579 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4581 *name_p
= attr
->name
;
4588 attr
= oballoc (struct attr_desc
);
4589 attr
->name
= DEF_ATTR_STRING (name
);
4590 attr
->enum_name
= 0;
4591 attr
->first_value
= attr
->default_val
= NULL
;
4592 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4593 attr
->next
= attrs
[index
];
4594 attrs
[index
] = attr
;
4596 *name_p
= attr
->name
;
4601 /* Create internal attribute with the given default value. */
4604 make_internal_attr (const char *name
, rtx value
, int special
)
4606 struct attr_desc
*attr
;
4608 attr
= find_attr (&name
, 1);
4609 gcc_assert (!attr
->default_val
);
4611 attr
->is_numeric
= 1;
4613 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4614 attr
->default_val
= get_attr_value (value
, attr
, -2);
4617 /* Find the most used value of an attribute. */
4619 static struct attr_value
*
4620 find_most_used (struct attr_desc
*attr
)
4622 struct attr_value
*av
;
4623 struct attr_value
*most_used
;
4629 for (av
= attr
->first_value
; av
; av
= av
->next
)
4630 if (av
->num_insns
> nuses
)
4631 nuses
= av
->num_insns
, most_used
= av
;
4636 /* Return (attr_value "n") */
4639 make_numeric_value (int n
)
4641 static rtx int_values
[20];
4645 gcc_assert (n
>= 0);
4647 if (n
< 20 && int_values
[n
])
4648 return int_values
[n
];
4650 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4651 exp
= attr_rtx (CONST_STRING
, p
);
4654 int_values
[n
] = exp
;
4660 copy_rtx_unchanging (rtx orig
)
4662 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4665 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4669 /* Determine if an insn has a constant number of delay slots, i.e., the
4670 number of delay slots is not a function of the length of the insn. */
4673 write_const_num_delay_slots (FILE *outf
)
4675 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4676 struct attr_value
*av
;
4680 fprintf (outf
, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4681 fprintf (outf
, "{\n");
4682 fprintf (outf
, " switch (recog_memoized (insn))\n");
4683 fprintf (outf
, " {\n");
4685 for (av
= attr
->first_value
; av
; av
= av
->next
)
4688 walk_attr_value (av
->value
);
4690 write_insn_cases (outf
, av
->first_insn
, 4);
4693 fprintf (outf
, " default:\n");
4694 fprintf (outf
, " return 1;\n");
4695 fprintf (outf
, " }\n}\n\n");
4699 /* Synthetic attributes used by insn-automata.c and the scheduler.
4700 These are primarily concerned with (define_insn_reservation)
4705 struct insn_reserv
*next
;
4708 int default_latency
;
4711 /* Sequence number of this insn. */
4714 /* Whether a (define_bypass) construct names this insn in its
4719 static struct insn_reserv
*all_insn_reservs
= 0;
4720 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4721 static size_t n_insn_reservs
;
4723 /* Store information from a DEFINE_INSN_RESERVATION for future
4724 attribute generation. */
4726 gen_insn_reserv (rtx def
, int lineno
)
4728 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4729 file_location
loc (read_md_filename
, lineno
);
4731 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4732 decl
->default_latency
= XINT (def
, 1);
4733 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, loc
);
4734 decl
->insn_num
= n_insn_reservs
;
4735 decl
->bypassed
= false;
4738 *last_insn_reserv_p
= decl
;
4739 last_insn_reserv_p
= &decl
->next
;
4743 /* Store information from a DEFINE_BYPASS for future attribute
4744 generation. The only thing we care about is the list of output
4745 insns, which will later be used to tag reservation structures with
4746 a 'bypassed' bit. */
4750 struct bypass_list
*next
;
4751 const char *pattern
;
4754 static struct bypass_list
*all_bypasses
;
4755 static size_t n_bypasses
;
4756 static size_t n_bypassed
;
4759 gen_bypass_1 (const char *s
, size_t len
)
4761 struct bypass_list
*b
;
4766 s
= attr_string (s
, len
);
4767 for (b
= all_bypasses
; b
; b
= b
->next
)
4768 if (s
== b
->pattern
)
4769 return; /* already got that one */
4771 b
= oballoc (struct bypass_list
);
4773 b
->next
= all_bypasses
;
4779 gen_bypass (rtx def
)
4781 const char *p
, *base
;
4783 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4786 gen_bypass_1 (base
, p
- base
);
4789 while (ISSPACE (*p
));
4792 gen_bypass_1 (base
, p
- base
);
4795 /* Find and mark all of the bypassed insns. */
4797 process_bypasses (void)
4799 struct bypass_list
*b
;
4800 struct insn_reserv
*r
;
4804 /* The reservation list is likely to be much longer than the bypass
4806 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4807 for (b
= all_bypasses
; b
; b
= b
->next
)
4808 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4816 /* Check that attribute NAME is used in define_insn_reservation condition
4817 EXP. Return true if it is. */
4819 check_tune_attr (const char *name
, rtx exp
)
4821 switch (GET_CODE (exp
))
4824 if (check_tune_attr (name
, XEXP (exp
, 0)))
4826 return check_tune_attr (name
, XEXP (exp
, 1));
4829 return (check_tune_attr (name
, XEXP (exp
, 0))
4830 && check_tune_attr (name
, XEXP (exp
, 1)));
4833 return XSTR (exp
, 0) == name
;
4840 /* Try to find a const attribute (usually cpu or tune) that is used
4841 in all define_insn_reservation conditions. */
4842 static struct attr_desc
*
4843 find_tune_attr (rtx exp
)
4845 struct attr_desc
*attr
;
4847 switch (GET_CODE (exp
))
4851 attr
= find_tune_attr (XEXP (exp
, 0));
4854 return find_tune_attr (XEXP (exp
, 1));
4857 if (XSTR (exp
, 0) == alternative_name
)
4860 attr
= find_attr (&XSTR (exp
, 0), 0);
4863 if (attr
->is_const
&& !attr
->is_special
)
4865 struct insn_reserv
*decl
;
4867 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4868 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4879 /* Create all of the attributes that describe automaton properties.
4880 Write the DFA and latency function prototypes to the files that
4881 need to have them, and write the init_sched_attrs(). */
4884 make_automaton_attrs (void)
4887 struct insn_reserv
*decl
;
4888 rtx code_exp
, lats_exp
, byps_exp
;
4889 struct attr_desc
*tune_attr
;
4891 if (n_insn_reservs
== 0)
4894 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4895 if (tune_attr
!= NULL
)
4897 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4898 struct attr_value
*val
;
4901 gcc_assert (tune_attr
->is_const
4902 && !tune_attr
->is_special
4903 && !tune_attr
->is_numeric
);
4905 /* Write the prototypes for all DFA functions. */
4906 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4908 if (val
== tune_attr
->default_val
)
4910 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4912 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4913 XSTR (val
->value
, 0));
4915 fprintf (dfa_file
, "\n");
4917 /* Write the prototypes for all latency functions. */
4918 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4920 if (val
== tune_attr
->default_val
)
4922 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4923 fprintf (latency_file
,
4924 "extern int insn_default_latency_%s (rtx_insn *);\n",
4925 XSTR (val
->value
, 0));
4927 fprintf (latency_file
, "\n");
4929 /* Write the prototypes for all automaton functions. */
4930 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4932 if (val
== tune_attr
->default_val
)
4934 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4936 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4937 "extern int insn_default_latency_%s (rtx_insn *);\n",
4938 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4940 fprintf (attr_file
, "\n");
4941 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4942 fprintf (attr_file
, "int (*insn_default_latency) (rtx_insn *);\n");
4943 fprintf (attr_file
, "\n");
4944 fprintf (attr_file
, "void\n");
4945 fprintf (attr_file
, "init_sched_attrs (void)\n");
4946 fprintf (attr_file
, "{\n");
4948 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4952 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
4954 if (val
== tune_attr
->default_val
)
4956 for (decl
= all_insn_reservs
, i
= 0;
4962 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
4963 if (condexp
== false_rtx
)
4965 if (condexp
== true_rtx
)
4967 condexps
[i
] = condexp
;
4968 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
4969 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
4973 code_exp
= rtx_alloc (COND
);
4974 lats_exp
= rtx_alloc (COND
);
4977 XVEC (code_exp
, 0) = rtvec_alloc (j
);
4978 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
4982 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
4983 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
4987 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4988 XEXP (lats_exp
, 1) = make_numeric_value (0);
4995 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
4996 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
4998 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
4999 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5002 name
= XNEWVEC (char,
5003 sizeof ("*internal_dfa_insn_code_")
5004 + strlen (XSTR (val
->value
, 0)));
5005 strcpy (name
, "*internal_dfa_insn_code_");
5006 strcat (name
, XSTR (val
->value
, 0));
5007 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5008 strcpy (name
, "*insn_default_latency_");
5009 strcat (name
, XSTR (val
->value
, 0));
5010 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5015 fprintf (attr_file
, " if (");
5019 fprintf (attr_file
, " else if (");
5020 write_test_expr (attr_file
, test
, 0, 0);
5021 fprintf (attr_file
, ")\n");
5022 fprintf (attr_file
, " {\n");
5023 fprintf (attr_file
, " internal_dfa_insn_code\n");
5024 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5025 XSTR (val
->value
, 0));
5026 fprintf (attr_file
, " insn_default_latency\n");
5027 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5028 XSTR (val
->value
, 0));
5029 fprintf (attr_file
, " }\n");
5032 fprintf (attr_file
, " else\n");
5033 fprintf (attr_file
, " gcc_unreachable ();\n");
5034 fprintf (attr_file
, "}\n");
5035 fprintf (attr_file
, "\n");
5037 XDELETEVEC (condexps
);
5041 code_exp
= rtx_alloc (COND
);
5042 lats_exp
= rtx_alloc (COND
);
5044 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5045 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5047 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5048 XEXP (lats_exp
, 1) = make_numeric_value (0);
5050 for (decl
= all_insn_reservs
, i
= 0;
5052 decl
= decl
->next
, i
+= 2)
5054 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5055 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5057 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5058 XVECEXP (lats_exp
, 0, i
+1)
5059 = make_numeric_value (decl
->default_latency
);
5061 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5062 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5065 if (n_bypasses
== 0)
5066 byps_exp
= make_numeric_value (0);
5069 process_bypasses ();
5071 byps_exp
= rtx_alloc (COND
);
5072 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypassed
* 2);
5073 XEXP (byps_exp
, 1) = make_numeric_value (0);
5074 for (decl
= all_insn_reservs
, i
= 0;
5079 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5080 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5085 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5089 write_header (FILE *outf
)
5091 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5092 " from the machine description file `md'. */\n\n");
5094 fprintf (outf
, "#include \"config.h\"\n");
5095 fprintf (outf
, "#include \"system.h\"\n");
5096 fprintf (outf
, "#include \"coretypes.h\"\n");
5097 fprintf (outf
, "#include \"backend.h\"\n");
5098 fprintf (outf
, "#include \"predict.h\"\n");
5099 fprintf (outf
, "#include \"tree.h\"\n");
5100 fprintf (outf
, "#include \"rtl.h\"\n");
5101 fprintf (outf
, "#include \"alias.h\"\n");
5102 fprintf (outf
, "#include \"options.h\"\n");
5103 fprintf (outf
, "#include \"varasm.h\"\n");
5104 fprintf (outf
, "#include \"stor-layout.h\"\n");
5105 fprintf (outf
, "#include \"calls.h\"\n");
5106 fprintf (outf
, "#include \"insn-attr.h\"\n");
5107 fprintf (outf
, "#include \"tm_p.h\"\n");
5108 fprintf (outf
, "#include \"insn-config.h\"\n");
5109 fprintf (outf
, "#include \"recog.h\"\n");
5110 fprintf (outf
, "#include \"regs.h\"\n");
5111 fprintf (outf
, "#include \"real.h\"\n");
5112 fprintf (outf
, "#include \"output.h\"\n");
5113 fprintf (outf
, "#include \"toplev.h\"\n");
5114 fprintf (outf
, "#include \"flags.h\"\n");
5115 fprintf (outf
, "#include \"emit-rtl.h\"\n");
5116 fprintf (outf
, "\n");
5117 fprintf (outf
, "#define operands recog_data.operand\n\n");
5121 open_outfile (const char *file_name
)
5124 outf
= fopen (file_name
, "w");
5126 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5127 write_header (outf
);
5132 handle_arg (const char *arg
)
5137 attr_file_name
= &arg
[2];
5140 dfa_file_name
= &arg
[2];
5143 latency_file_name
= &arg
[2];
5151 main (int argc
, char **argv
)
5154 struct attr_desc
*attr
;
5155 struct insn_def
*id
;
5159 progname
= "genattrtab";
5161 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5162 return FATAL_EXIT_CODE
;
5164 attr_file
= open_outfile (attr_file_name
);
5165 dfa_file
= open_outfile (dfa_file_name
);
5166 latency_file
= open_outfile (latency_file_name
);
5168 obstack_init (hash_obstack
);
5169 obstack_init (temp_obstack
);
5171 /* Set up true and false rtx's */
5172 true_rtx
= rtx_alloc (CONST_INT
);
5173 XWINT (true_rtx
, 0) = 1;
5174 false_rtx
= rtx_alloc (CONST_INT
);
5175 XWINT (false_rtx
, 0) = 0;
5176 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5177 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5179 alternative_name
= DEF_ATTR_STRING ("alternative");
5180 length_str
= DEF_ATTR_STRING ("length");
5181 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5182 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5183 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5185 /* Read the machine description. */
5191 desc
= read_md_rtx (&lineno
, &insn_code_number
);
5195 switch (GET_CODE (desc
))
5198 case DEFINE_PEEPHOLE
:
5199 case DEFINE_ASM_ATTRIBUTES
:
5200 gen_insn (desc
, lineno
);
5204 case DEFINE_ENUM_ATTR
:
5205 gen_attr (desc
, lineno
);
5209 gen_delay (desc
, lineno
);
5212 case DEFINE_INSN_RESERVATION
:
5213 gen_insn_reserv (desc
, lineno
);
5223 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
5224 insn_index_number
++;
5228 return FATAL_EXIT_CODE
;
5232 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5233 if (! got_define_asm_attributes
)
5235 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5236 XVEC (tem
, 0) = rtvec_alloc (0);
5240 /* Expand DEFINE_DELAY information into new attribute. */
5244 /* Make `insn_alternatives'. */
5245 insn_alternatives
= oballocvec (uint64_t, insn_code_number
);
5246 for (id
= defs
; id
; id
= id
->next
)
5247 if (id
->insn_code
>= 0)
5248 insn_alternatives
[id
->insn_code
]
5249 = (((uint64_t) 1) << id
->num_alternatives
) - 1;
5251 /* Make `insn_n_alternatives'. */
5252 insn_n_alternatives
= oballocvec (int, insn_code_number
);
5253 for (id
= defs
; id
; id
= id
->next
)
5254 if (id
->insn_code
>= 0)
5255 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5257 /* Construct extra attributes for automata. */
5258 make_automaton_attrs ();
5260 /* Prepare to write out attribute subroutines by checking everything stored
5261 away and building the attribute cases. */
5265 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5266 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5267 attr
->default_val
->value
5268 = check_attr_value (attr
->default_val
->value
, attr
);
5271 return FATAL_EXIT_CODE
;
5273 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5274 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5277 /* Construct extra attributes for `length'. */
5278 make_length_attrs ();
5280 /* Perform any possible optimizations to speed up compilation. */
5283 /* Now write out all the `gen_attr_...' routines. Do these before the
5284 special routines so that they get defined before they are used. */
5286 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5287 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5291 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5292 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5294 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5295 outf
= latency_file
;
5298 #undef IS_ATTR_GROUP
5300 if (! attr
->is_special
&& ! attr
->is_const
)
5301 write_attr_get (outf
, attr
);
5304 /* Write out delay eligibility information, if DEFINE_DELAY present.
5305 (The function to compute the number of delay slots will be written
5309 write_eligible_delay (attr_file
, "delay");
5310 if (have_annul_true
)
5311 write_eligible_delay (attr_file
, "annul_true");
5312 if (have_annul_false
)
5313 write_eligible_delay (attr_file
, "annul_false");
5316 /* Write out constant delay slot info. */
5317 write_const_num_delay_slots (attr_file
);
5319 write_length_unit_log (attr_file
);
5321 if (fclose (attr_file
) != 0)
5322 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5323 if (fclose (dfa_file
) != 0)
5324 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5325 if (fclose (latency_file
) != 0)
5326 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5328 return SUCCESS_EXIT_CODE
;