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 const char *filename
; /* Filename. */
143 int lineno
; /* Line number. */
144 int num_alternatives
; /* Number of alternatives. */
145 int vec_idx
; /* Index of attribute vector in `def'. */
148 /* Once everything has been read in, we store in each attribute value a list
149 of insn codes that have that value. Here is the structure used for the
154 struct insn_ent
*next
; /* Next in chain. */
155 struct insn_def
*def
; /* Instruction definition. */
158 /* Each value of an attribute (either constant or computed) is assigned a
159 structure which is used as the listhead of the insns that have that
164 rtx value
; /* Value of attribute. */
165 struct attr_value
*next
; /* Next attribute value in chain. */
166 struct insn_ent
*first_insn
; /* First insn with this value. */
167 int num_insns
; /* Number of insns with this value. */
168 int has_asm_insn
; /* True if this value used for `asm' insns */
171 /* Structure for each attribute. */
175 char *name
; /* Name of attribute. */
176 const char *enum_name
; /* Enum name for DEFINE_ENUM_NAME. */
177 struct attr_desc
*next
; /* Next attribute. */
178 struct attr_value
*first_value
; /* First value of this attribute. */
179 struct attr_value
*default_val
; /* Default value for this attribute. */
180 int lineno
: 24; /* Line number. */
181 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
182 unsigned is_const
: 1; /* Attribute value constant for each run. */
183 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
186 /* Structure for each DEFINE_DELAY. */
190 rtx def
; /* DEFINE_DELAY expression. */
191 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
192 int num
; /* Number of DEFINE_DELAY, starting at 1. */
193 int lineno
; /* Line number. */
196 struct attr_value_list
198 struct attr_value
*av
;
200 struct attr_desc
*attr
;
201 struct attr_value_list
*next
;
204 /* Listheads of above structures. */
206 /* This one is indexed by the first character of the attribute name. */
207 #define MAX_ATTRS_INDEX 256
208 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
209 static struct insn_def
*defs
;
210 static struct delay_desc
*delays
;
211 struct attr_value_list
**insn_code_values
;
213 /* Other variables. */
215 static int insn_code_number
;
216 static int insn_index_number
;
217 static int got_define_asm_attributes
;
218 static int must_extract
;
219 static int must_constrain
;
220 static int address_used
;
221 static int length_used
;
222 static int num_delays
;
223 static int have_annul_true
, have_annul_false
;
224 static int num_insn_ents
;
226 /* Stores, for each insn code, the number of constraint alternatives. */
228 static int *insn_n_alternatives
;
230 /* Stores, for each insn code, a bitmap that has bits on for each possible
233 static uint64_t *insn_alternatives
;
235 /* Used to simplify expressions. */
237 static rtx true_rtx
, false_rtx
;
239 /* Used to reduce calls to `strcmp' */
241 static const char *alternative_name
;
242 static const char *length_str
;
243 static const char *delay_type_str
;
244 static const char *delay_1_0_str
;
245 static const char *num_delay_slots_str
;
247 /* Simplify an expression. Only call the routine if there is something to
249 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
250 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
251 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
253 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
255 /* Forward declarations of functions used before their definitions, only. */
256 static char *attr_string (const char *, int);
257 static char *attr_printf (unsigned int, const char *, ...)
259 static rtx
make_numeric_value (int);
260 static struct attr_desc
*find_attr (const char **, int);
261 static rtx
mk_attr_alt (uint64_t);
262 static char *next_comma_elt (const char **);
263 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
264 static rtx
copy_boolean (rtx
);
265 static int compares_alternatives_p (rtx
);
266 static void make_internal_attr (const char *, rtx
, int);
267 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
268 static void walk_attr_value (rtx
);
269 static int max_attr_value (rtx
, int*);
270 static int min_attr_value (rtx
, int*);
271 static int or_attr_value (rtx
, int*);
272 static rtx
simplify_test_exp (rtx
, int, int);
273 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
274 static rtx
copy_rtx_unchanging (rtx
);
275 static bool attr_alt_subset_p (rtx
, rtx
);
276 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
277 static void clear_struct_flag (rtx
);
278 static void write_attr_valueq (FILE *, struct attr_desc
*, const char *);
279 static struct attr_value
*find_most_used (struct attr_desc
*);
280 static void write_attr_set (FILE *, struct attr_desc
*, int, rtx
,
281 const char *, const char *, rtx
,
282 int, int, unsigned int);
283 static void write_attr_case (FILE *, struct attr_desc
*,
285 int, const char *, const char *, int, rtx
);
286 static void write_attr_value (FILE *, struct attr_desc
*, rtx
);
287 static void write_upcase (FILE *, const char *);
288 static void write_indent (FILE *, int);
289 static rtx
identity_fn (rtx
);
290 static rtx
zero_fn (rtx
);
291 static rtx
one_fn (rtx
);
292 static rtx
max_fn (rtx
);
293 static rtx
min_fn (rtx
);
295 #define oballoc(T) XOBNEW (hash_obstack, T)
296 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
298 /* This gen* file is unique, in that it writes out multiple files.
300 Before GCC 4.8, insn-attrtab.c was written out containing many large
301 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
302 a parallel build, and even made it impossible to build GCC on machines
303 with relatively small RAM space (PR other/29442). Therefore, the
304 atrribute functions/tables are now written out to three separate
305 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
306 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
307 rest goes to ATTR_FILE_NAME. */
309 static const char *attr_file_name
= NULL
;
310 static const char *dfa_file_name
= NULL
;
311 static const char *latency_file_name
= NULL
;
313 static FILE *attr_file
, *dfa_file
, *latency_file
;
315 /* Hash table for sharing RTL and strings. */
317 /* Each hash table slot is a bucket containing a chain of these structures.
318 Strings are given negative hash codes; RTL expressions are given positive
323 struct attr_hash
*next
; /* Next structure in the bucket. */
324 unsigned int hashcode
; /* Hash code of this rtx or string. */
327 char *str
; /* The string (negative hash codes) */
328 rtx rtl
; /* or the RTL recorded here. */
332 /* Now here is the hash table. When recording an RTL, it is added to
333 the slot whose index is the hash code mod the table size. Note
334 that the hash table is used for several kinds of RTL (see attr_rtx)
335 and for strings. While all these live in the same table, they are
336 completely independent, and the hash code is computed differently
339 #define RTL_HASH_SIZE 4093
340 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
342 /* Here is how primitive or already-shared RTL's hash
344 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
346 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
349 attr_hash_add_rtx (unsigned int hashcode
, rtx rtl
)
353 h
= XOBNEW (hash_obstack
, struct attr_hash
);
354 h
->hashcode
= hashcode
;
356 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
357 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
360 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
363 attr_hash_add_string (unsigned int hashcode
, char *str
)
367 h
= XOBNEW (hash_obstack
, struct attr_hash
);
368 h
->hashcode
= -hashcode
;
370 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
371 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
374 /* Generate an RTL expression, but avoid duplicates.
375 Set the ATTR_PERMANENT_P flag for these permanent objects.
377 In some cases we cannot uniquify; then we return an ordinary
378 impermanent rtx with ATTR_PERMANENT_P clear.
382 rtx attr_rtx (code, [element1, ..., elementn]) */
385 attr_rtx_1 (enum rtx_code code
, va_list p
)
387 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
388 unsigned int hashcode
;
390 struct obstack
*old_obstack
= rtl_obstack
;
392 /* For each of several cases, search the hash table for an existing entry.
393 Use that entry if one is found; otherwise create a new RTL and add it
396 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
398 rtx arg0
= va_arg (p
, rtx
);
400 /* A permanent object cannot point to impermanent ones. */
401 if (! ATTR_PERMANENT_P (arg0
))
403 rt_val
= rtx_alloc (code
);
404 XEXP (rt_val
, 0) = arg0
;
408 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
409 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
410 if (h
->hashcode
== hashcode
411 && GET_CODE (h
->u
.rtl
) == code
412 && XEXP (h
->u
.rtl
, 0) == arg0
)
417 rtl_obstack
= hash_obstack
;
418 rt_val
= rtx_alloc (code
);
419 XEXP (rt_val
, 0) = arg0
;
422 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
423 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
424 || GET_RTX_CLASS (code
) == RTX_COMPARE
425 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
427 rtx arg0
= va_arg (p
, rtx
);
428 rtx arg1
= va_arg (p
, rtx
);
430 /* A permanent object cannot point to impermanent ones. */
431 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
433 rt_val
= rtx_alloc (code
);
434 XEXP (rt_val
, 0) = arg0
;
435 XEXP (rt_val
, 1) = arg1
;
439 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
440 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
441 if (h
->hashcode
== hashcode
442 && GET_CODE (h
->u
.rtl
) == code
443 && XEXP (h
->u
.rtl
, 0) == arg0
444 && XEXP (h
->u
.rtl
, 1) == arg1
)
449 rtl_obstack
= hash_obstack
;
450 rt_val
= rtx_alloc (code
);
451 XEXP (rt_val
, 0) = arg0
;
452 XEXP (rt_val
, 1) = arg1
;
455 else if (code
== SYMBOL_REF
456 || (GET_RTX_LENGTH (code
) == 1
457 && GET_RTX_FORMAT (code
)[0] == 's'))
459 char *arg0
= va_arg (p
, char *);
461 arg0
= DEF_ATTR_STRING (arg0
);
463 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
464 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
465 if (h
->hashcode
== hashcode
466 && GET_CODE (h
->u
.rtl
) == code
467 && XSTR (h
->u
.rtl
, 0) == arg0
)
472 rtl_obstack
= hash_obstack
;
473 rt_val
= rtx_alloc (code
);
474 XSTR (rt_val
, 0) = arg0
;
475 if (code
== SYMBOL_REF
)
476 X0EXP (rt_val
, 1) = NULL_RTX
;
479 else if (GET_RTX_LENGTH (code
) == 2
480 && GET_RTX_FORMAT (code
)[0] == 's'
481 && GET_RTX_FORMAT (code
)[1] == 's')
483 char *arg0
= va_arg (p
, char *);
484 char *arg1
= va_arg (p
, char *);
486 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
487 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
488 if (h
->hashcode
== hashcode
489 && GET_CODE (h
->u
.rtl
) == code
490 && XSTR (h
->u
.rtl
, 0) == arg0
491 && XSTR (h
->u
.rtl
, 1) == arg1
)
496 rtl_obstack
= hash_obstack
;
497 rt_val
= rtx_alloc (code
);
498 XSTR (rt_val
, 0) = arg0
;
499 XSTR (rt_val
, 1) = arg1
;
502 else if (code
== CONST_INT
)
504 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
514 int i
; /* Array indices... */
515 const char *fmt
; /* Current rtx's format... */
517 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
519 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
520 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
524 case '0': /* Unused field. */
527 case 'i': /* An integer? */
528 XINT (rt_val
, i
) = va_arg (p
, int);
531 case 'w': /* A wide integer? */
532 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
535 case 's': /* A string? */
536 XSTR (rt_val
, i
) = va_arg (p
, char *);
539 case 'e': /* An expression? */
540 case 'u': /* An insn? Same except when printing. */
541 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
544 case 'E': /* An RTX vector? */
545 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
555 rtl_obstack
= old_obstack
;
556 attr_hash_add_rtx (hashcode
, rt_val
);
557 ATTR_PERMANENT_P (rt_val
) = 1;
562 attr_rtx (enum rtx_code code
, ...)
568 result
= attr_rtx_1 (code
, p
);
573 /* Create a new string printed with the printf line arguments into a space
574 of at most LEN bytes:
576 rtx attr_printf (len, format, [arg1, ..., argn]) */
579 attr_printf (unsigned int len
, const char *fmt
, ...)
586 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
588 vsprintf (str
, fmt
, p
);
591 return DEF_ATTR_STRING (str
);
595 attr_eq (const char *name
, const char *value
)
597 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
603 return XSTR (make_numeric_value (n
), 0);
606 /* Return a permanent (possibly shared) copy of a string STR (not assumed
607 to be null terminated) with LEN bytes. */
610 attr_string (const char *str
, int len
)
613 unsigned int hashcode
;
617 /* Compute the hash code. */
618 hashcode
= (len
+ 1) * 613U + (unsigned) str
[0];
619 for (i
= 1; i
< len
; i
+= 2)
620 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
621 if ((int) hashcode
< 0)
622 hashcode
= -hashcode
;
624 /* Search the table for the string. */
625 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
626 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
627 && !strncmp (h
->u
.str
, str
, len
))
628 return h
->u
.str
; /* <-- return if found. */
630 /* Not found; create a permanent copy and add it to the hash table. */
631 new_str
= XOBNEWVAR (hash_obstack
, char, len
+ 1);
632 memcpy (new_str
, str
, len
);
634 attr_hash_add_string (hashcode
, new_str
);
635 copy_md_ptr_loc (new_str
, str
);
637 return new_str
; /* Return the new string. */
640 /* Check two rtx's for equality of contents,
641 taking advantage of the fact that if both are hashed
642 then they can't be equal unless they are the same object. */
645 attr_equal_p (rtx x
, rtx y
)
647 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
648 && rtx_equal_p (x
, y
)));
651 /* Copy an attribute value expression,
652 descending to all depths, but not copying any
653 permanent hashed subexpressions. */
656 attr_copy_rtx (rtx orig
)
661 const char *format_ptr
;
663 /* No need to copy a permanent object. */
664 if (ATTR_PERMANENT_P (orig
))
667 code
= GET_CODE (orig
);
684 copy
= rtx_alloc (code
);
685 PUT_MODE (copy
, GET_MODE (orig
));
686 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
687 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
688 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
690 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
692 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
694 switch (*format_ptr
++)
697 XEXP (copy
, i
) = XEXP (orig
, i
);
698 if (XEXP (orig
, i
) != NULL
)
699 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
704 XVEC (copy
, i
) = XVEC (orig
, i
);
705 if (XVEC (orig
, i
) != NULL
)
707 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
708 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
709 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
715 XINT (copy
, i
) = XINT (orig
, i
);
719 XWINT (copy
, i
) = XWINT (orig
, i
);
724 XSTR (copy
, i
) = XSTR (orig
, i
);
734 /* Given a test expression for an attribute, ensure it is validly formed.
735 IS_CONST indicates whether the expression is constant for each compiler
736 run (a constant expression may not test any particular insn).
738 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
739 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
740 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
742 Update the string address in EQ_ATTR expression to be the same used
743 in the attribute (or `alternative_name') to speed up subsequent
744 `find_attr' calls and eliminate most `strcmp' calls.
746 Return the new expression, if any. */
749 check_attr_test (rtx exp
, int is_const
, int lineno
)
751 struct attr_desc
*attr
;
752 struct attr_value
*av
;
753 const char *name_ptr
, *p
;
756 switch (GET_CODE (exp
))
759 /* Handle negation test. */
760 if (XSTR (exp
, 1)[0] == '!')
761 return check_attr_test (attr_rtx (NOT
,
762 attr_eq (XSTR (exp
, 0),
766 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
768 attr
= find_attr (&XSTR (exp
, 0), 0);
771 if (! strcmp (XSTR (exp
, 0), "alternative"))
772 return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
774 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
777 if (is_const
&& ! attr
->is_const
)
778 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
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 ("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 ("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
, lineno
);
842 /* Either TRUE or FALSE. */
850 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
851 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
855 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
859 exp
= attr_rtx (MATCH_TEST
, XSTR (exp
, 0));
860 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
865 fatal ("RTL operator \"%s\" not valid in constant attribute test",
866 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 ("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
902 if not. If no attribute is specified, assume a numeric attribute.
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
&& ! attr
->is_numeric
)
918 error_with_line (attr
->lineno
,
919 "CONST_INT not valid for non-numeric attribute %s",
924 if (INTVAL (exp
) < 0)
926 error_with_line (attr
->lineno
,
927 "negative numeric value specified for attribute %s",
934 if (! strcmp (XSTR (exp
, 0), "*"))
937 if (attr
== 0 || attr
->is_numeric
)
943 error_with_line (attr
? attr
->lineno
: 0,
944 "non-numeric value for numeric attribute %s",
945 attr
? attr
->name
: "internal");
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_with_line (attr
->lineno
,
958 "unknown value `%s' for `%s' attribute",
959 XSTR (exp
, 0), attr
? attr
->name
: "internal");
963 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
964 attr
? attr
->is_const
: 0,
965 attr
? attr
->lineno
: 0);
966 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
967 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
975 if (attr
&& !attr
->is_numeric
)
977 error_with_line (attr
->lineno
,
978 "invalid operation `%s' for non-numeric"
979 " attribute value", GET_RTX_NAME (GET_CODE (exp
)));
986 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
987 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
996 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1000 if (XVECLEN (exp
, 0) % 2 != 0)
1002 error_with_line (attr
->lineno
,
1003 "first operand of COND must have even length");
1007 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1009 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1010 attr
? attr
->is_const
: 0,
1011 attr
? attr
->lineno
: 0);
1012 XVECEXP (exp
, 0, i
+ 1)
1013 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1016 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1021 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1023 error_with_line (attr
? attr
->lineno
: 0,
1024 "unknown attribute `%s' in ATTR",
1026 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1027 error_with_line (attr
->lineno
,
1028 "non-constant attribute `%s' referenced from `%s'",
1029 XSTR (exp
, 0), attr
->name
);
1031 && attr
->is_numeric
!= attr2
->is_numeric
)
1032 error_with_line (attr
->lineno
,
1033 "numeric attribute mismatch calling `%s' from `%s'",
1034 XSTR (exp
, 0), attr
->name
);
1039 /* A constant SYMBOL_REF is valid as a constant attribute test and
1040 is expanded later by make_canonical into a COND. In a non-constant
1041 attribute test, it is left be. */
1042 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1045 error_with_line (attr
? attr
->lineno
: 0,
1046 "invalid operation `%s' for attribute value",
1047 GET_RTX_NAME (GET_CODE (exp
)));
1054 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1055 It becomes a COND with each test being (eq_attr "alternative" "n") */
1058 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1060 int num_alt
= id
->num_alternatives
;
1064 if (XVECLEN (exp
, 1) != num_alt
)
1066 error_with_line (id
->lineno
,
1067 "bad number of entries in SET_ATTR_ALTERNATIVE, was %d expected %d",
1068 XVECLEN (exp
, 1), num_alt
);
1072 /* Make a COND with all tests but the last. Select the last value via the
1074 condexp
= rtx_alloc (COND
);
1075 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1077 for (i
= 0; i
< num_alt
- 1; i
++)
1080 p
= attr_numeral (i
);
1082 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1083 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1086 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1088 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1091 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1092 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1095 convert_set_attr (rtx exp
, struct insn_def
*id
)
1098 const char *name_ptr
;
1102 /* See how many alternative specified. */
1103 n
= n_comma_elts (XSTR (exp
, 1));
1105 return attr_rtx (SET
,
1106 attr_rtx (ATTR
, XSTR (exp
, 0)),
1107 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1109 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1110 XSTR (newexp
, 0) = XSTR (exp
, 0);
1111 XVEC (newexp
, 1) = rtvec_alloc (n
);
1113 /* Process each comma-separated name. */
1114 name_ptr
= XSTR (exp
, 1);
1116 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1117 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1119 return convert_set_attr_alternative (newexp
, id
);
1122 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1123 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1129 struct insn_def
*id
;
1130 struct attr_desc
*attr
;
1134 for (id
= defs
; id
; id
= id
->next
)
1136 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1139 read_md_filename
= id
->filename
;
1140 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1142 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1143 switch (GET_CODE (value
))
1146 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1148 error_with_line (id
->lineno
, "bad attribute set");
1153 case SET_ATTR_ALTERNATIVE
:
1154 value
= convert_set_attr_alternative (value
, id
);
1158 value
= convert_set_attr (value
, id
);
1162 error_with_line (id
->lineno
, "invalid attribute code %s",
1163 GET_RTX_NAME (GET_CODE (value
)));
1166 if (value
== NULL_RTX
)
1169 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1171 error_with_line (id
->lineno
, "unknown attribute %s",
1172 XSTR (XEXP (value
, 0), 0));
1176 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1177 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1182 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1183 expressions by converting them into a COND. This removes cases from this
1184 program. Also, replace an attribute value of "*" with the default attribute
1188 make_canonical (struct attr_desc
*attr
, rtx exp
)
1193 switch (GET_CODE (exp
))
1196 exp
= make_numeric_value (INTVAL (exp
));
1200 if (! strcmp (XSTR (exp
, 0), "*"))
1202 if (attr
== 0 || attr
->default_val
== 0)
1203 fatal ("(attr_value \"*\") used in invalid context");
1204 exp
= attr
->default_val
->value
;
1207 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1212 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1214 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1215 This makes the COND something that won't be considered an arbitrary
1216 expression by walk_attr_value. */
1217 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1218 exp
= check_attr_value (exp
, attr
);
1222 newexp
= rtx_alloc (COND
);
1223 XVEC (newexp
, 0) = rtvec_alloc (2);
1224 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1225 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1227 XEXP (newexp
, 1) = XEXP (exp
, 2);
1230 /* Fall through to COND case since this is now a COND. */
1237 /* First, check for degenerate COND. */
1238 if (XVECLEN (exp
, 0) == 0)
1239 return make_canonical (attr
, XEXP (exp
, 1));
1240 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1242 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1244 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1245 XVECEXP (exp
, 0, i
+ 1)
1246 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1247 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1263 copy_boolean (rtx exp
)
1265 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1266 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1267 copy_boolean (XEXP (exp
, 1)));
1268 if (GET_CODE (exp
) == MATCH_OPERAND
)
1270 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1271 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1273 else if (GET_CODE (exp
) == EQ_ATTR
)
1275 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1276 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1282 /* Given a value and an attribute description, return a `struct attr_value *'
1283 that represents that value. This is either an existing structure, if the
1284 value has been previously encountered, or a newly-created structure.
1286 `insn_code' is the code of an insn whose attribute has the specified
1287 value (-2 if not processing an insn). We ensure that all insns for
1288 a given value have the same number of alternatives if the value checks
1291 static struct attr_value
*
1292 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1294 struct attr_value
*av
;
1295 uint64_t num_alt
= 0;
1297 value
= make_canonical (attr
, value
);
1298 if (compares_alternatives_p (value
))
1300 if (insn_code
< 0 || insn_alternatives
== NULL
)
1301 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1303 num_alt
= insn_alternatives
[insn_code
];
1306 for (av
= attr
->first_value
; av
; av
= av
->next
)
1307 if (rtx_equal_p (value
, av
->value
)
1308 && (num_alt
== 0 || av
->first_insn
== NULL
1309 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1312 av
= oballoc (struct attr_value
);
1314 av
->next
= attr
->first_value
;
1315 attr
->first_value
= av
;
1316 av
->first_insn
= NULL
;
1318 av
->has_asm_insn
= 0;
1323 /* After all DEFINE_DELAYs have been read in, create internal attributes
1324 to generate the required routines.
1326 First, we compute the number of delay slots for each insn (as a COND of
1327 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1328 delay type is specified, we compute a similar function giving the
1329 DEFINE_DELAY ordinal for each insn.
1331 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1332 tells whether a given insn can be in that delay slot.
1334 Normal attribute filling and optimization expands these to contain the
1335 information needed to handle delay slots. */
1338 expand_delays (void)
1340 struct delay_desc
*delay
;
1346 /* First, generate data for `num_delay_slots' function. */
1348 condexp
= rtx_alloc (COND
);
1349 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1350 XEXP (condexp
, 1) = make_numeric_value (0);
1352 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1354 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1355 XVECEXP (condexp
, 0, i
+ 1)
1356 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1359 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1361 /* If more than one delay type, do the same for computing the delay type. */
1364 condexp
= rtx_alloc (COND
);
1365 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1366 XEXP (condexp
, 1) = make_numeric_value (0);
1368 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1370 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1371 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1374 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1377 /* For each delay possibility and delay slot, compute an eligibility
1378 attribute for non-annulled insns and for each type of annulled (annul
1379 if true and annul if false). */
1380 for (delay
= delays
; delay
; delay
= delay
->next
)
1382 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1384 condexp
= XVECEXP (delay
->def
, 1, i
);
1386 condexp
= false_rtx
;
1387 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1388 make_numeric_value (1), make_numeric_value (0));
1390 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1391 "*delay_%d_%d", delay
->num
, i
/ 3);
1392 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1394 if (have_annul_true
)
1396 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1397 if (condexp
== 0) condexp
= false_rtx
;
1398 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1399 make_numeric_value (1),
1400 make_numeric_value (0));
1401 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1402 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1403 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1406 if (have_annul_false
)
1408 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1409 if (condexp
== 0) condexp
= false_rtx
;
1410 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1411 make_numeric_value (1),
1412 make_numeric_value (0));
1413 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1414 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1415 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1421 /* Once all attributes and insns have been read and checked, we construct for
1422 each attribute value a list of all the insns that have that value for
1426 fill_attr (struct attr_desc
*attr
)
1428 struct attr_value
*av
;
1429 struct insn_ent
*ie
;
1430 struct insn_def
*id
;
1434 /* Don't fill constant attributes. The value is independent of
1435 any particular insn. */
1439 for (id
= defs
; id
; id
= id
->next
)
1441 /* If no value is specified for this insn for this attribute, use the
1444 if (XVEC (id
->def
, id
->vec_idx
))
1445 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1446 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1448 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1451 av
= attr
->default_val
;
1453 av
= get_attr_value (value
, attr
, id
->insn_code
);
1455 ie
= oballoc (struct insn_ent
);
1457 insert_insn_ent (av
, ie
);
1461 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1462 test that checks relative positions of insns (uses MATCH_DUP or PC).
1463 If so, replace it with what is obtained by passing the expression to
1464 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1465 recursively on each value (including the default value). Otherwise,
1466 return the value returned by NO_ADDRESS_FN applied to EXP. */
1469 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1470 rtx (*address_fn
) (rtx
))
1475 if (GET_CODE (exp
) == COND
)
1477 /* See if any tests use addresses. */
1479 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1480 walk_attr_value (XVECEXP (exp
, 0, i
));
1483 return (*address_fn
) (exp
);
1485 /* Make a new copy of this COND, replacing each element. */
1486 newexp
= rtx_alloc (COND
);
1487 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1488 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1490 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1491 XVECEXP (newexp
, 0, i
+ 1)
1492 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1493 no_address_fn
, address_fn
);
1496 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1497 no_address_fn
, address_fn
);
1502 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1505 walk_attr_value (XEXP (exp
, 0));
1507 return (*address_fn
) (exp
);
1509 return attr_rtx (IF_THEN_ELSE
,
1510 substitute_address (XEXP (exp
, 0),
1511 no_address_fn
, address_fn
),
1512 substitute_address (XEXP (exp
, 1),
1513 no_address_fn
, address_fn
),
1514 substitute_address (XEXP (exp
, 2),
1515 no_address_fn
, address_fn
));
1518 return (*no_address_fn
) (exp
);
1521 /* Make new attributes from the `length' attribute. The following are made,
1522 each corresponding to a function called from `shorten_branches' or
1525 *insn_default_length This is the length of the insn to be returned
1526 by `get_attr_length' before `shorten_branches'
1527 has been called. In each case where the length
1528 depends on relative addresses, the largest
1529 possible is used. This routine is also used
1530 to compute the initial size of the insn.
1532 *insn_variable_length_p This returns 1 if the insn's length depends
1533 on relative addresses, zero otherwise.
1535 *insn_current_length This is only called when it is known that the
1536 insn has a variable length and returns the
1537 current length, based on relative addresses.
1541 make_length_attrs (void)
1543 static const char *new_names
[] =
1545 "*insn_default_length",
1547 "*insn_variable_length_p",
1548 "*insn_current_length"
1550 static rtx (*const no_address_fn
[]) (rtx
)
1551 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1552 static rtx (*const address_fn
[]) (rtx
)
1553 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1555 struct attr_desc
*length_attr
, *new_attr
;
1556 struct attr_value
*av
, *new_av
;
1557 struct insn_ent
*ie
, *new_ie
;
1559 /* See if length attribute is defined. If so, it must be numeric. Make
1560 it special so we don't output anything for it. */
1561 length_attr
= find_attr (&length_str
, 0);
1562 if (length_attr
== 0)
1565 if (! length_attr
->is_numeric
)
1566 fatal ("length attribute must be numeric");
1568 length_attr
->is_const
= 0;
1569 length_attr
->is_special
= 1;
1571 /* Make each new attribute, in turn. */
1572 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1574 make_internal_attr (new_names
[i
],
1575 substitute_address (length_attr
->default_val
->value
,
1576 no_address_fn
[i
], address_fn
[i
]),
1578 new_attr
= find_attr (&new_names
[i
], 0);
1579 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1580 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1582 new_av
= get_attr_value (substitute_address (av
->value
,
1585 new_attr
, ie
->def
->insn_code
);
1586 new_ie
= oballoc (struct insn_ent
);
1587 new_ie
->def
= ie
->def
;
1588 insert_insn_ent (new_av
, new_ie
);
1593 /* Utility functions called from above routine. */
1596 identity_fn (rtx exp
)
1602 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1604 return make_numeric_value (0);
1608 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1610 return make_numeric_value (1);
1617 return make_numeric_value (max_attr_value (exp
, &unknown
));
1624 return make_numeric_value (min_attr_value (exp
, &unknown
));
1628 write_length_unit_log (FILE *outf
)
1630 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1631 struct attr_value
*av
;
1632 struct insn_ent
*ie
;
1633 unsigned int length_unit_log
, length_or
;
1638 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1639 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1640 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1641 length_or
|= or_attr_value (av
->value
, &unknown
);
1644 if (length_attr
== NULL
|| unknown
)
1645 length_unit_log
= 0;
1648 length_or
= ~length_or
;
1649 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1652 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1655 /* Compute approximate cost of the expression. Used to decide whether
1656 expression is cheap enough for inline. */
1658 attr_rtx_cost (rtx x
)
1664 code
= GET_CODE (x
);
1677 /* Alternatives don't result into function call. */
1678 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1685 const char *fmt
= GET_RTX_FORMAT (code
);
1686 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1692 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1693 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1696 cost
+= attr_rtx_cost (XEXP (x
, i
));
1706 /* Take a COND expression and see if any of the conditions in it can be
1707 simplified. If any are known true or known false for the particular insn
1708 code, the COND can be further simplified.
1710 Also call ourselves on any COND operations that are values of this COND.
1712 We do not modify EXP; rather, we make and return a new rtx. */
1715 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1718 /* We store the desired contents here,
1719 then build a new expression if they don't match EXP. */
1720 rtx defval
= XEXP (exp
, 1);
1721 rtx new_defval
= XEXP (exp
, 1);
1722 int len
= XVECLEN (exp
, 0);
1723 rtx
*tests
= XNEWVEC (rtx
, len
);
1727 /* This lets us free all storage allocated below, if appropriate. */
1728 obstack_finish (rtl_obstack
);
1730 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1732 /* See if default value needs simplification. */
1733 if (GET_CODE (defval
) == COND
)
1734 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1736 /* Simplify the subexpressions, and see what tests we can get rid of. */
1738 for (i
= 0; i
< len
; i
+= 2)
1740 rtx newtest
, newval
;
1742 /* Simplify this test. */
1743 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1746 newval
= tests
[i
+ 1];
1747 /* See if this value may need simplification. */
1748 if (GET_CODE (newval
) == COND
)
1749 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1751 /* Look for ways to delete or combine this test. */
1752 if (newtest
== true_rtx
)
1754 /* If test is true, make this value the default
1755 and discard this + any following tests. */
1757 defval
= tests
[i
+ 1];
1758 new_defval
= newval
;
1761 else if (newtest
== false_rtx
)
1763 /* If test is false, discard it and its value. */
1764 for (j
= i
; j
< len
- 2; j
++)
1765 tests
[j
] = tests
[j
+ 2];
1770 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1772 /* If this value and the value for the prev test are the same,
1776 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1777 insn_code
, insn_index
);
1779 /* Delete this test/value. */
1780 for (j
= i
; j
< len
- 2; j
++)
1781 tests
[j
] = tests
[j
+ 2];
1787 tests
[i
+ 1] = newval
;
1790 /* If the last test in a COND has the same value
1791 as the default value, that test isn't needed. */
1793 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1796 /* See if we changed anything. */
1797 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1800 for (i
= 0; i
< len
; i
++)
1801 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1809 if (GET_CODE (defval
) == COND
)
1810 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1818 rtx newexp
= rtx_alloc (COND
);
1820 XVEC (newexp
, 0) = rtvec_alloc (len
);
1821 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1822 XEXP (newexp
, 1) = new_defval
;
1829 /* Remove an insn entry from an attribute value. */
1832 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1834 struct insn_ent
*previe
;
1836 if (av
->first_insn
== ie
)
1837 av
->first_insn
= ie
->next
;
1840 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1842 previe
->next
= ie
->next
;
1846 if (ie
->def
->insn_code
== -1)
1847 av
->has_asm_insn
= 0;
1852 /* Insert an insn entry in an attribute value list. */
1855 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1857 ie
->next
= av
->first_insn
;
1858 av
->first_insn
= ie
;
1860 if (ie
->def
->insn_code
== -1)
1861 av
->has_asm_insn
= 1;
1866 /* This is a utility routine to take an expression that is a tree of either
1867 AND or IOR expressions and insert a new term. The new term will be
1868 inserted at the right side of the first node whose code does not match
1869 the root. A new node will be created with the root's code. Its left
1870 side will be the old right side and its right side will be the new
1873 If the `term' is itself a tree, all its leaves will be inserted. */
1876 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1880 /* Avoid consing in some special cases. */
1881 if (code
== AND
&& term
== true_rtx
)
1883 if (code
== AND
&& term
== false_rtx
)
1885 if (code
== AND
&& exp
== true_rtx
)
1887 if (code
== AND
&& exp
== false_rtx
)
1889 if (code
== IOR
&& term
== true_rtx
)
1891 if (code
== IOR
&& term
== false_rtx
)
1893 if (code
== IOR
&& exp
== true_rtx
)
1895 if (code
== IOR
&& exp
== false_rtx
)
1897 if (attr_equal_p (exp
, term
))
1900 if (GET_CODE (term
) == code
)
1902 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1903 insn_code
, insn_index
);
1904 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1905 insn_code
, insn_index
);
1910 if (GET_CODE (exp
) == code
)
1912 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1913 term
, insn_code
, insn_index
);
1914 if (new_rtx
!= XEXP (exp
, 1))
1915 /* Make a copy of this expression and call recursively. */
1916 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1922 /* Insert the new term. */
1923 newexp
= attr_rtx (code
, exp
, term
);
1926 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1929 /* If we have an expression which AND's a bunch of
1930 (not (eq_attrq "alternative" "n"))
1931 terms, we may have covered all or all but one of the possible alternatives.
1932 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1934 This routine is passed an expression and either AND or IOR. It returns a
1935 bitmask indicating which alternatives are mentioned within EXP. */
1938 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1941 if (GET_CODE (exp
) == code
)
1942 return compute_alternative_mask (XEXP (exp
, 0), code
)
1943 | compute_alternative_mask (XEXP (exp
, 1), code
);
1945 else if (code
== AND
&& GET_CODE (exp
) == NOT
1946 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1947 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1948 string
= XSTR (XEXP (exp
, 0), 1);
1950 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1951 && XSTR (exp
, 0) == alternative_name
)
1952 string
= XSTR (exp
, 1);
1954 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1956 if (code
== AND
&& XINT (exp
, 1))
1957 return XINT (exp
, 0);
1959 if (code
== IOR
&& !XINT (exp
, 1))
1960 return XINT (exp
, 0);
1968 return ((uint64_t) 1) << (string
[0] - '0');
1969 return ((uint64_t) 1) << atoi (string
);
1972 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1973 attribute with the value represented by that bit. */
1976 make_alternative_compare (uint64_t mask
)
1978 return mk_attr_alt (mask
);
1981 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1982 of "attr" for this insn code. From that value, we can compute a test
1983 showing when the EQ_ATTR will be true. This routine performs that
1984 computation. If a test condition involves an address, we leave the EQ_ATTR
1985 intact because addresses are only valid for the `length' attribute.
1987 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1988 it refers. VALUE is the value of that attribute for the insn
1989 corresponding to INSN_CODE and INSN_INDEX. */
1992 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1993 int insn_code
, int insn_index
)
2000 while (GET_CODE (value
) == ATTR
)
2002 struct attr_value
*av
= NULL
;
2004 attr
= find_attr (&XSTR (value
, 0), 0);
2006 if (insn_code_values
)
2008 struct attr_value_list
*iv
;
2009 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2010 if (iv
->attr
== attr
)
2018 struct insn_ent
*ie
;
2019 for (av
= attr
->first_value
; av
; av
= av
->next
)
2020 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2021 if (ie
->def
->insn_code
== insn_code
)
2031 switch (GET_CODE (value
))
2034 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2045 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2046 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
2047 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
2048 for (p
= string
; *p
; p
++)
2051 newexp
= attr_rtx (EQ
, value
,
2052 attr_rtx (SYMBOL_REF
,
2053 DEF_ATTR_STRING (string
)));
2058 /* We construct an IOR of all the cases for which the
2059 requested attribute value is present. Since we start with
2060 FALSE, if it is not present, FALSE will be returned.
2062 Each case is the AND of the NOT's of the previous conditions with the
2063 current condition; in the default case the current condition is TRUE.
2065 For each possible COND value, call ourselves recursively.
2067 The extra TRUE and FALSE expressions will be eliminated by another
2068 call to the simplification routine. */
2073 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2075 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2076 insn_code
, insn_index
);
2078 right
= insert_right_side (AND
, andexp
, this_cond
,
2079 insn_code
, insn_index
);
2080 right
= insert_right_side (AND
, right
,
2081 evaluate_eq_attr (exp
, attr
,
2084 insn_code
, insn_index
),
2085 insn_code
, insn_index
);
2086 orexp
= insert_right_side (IOR
, orexp
, right
,
2087 insn_code
, insn_index
);
2089 /* Add this condition into the AND expression. */
2090 newexp
= attr_rtx (NOT
, this_cond
);
2091 andexp
= insert_right_side (AND
, andexp
, newexp
,
2092 insn_code
, insn_index
);
2095 /* Handle the default case. */
2096 right
= insert_right_side (AND
, andexp
,
2097 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2098 insn_code
, insn_index
),
2099 insn_code
, insn_index
);
2100 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2107 /* If uses an address, must return original expression. But set the
2108 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2111 walk_attr_value (newexp
);
2115 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2116 return copy_rtx_unchanging (exp
);
2123 /* This routine is called when an AND of a term with a tree of AND's is
2124 encountered. If the term or its complement is present in the tree, it
2125 can be replaced with TRUE or FALSE, respectively.
2127 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2128 be true and hence are complementary.
2130 There is one special case: If we see
2131 (and (not (eq_attr "att" "v1"))
2132 (eq_attr "att" "v2"))
2133 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2134 replace the term, not anything in the AND tree. So we pass a pointer to
2138 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2143 int left_eliminates_term
, right_eliminates_term
;
2145 if (GET_CODE (exp
) == AND
)
2147 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2148 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2149 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2151 newexp
= attr_rtx (AND
, left
, right
);
2153 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2157 else if (GET_CODE (exp
) == IOR
)
2159 /* For the IOR case, we do the same as above, except that we can
2160 only eliminate `term' if both sides of the IOR would do so. */
2162 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2163 left_eliminates_term
= (temp
== true_rtx
);
2166 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2167 right_eliminates_term
= (temp
== true_rtx
);
2169 if (left_eliminates_term
&& right_eliminates_term
)
2172 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2174 newexp
= attr_rtx (IOR
, left
, right
);
2176 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2180 /* Check for simplifications. Do some extra checking here since this
2181 routine is called so many times. */
2186 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2189 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2192 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2194 if (attr_alt_subset_p (*pterm
, exp
))
2197 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2200 if (attr_alt_subset_p (exp
, *pterm
))
2206 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2208 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2211 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2217 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2218 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2220 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2223 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2229 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2230 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2232 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2235 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2241 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2243 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2247 else if (GET_CODE (exp
) == NOT
)
2249 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2253 else if (GET_CODE (*pterm
) == NOT
)
2255 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2259 else if (attr_equal_p (exp
, *pterm
))
2265 /* Similar to `simplify_and_tree', but for IOR trees. */
2268 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2273 int left_eliminates_term
, right_eliminates_term
;
2275 if (GET_CODE (exp
) == IOR
)
2277 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2278 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2279 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2281 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2283 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2287 else if (GET_CODE (exp
) == AND
)
2289 /* For the AND case, we do the same as above, except that we can
2290 only eliminate `term' if both sides of the AND would do so. */
2292 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2293 left_eliminates_term
= (temp
== false_rtx
);
2296 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2297 right_eliminates_term
= (temp
== false_rtx
);
2299 if (left_eliminates_term
&& right_eliminates_term
)
2302 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2304 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2306 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2310 if (attr_equal_p (exp
, *pterm
))
2313 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2316 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2319 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2320 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2321 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2324 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2325 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2326 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2332 /* Simplify test expression and use temporary obstack in order to avoid
2333 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2334 and avoid unnecessary copying if possible. */
2337 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2340 struct obstack
*old
;
2341 if (ATTR_IND_SIMPLIFIED_P (exp
))
2344 rtl_obstack
= temp_obstack
;
2345 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2347 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2349 return attr_copy_rtx (x
);
2352 /* Returns true if S1 is a subset of S2. */
2355 attr_alt_subset_p (rtx s1
, rtx s2
)
2357 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2360 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2363 return !(XINT (s1
, 0) & XINT (s2
, 0));
2369 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2376 /* Returns true if S1 is a subset of complement of S2. */
2379 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2381 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2384 return !(XINT (s1
, 0) & XINT (s2
, 0));
2387 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2390 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2400 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2403 attr_alt_intersection (rtx s1
, rtx s2
)
2405 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2407 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2410 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2413 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2416 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2419 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2424 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2429 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2432 attr_alt_union (rtx s1
, rtx s2
)
2434 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2436 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2439 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2442 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2445 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2448 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2454 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2458 /* Return EQ_ATTR_ALT expression representing complement of S. */
2461 attr_alt_complement (rtx s
)
2463 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2465 XINT (result
, 0) = XINT (s
, 0);
2466 XINT (result
, 1) = 1 - XINT (s
, 1);
2471 /* Return EQ_ATTR_ALT expression representing set containing elements set
2475 mk_attr_alt (uint64_t e
)
2477 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2479 XINT (result
, 0) = e
;
2480 XINT (result
, 1) = 0;
2485 /* Given an expression, see if it can be simplified for a particular insn
2486 code based on the values of other attributes being tested. This can
2487 eliminate nested get_attr_... calls.
2489 Note that if an endless recursion is specified in the patterns, the
2490 optimization will loop. However, it will do so in precisely the cases where
2491 an infinite recursion loop could occur during compilation. It's better that
2495 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2498 struct attr_desc
*attr
;
2499 struct attr_value
*av
;
2500 struct insn_ent
*ie
;
2501 struct attr_value_list
*iv
;
2504 bool left_alt
, right_alt
;
2506 /* Don't re-simplify something we already simplified. */
2507 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2510 switch (GET_CODE (exp
))
2513 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2514 if (left
== false_rtx
)
2516 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2517 if (right
== false_rtx
)
2520 if (GET_CODE (left
) == EQ_ATTR_ALT
2521 && GET_CODE (right
) == EQ_ATTR_ALT
)
2523 exp
= attr_alt_intersection (left
, right
);
2524 return simplify_test_exp (exp
, insn_code
, insn_index
);
2527 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2528 present on both sides, apply the distributive law since this will
2529 yield simplifications. */
2530 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2531 && compute_alternative_mask (left
, IOR
)
2532 && compute_alternative_mask (right
, IOR
))
2534 if (GET_CODE (left
) == IOR
)
2535 std::swap (left
, right
);
2537 newexp
= attr_rtx (IOR
,
2538 attr_rtx (AND
, left
, XEXP (right
, 0)),
2539 attr_rtx (AND
, left
, XEXP (right
, 1)));
2541 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2544 /* Try with the term on both sides. */
2545 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2546 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2547 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2549 if (left
== false_rtx
|| right
== false_rtx
)
2551 else if (left
== true_rtx
)
2555 else if (right
== true_rtx
)
2559 /* See if all or all but one of the insn's alternatives are specified
2560 in this tree. Optimize if so. */
2562 if (GET_CODE (left
) == NOT
)
2563 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2564 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2566 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2569 if (GET_CODE (right
) == NOT
)
2570 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2571 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2573 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2574 && XINT (right
, 1));
2577 && (GET_CODE (left
) == AND
2579 || GET_CODE (right
) == AND
2582 i
= compute_alternative_mask (exp
, AND
);
2583 if (i
& ~insn_alternatives
[insn_code
])
2584 fatal ("invalid alternative specified for pattern number %d",
2587 /* If all alternatives are excluded, this is false. */
2588 i
^= insn_alternatives
[insn_code
];
2591 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2593 /* If just one excluded, AND a comparison with that one to the
2594 front of the tree. The others will be eliminated by
2595 optimization. We do not want to do this if the insn has one
2596 alternative and we have tested none of them! */
2597 left
= make_alternative_compare (i
);
2598 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2599 newexp
= attr_rtx (AND
, left
, right
);
2601 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2605 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2607 newexp
= attr_rtx (AND
, left
, right
);
2608 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2613 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2614 if (left
== true_rtx
)
2616 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2617 if (right
== true_rtx
)
2620 if (GET_CODE (left
) == EQ_ATTR_ALT
2621 && GET_CODE (right
) == EQ_ATTR_ALT
)
2623 exp
= attr_alt_union (left
, right
);
2624 return simplify_test_exp (exp
, insn_code
, insn_index
);
2627 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2628 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2629 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2631 if (right
== true_rtx
|| left
== true_rtx
)
2633 else if (left
== false_rtx
)
2637 else if (right
== false_rtx
)
2642 /* Test for simple cases where the distributive law is useful. I.e.,
2643 convert (ior (and (x) (y))
2649 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2650 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2652 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2654 left
= XEXP (left
, 0);
2656 newexp
= attr_rtx (AND
, left
, right
);
2657 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2661 convert (ior (and (y) (x))
2663 to (and (ior (y) (z))
2665 Note that we want the common term to stay at the end.
2668 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2669 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2671 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2674 right
= XEXP (right
, 1);
2675 newexp
= attr_rtx (AND
, left
, right
);
2676 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2679 /* See if all or all but one of the insn's alternatives are specified
2680 in this tree. Optimize if so. */
2682 else if (insn_code
>= 0
2683 && (GET_CODE (left
) == IOR
2684 || (GET_CODE (left
) == EQ_ATTR_ALT
2686 || (GET_CODE (left
) == EQ_ATTR
2687 && XSTR (left
, 0) == alternative_name
)
2688 || GET_CODE (right
) == IOR
2689 || (GET_CODE (right
) == EQ_ATTR_ALT
2690 && !XINT (right
, 1))
2691 || (GET_CODE (right
) == EQ_ATTR
2692 && XSTR (right
, 0) == alternative_name
)))
2694 i
= compute_alternative_mask (exp
, IOR
);
2695 if (i
& ~insn_alternatives
[insn_code
])
2696 fatal ("invalid alternative specified for pattern number %d",
2699 /* If all alternatives are included, this is true. */
2700 i
^= insn_alternatives
[insn_code
];
2703 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2705 /* If just one excluded, IOR a comparison with that one to the
2706 front of the tree. The others will be eliminated by
2707 optimization. We do not want to do this if the insn has one
2708 alternative and we have tested none of them! */
2709 left
= make_alternative_compare (i
);
2710 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2711 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2713 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2717 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2719 newexp
= attr_rtx (IOR
, left
, right
);
2720 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2725 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2727 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2728 insn_code
, insn_index
);
2732 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2733 if (GET_CODE (left
) == NOT
)
2734 return XEXP (left
, 0);
2736 if (left
== false_rtx
)
2738 if (left
== true_rtx
)
2741 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2743 exp
= attr_alt_complement (left
);
2744 return simplify_test_exp (exp
, insn_code
, insn_index
);
2747 /* Try to apply De`Morgan's laws. */
2748 if (GET_CODE (left
) == IOR
)
2750 newexp
= attr_rtx (AND
,
2751 attr_rtx (NOT
, XEXP (left
, 0)),
2752 attr_rtx (NOT
, XEXP (left
, 1)));
2754 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2756 else if (GET_CODE (left
) == AND
)
2758 newexp
= attr_rtx (IOR
,
2759 attr_rtx (NOT
, XEXP (left
, 0)),
2760 attr_rtx (NOT
, XEXP (left
, 1)));
2762 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2764 else if (left
!= XEXP (exp
, 0))
2766 newexp
= attr_rtx (NOT
, left
);
2772 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2776 if (XSTR (exp
, 0) == alternative_name
)
2778 newexp
= mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp
, 1)));
2782 /* Look at the value for this insn code in the specified attribute.
2783 We normally can replace this comparison with the condition that
2784 would give this insn the values being tested for. */
2786 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2791 if (insn_code_values
)
2793 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2794 if (iv
->attr
== attr
)
2802 for (av
= attr
->first_value
; av
; av
= av
->next
)
2803 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2804 if (ie
->def
->insn_code
== insn_code
)
2811 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2812 insn_code
, insn_index
);
2813 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2814 if (attr_rtx_cost (x
) < 7)
2824 /* We have already simplified this expression. Simplifying it again
2825 won't buy anything unless we weren't given a valid insn code
2826 to process (i.e., we are canonicalizing something.). */
2828 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2829 return copy_rtx_unchanging (newexp
);
2834 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2835 otherwise return 0. */
2838 tests_attr_p (rtx p
, struct attr_desc
*attr
)
2843 if (GET_CODE (p
) == EQ_ATTR
)
2845 if (XSTR (p
, 0) != attr
->name
)
2850 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2851 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2852 for (i
= 0; i
< ie
; i
++)
2857 if (tests_attr_p (XEXP (p
, i
), attr
))
2862 je
= XVECLEN (p
, i
);
2863 for (j
= 0; j
< je
; ++j
)
2864 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2873 /* Calculate a topological sorting of all attributes so that
2874 all attributes only depend on attributes in front of it.
2875 Place the result in *RET (which is a pointer to an array of
2876 attr_desc pointers), and return the size of that array. */
2879 get_attr_order (struct attr_desc
***ret
)
2883 struct attr_desc
*attr
;
2884 struct attr_desc
**all
, **sorted
;
2886 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2887 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2889 all
= XNEWVEC (struct attr_desc
*, num
);
2890 sorted
= XNEWVEC (struct attr_desc
*, num
);
2891 handled
= XCNEWVEC (char, num
);
2893 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2894 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2898 for (i
= 0; i
< num
; i
++)
2899 if (all
[i
]->is_const
)
2900 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2902 /* We have only few attributes hence we can live with the inner
2903 loop being O(n^2), unlike the normal fast variants of topological
2907 for (i
= 0; i
< num
; i
++)
2910 /* Let's see if I depends on anything interesting. */
2912 for (k
= 0; k
< num
; k
++)
2915 struct attr_value
*av
;
2916 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2917 if (av
->num_insns
!= 0)
2918 if (tests_attr_p (av
->value
, all
[k
]))
2922 /* Something in I depends on K. */
2927 /* Nothing in I depended on anything intersting, so
2930 sorted
[j
++] = all
[i
];
2936 for (j
= 0; j
< num
; j
++)
2938 struct attr_desc
*attr2
;
2939 struct attr_value
*av
;
2942 fprintf (stderr
, "%s depends on: ", attr
->name
);
2943 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2944 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2945 if (!attr2
->is_const
)
2946 for (av
= attr
->first_value
; av
; av
= av
->next
)
2947 if (av
->num_insns
!= 0)
2948 if (tests_attr_p (av
->value
, attr2
))
2950 fprintf (stderr
, "%s, ", attr2
->name
);
2953 fprintf (stderr
, "\n");
2961 /* Optimize the attribute lists by seeing if we can determine conditional
2962 values from the known values of other attributes. This will save subroutine
2963 calls during the compilation. */
2966 optimize_attrs (void)
2968 struct attr_desc
*attr
;
2969 struct attr_value
*av
;
2970 struct insn_ent
*ie
;
2973 struct attr_value_list
*ivbuf
;
2974 struct attr_value_list
*iv
;
2975 struct attr_desc
**topsort
;
2978 /* For each insn code, make a list of all the insn_ent's for it,
2979 for all values for all attributes. */
2981 if (num_insn_ents
== 0)
2984 /* Make 2 extra elements, for "code" values -2 and -1. */
2985 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2987 /* Offset the table address so we can index by -2 or -1. */
2988 insn_code_values
+= 2;
2990 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2992 /* Create the chain of insn*attr values such that we see dependend
2993 attributes after their dependencies. As we use a stack via the
2994 next pointers start from the end of the topological order. */
2995 topnum
= get_attr_order (&topsort
);
2996 for (i
= topnum
- 1; i
>= 0; i
--)
2997 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
2998 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
3000 iv
->attr
= topsort
[i
];
3003 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
3004 insn_code_values
[ie
->def
->insn_code
] = iv
;
3009 /* Sanity check on num_insn_ents. */
3010 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
3012 /* Process one insn code at a time. */
3013 for (i
= -2; i
< insn_code_number
; i
++)
3015 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3016 We use it to mean "already simplified for this insn". */
3017 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3018 clear_struct_flag (iv
->av
->value
);
3020 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3022 struct obstack
*old
= rtl_obstack
;
3027 if (GET_CODE (av
->value
) != COND
)
3030 rtl_obstack
= temp_obstack
;
3032 while (GET_CODE (newexp
) == COND
)
3034 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
3035 ie
->def
->insn_index
);
3036 if (newexp2
== newexp
)
3042 /* If we created a new value for this instruction, and it's
3043 cheaper than the old value, and overall cheap, use that
3044 one as specific value for the current instruction.
3045 The last test is to avoid exploding the get_attr_ function
3046 sizes for no much gain. */
3047 if (newexp
!= av
->value
3048 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
3049 && attr_rtx_cost (newexp
) < 26
3052 newexp
= attr_copy_rtx (newexp
);
3053 remove_insn_ent (av
, ie
);
3054 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
3056 insert_insn_ent (av
, ie
);
3062 free (insn_code_values
- 2);
3063 insn_code_values
= NULL
;
3066 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3069 clear_struct_flag (rtx x
)
3076 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3077 if (ATTR_IND_SIMPLIFIED_P (x
))
3080 code
= GET_CODE (x
);
3099 /* Compare the elements. If any pair of corresponding elements
3100 fail to match, return 0 for the whole things. */
3102 fmt
= GET_RTX_FORMAT (code
);
3103 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3109 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3110 clear_struct_flag (XVECEXP (x
, i
, j
));
3114 clear_struct_flag (XEXP (x
, i
));
3120 /* Add attribute value NAME to the beginning of ATTR's list. */
3123 add_attr_value (struct attr_desc
*attr
, const char *name
)
3125 struct attr_value
*av
;
3127 av
= oballoc (struct attr_value
);
3128 av
->value
= attr_rtx (CONST_STRING
, name
);
3129 av
->next
= attr
->first_value
;
3130 attr
->first_value
= av
;
3131 av
->first_insn
= NULL
;
3133 av
->has_asm_insn
= 0;
3136 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3139 gen_attr (rtx exp
, int lineno
)
3141 struct enum_type
*et
;
3142 struct enum_value
*ev
;
3143 struct attr_desc
*attr
;
3144 const char *name_ptr
;
3147 /* Make a new attribute structure. Check for duplicate by looking at
3148 attr->default_val, since it is initialized by this routine. */
3149 attr
= find_attr (&XSTR (exp
, 0), 1);
3150 if (attr
->default_val
)
3152 error_with_line (lineno
, "duplicate definition for attribute %s",
3154 message_with_line (attr
->lineno
, "previous definition");
3157 attr
->lineno
= lineno
;
3159 if (GET_CODE (exp
) == DEFINE_ENUM_ATTR
)
3161 attr
->enum_name
= XSTR (exp
, 1);
3162 et
= lookup_enum_type (XSTR (exp
, 1));
3163 if (!et
|| !et
->md_p
)
3164 error_with_line (lineno
, "No define_enum called `%s' defined",
3167 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3168 add_attr_value (attr
, ev
->name
);
3170 else if (*XSTR (exp
, 1) == '\0')
3171 attr
->is_numeric
= 1;
3174 name_ptr
= XSTR (exp
, 1);
3175 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3176 add_attr_value (attr
, p
);
3179 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3182 if (attr
->is_numeric
)
3183 error_with_line (lineno
,
3184 "constant attributes may not take numeric values");
3186 /* Get rid of the CONST node. It is allowed only at top-level. */
3187 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3190 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3191 error_with_line (lineno
, "`length' attribute must take numeric values");
3193 /* Set up the default value. */
3194 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3195 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3198 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3199 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3200 number of alternatives as this should be checked elsewhere. */
3203 count_alternatives (rtx exp
)
3208 if (GET_CODE (exp
) == MATCH_OPERAND
)
3209 return n_comma_elts (XSTR (exp
, 2));
3211 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3212 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3217 n
= count_alternatives (XEXP (exp
, i
));
3224 if (XVEC (exp
, i
) != NULL
)
3225 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3227 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3236 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3237 `alternative' attribute. */
3240 compares_alternatives_p (rtx exp
)
3245 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3248 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3249 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3254 if (compares_alternatives_p (XEXP (exp
, i
)))
3259 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3260 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3268 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3271 gen_insn (rtx exp
, int lineno
)
3273 struct insn_def
*id
;
3275 id
= oballoc (struct insn_def
);
3279 id
->filename
= read_md_filename
;
3280 id
->lineno
= lineno
;
3282 switch (GET_CODE (exp
))
3285 id
->insn_code
= insn_code_number
;
3286 id
->insn_index
= insn_index_number
;
3287 id
->num_alternatives
= count_alternatives (exp
);
3288 if (id
->num_alternatives
== 0)
3289 id
->num_alternatives
= 1;
3293 case DEFINE_PEEPHOLE
:
3294 id
->insn_code
= insn_code_number
;
3295 id
->insn_index
= insn_index_number
;
3296 id
->num_alternatives
= count_alternatives (exp
);
3297 if (id
->num_alternatives
== 0)
3298 id
->num_alternatives
= 1;
3302 case DEFINE_ASM_ATTRIBUTES
:
3304 id
->insn_index
= -1;
3305 id
->num_alternatives
= 1;
3307 got_define_asm_attributes
= 1;
3315 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3316 true or annul false is specified, and make a `struct delay_desc'. */
3319 gen_delay (rtx def
, int lineno
)
3321 struct delay_desc
*delay
;
3324 if (XVECLEN (def
, 1) % 3 != 0)
3326 error_with_line (lineno
,
3327 "number of elements in DEFINE_DELAY must"
3328 " be multiple of three");
3332 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3334 if (XVECEXP (def
, 1, i
+ 1))
3335 have_annul_true
= 1;
3336 if (XVECEXP (def
, 1, i
+ 2))
3337 have_annul_false
= 1;
3340 delay
= oballoc (struct delay_desc
);
3342 delay
->num
= ++num_delays
;
3343 delay
->next
= delays
;
3344 delay
->lineno
= lineno
;
3348 /* Names of attributes that could be possibly cached. */
3349 static const char *cached_attrs
[32];
3350 /* Number of such attributes. */
3351 static int cached_attr_count
;
3352 /* Bitmasks of possibly cached attributes. */
3353 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3354 static unsigned int attrs_to_cache
;
3355 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3357 /* Finds non-const attributes that could be possibly cached.
3358 When create is TRUE, fills in cached_attrs array.
3359 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3363 find_attrs_to_cache (rtx exp
, bool create
)
3367 struct attr_desc
*attr
;
3372 switch (GET_CODE (exp
))
3375 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3376 find_attrs_to_cache (XEXP (exp
, 0), create
);
3380 name
= XSTR (exp
, 0);
3381 if (name
== alternative_name
)
3383 for (i
= 0; i
< cached_attr_count
; i
++)
3384 if (name
== cached_attrs
[i
])
3386 if ((attrs_seen_once
& (1U << i
)) != 0)
3387 attrs_seen_more_than_once
|= (1U << i
);
3389 attrs_seen_once
|= (1U << i
);
3394 attr
= find_attr (&name
, 0);
3398 if (cached_attr_count
== 32)
3400 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3401 attrs_seen_once
|= (1U << cached_attr_count
);
3402 cached_attr_count
++;
3407 find_attrs_to_cache (XEXP (exp
, 0), create
);
3408 find_attrs_to_cache (XEXP (exp
, 1), create
);
3412 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3413 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3421 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3422 We use AND and IOR both for logical and bit-wise operations, so
3423 interpret them as logical unless they are inside a comparison expression. */
3425 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3426 #define FLG_BITWISE 1
3427 /* Set if cached attribute will be known initialized in else block after
3428 this condition. This is true for LHS of toplevel && and || and
3429 even for RHS of ||, but not for RHS of &&. */
3431 /* Set if cached attribute will be known initialized in then block after
3432 this condition. This is true for LHS of toplevel && and || and
3433 even for RHS of &&, but not for RHS of ||. */
3434 #define FLG_INSIDE 4
3435 /* Cleared when an operand of &&. */
3436 #define FLG_OUTSIDE_AND 8
3439 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
)
3441 int comparison_operator
= 0;
3443 struct attr_desc
*attr
;
3445 /* In order not to worry about operator precedence, surround our part of
3446 the expression with parentheses. */
3448 fprintf (outf
, "(");
3449 code
= GET_CODE (exp
);
3452 /* Binary operators. */
3455 fprintf (outf
, "(unsigned) ");
3461 comparison_operator
= FLG_BITWISE
;
3463 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3464 case AND
: case IOR
: case XOR
:
3465 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3466 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3468 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3469 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3470 flags
| comparison_operator
);
3475 flags
&= ~FLG_OUTSIDE_AND
;
3476 if (GET_CODE (XEXP (exp
, 0)) == code
3477 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3478 || (GET_CODE (XEXP (exp
, 0)) == NOT
3479 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3481 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3483 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3488 fprintf (outf
, " == ");
3491 fprintf (outf
, " != ");
3494 fprintf (outf
, " >= ");
3497 fprintf (outf
, " > ");
3500 fprintf (outf
, " >= (unsigned) ");
3503 fprintf (outf
, " > (unsigned) ");
3506 fprintf (outf
, " <= ");
3509 fprintf (outf
, " < ");
3512 fprintf (outf
, " <= (unsigned) ");
3515 fprintf (outf
, " < (unsigned) ");
3518 fprintf (outf
, " + ");
3521 fprintf (outf
, " - ");
3524 fprintf (outf
, " * ");
3527 fprintf (outf
, " / ");
3530 fprintf (outf
, " %% ");
3533 if (flags
& FLG_BITWISE
)
3534 fprintf (outf
, " & ");
3536 fprintf (outf
, " && ");
3539 if (flags
& FLG_BITWISE
)
3540 fprintf (outf
, " | ");
3542 fprintf (outf
, " || ");
3545 fprintf (outf
, " ^ ");
3548 fprintf (outf
, " << ");
3552 fprintf (outf
, " >> ");
3560 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3561 cached_x is only known to be initialized in then block. */
3562 flags
&= ~FLG_AFTER
;
3564 else if (code
== IOR
)
3566 if (flags
& FLG_OUTSIDE_AND
)
3567 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3568 cached_x is only known to be initialized in else block
3569 and else if conditions. */
3570 flags
&= ~FLG_INSIDE
;
3572 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3574 cached_x is not know to be initialized anywhere. */
3575 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3577 if ((code
== AND
|| code
== IOR
)
3578 && (GET_CODE (XEXP (exp
, 1)) == code
3579 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3580 || (GET_CODE (XEXP (exp
, 1)) == NOT
3581 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3583 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
);
3585 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3586 flags
| comparison_operator
);
3590 /* Special-case (not (eq_attrq "alternative" "x")) */
3591 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3593 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3595 fprintf (outf
, "which_alternative != %s",
3596 XSTR (XEXP (exp
, 0), 1));
3600 fprintf (outf
, "! ");
3602 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3606 /* Otherwise, fall through to normal unary operator. */
3608 /* Unary operators. */
3613 if (flags
& FLG_BITWISE
)
3614 fprintf (outf
, "~ ");
3616 fprintf (outf
, "! ");
3619 fprintf (outf
, "abs ");
3622 fprintf (outf
, "-");
3628 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3629 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3634 int set
= XINT (exp
, 0), bit
= 0;
3636 if (flags
& FLG_BITWISE
)
3637 fatal ("EQ_ATTR_ALT not valid inside comparison");
3640 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3642 if (!(set
& (set
- 1)))
3644 if (!(set
& 0xffff))
3667 fprintf (outf
, "which_alternative %s= %d",
3668 XINT (exp
, 1) ? "!" : "=", bit
);
3672 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3673 XINT (exp
, 1) ? "!" : "", set
);
3678 /* Comparison test of an attribute with a value. Most of these will
3679 have been removed by optimization. Handle "alternative"
3680 specially and give error if EQ_ATTR present inside a comparison. */
3682 if (flags
& FLG_BITWISE
)
3683 fatal ("EQ_ATTR not valid inside comparison");
3685 if (XSTR (exp
, 0) == alternative_name
)
3687 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3691 attr
= find_attr (&XSTR (exp
, 0), 0);
3694 /* Now is the time to expand the value of a constant attribute. */
3697 write_test_expr (outf
,
3698 evaluate_eq_attr (exp
, attr
,
3699 attr
->default_val
->value
,
3706 for (i
= 0; i
< cached_attr_count
; i
++)
3707 if (attr
->name
== cached_attrs
[i
])
3709 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3710 fprintf (outf
, "cached_%s", attr
->name
);
3711 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3713 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3714 attr
->name
, attr
->name
);
3715 if (flags
& FLG_AFTER
)
3716 attrs_cached_after
|= (1U << i
);
3717 if (flags
& FLG_INSIDE
)
3718 attrs_cached_inside
|= (1U << i
);
3719 attrs_cached
|= (1U << i
);
3722 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3723 fprintf (outf
, " == ");
3724 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3728 /* Comparison test of flags for define_delays. */
3730 if (flags
& FLG_BITWISE
)
3731 fatal ("ATTR_FLAG not valid inside comparison");
3732 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3735 /* See if an operand matches a predicate. */
3737 /* If only a mode is given, just ensure the mode matches the operand.
3738 If neither a mode nor predicate is given, error. */
3739 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3741 if (GET_MODE (exp
) == VOIDmode
)
3742 fatal ("null MATCH_OPERAND specified as test");
3744 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3745 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3748 fprintf (outf
, "%s (operands[%d], %smode)",
3749 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3752 /* Constant integer. */
3754 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3758 fprint_c_condition (outf
, XSTR (exp
, 0));
3759 if (flags
& FLG_BITWISE
)
3760 fprintf (outf
, " != 0");
3763 /* A random C expression. */
3765 fprint_c_condition (outf
, XSTR (exp
, 0));
3768 /* The address of the branch target. */
3771 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3772 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3776 /* The address of the current insn. We implement this actually as the
3777 address of the current insn for backward branches, but the last
3778 address of the next insn for forward branches, and both with
3779 adjustments that account for the worst-case possible stretching of
3780 intervening alignments between this insn and its destination. */
3781 fprintf (outf
, "insn_current_reference_address (insn)");
3785 fprintf (outf
, "%s", XSTR (exp
, 0));
3789 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3790 fprintf (outf
, " ? ");
3791 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3792 fprintf (outf
, " : ");
3793 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3797 fatal ("bad RTX code `%s' in attribute calculation\n",
3798 GET_RTX_NAME (code
));
3801 fprintf (outf
, ")");
3802 return attrs_cached
;
3805 /* Given an attribute value, return the maximum CONST_STRING argument
3806 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3809 max_attr_value (rtx exp
, int *unknownp
)
3814 switch (GET_CODE (exp
))
3817 current_max
= atoi (XSTR (exp
, 0));
3821 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3822 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3824 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3825 if (n
> current_max
)
3831 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3832 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3833 if (n
> current_max
)
3839 current_max
= INT_MAX
;
3846 /* Given an attribute value, return the minimum CONST_STRING argument
3847 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3850 min_attr_value (rtx exp
, int *unknownp
)
3855 switch (GET_CODE (exp
))
3858 current_min
= atoi (XSTR (exp
, 0));
3862 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3863 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3865 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3866 if (n
< current_min
)
3872 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3873 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3874 if (n
< current_min
)
3880 current_min
= INT_MAX
;
3887 /* Given an attribute value, return the result of ORing together all
3888 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3889 if the numeric value is not known. */
3892 or_attr_value (rtx exp
, int *unknownp
)
3897 switch (GET_CODE (exp
))
3900 current_or
= atoi (XSTR (exp
, 0));
3904 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3905 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3906 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3910 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3911 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3923 /* Scan an attribute value, possibly a conditional, and record what actions
3924 will be required to do any conditional tests in it.
3927 `must_extract' if we need to extract the insn operands
3928 `must_constrain' if we must compute `which_alternative'
3929 `address_used' if an address expression was used
3930 `length_used' if an (eq_attr "length" ...) was used
3934 walk_attr_value (rtx exp
)
3943 code
= GET_CODE (exp
);
3947 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3948 /* Since this is an arbitrary expression, it can look at anything.
3949 However, constant expressions do not depend on any particular
3951 must_extract
= must_constrain
= 1;
3960 must_extract
= must_constrain
= 1;
3964 if (XSTR (exp
, 0) == alternative_name
)
3965 must_extract
= must_constrain
= 1;
3966 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3986 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3991 walk_attr_value (XEXP (exp
, i
));
3995 if (XVEC (exp
, i
) != NULL
)
3996 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3997 walk_attr_value (XVECEXP (exp
, i
, j
));
4002 /* Write out a function to obtain the attribute for a given INSN. */
4005 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
4007 struct attr_value
*av
, *common_av
;
4010 /* Find the most used attribute value. Handle that as the `default' of the
4011 switch we will generate. */
4012 common_av
= find_most_used (attr
);
4014 /* Write out start of function, then all values with explicit `case' lines,
4015 then a `default', then the value with the most uses. */
4016 if (attr
->enum_name
)
4017 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4018 else if (!attr
->is_numeric
)
4019 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4021 fprintf (outf
, "int\n");
4023 /* If the attribute name starts with a star, the remainder is the name of
4024 the subroutine to use, instead of `get_attr_...'. */
4025 if (attr
->name
[0] == '*')
4026 fprintf (outf
, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4027 else if (attr
->is_const
== 0)
4028 fprintf (outf
, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4031 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4032 fprintf (outf
, "{\n");
4034 for (av
= attr
->first_value
; av
; av
= av
->next
)
4035 if (av
->num_insns
== 1)
4036 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4037 true_rtx
, av
->first_insn
->def
->insn_code
,
4038 av
->first_insn
->def
->insn_index
, 0);
4039 else if (av
->num_insns
!= 0)
4040 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4041 true_rtx
, -2, 0, 0);
4043 fprintf (outf
, "}\n\n");
4047 fprintf (outf
, "{\n");
4049 /* Find attributes that are worth caching in the conditions. */
4050 cached_attr_count
= 0;
4051 attrs_seen_more_than_once
= 0;
4052 for (av
= attr
->first_value
; av
; av
= av
->next
)
4054 attrs_seen_once
= 0;
4055 find_attrs_to_cache (av
->value
, true);
4057 /* Remove those that aren't worth caching from the array. */
4058 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4059 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4061 const char *name
= cached_attrs
[i
];
4062 struct attr_desc
*cached_attr
;
4064 cached_attrs
[j
] = name
;
4065 cached_attr
= find_attr (&name
, 0);
4066 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4067 if (cached_attr
->enum_name
)
4068 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4069 else if (!cached_attr
->is_numeric
)
4070 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4072 fprintf (outf
, " int");
4073 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4076 cached_attr_count
= j
;
4077 if (cached_attr_count
)
4078 fprintf (outf
, "\n");
4080 fprintf (outf
, " switch (recog_memoized (insn))\n");
4081 fprintf (outf
, " {\n");
4083 for (av
= attr
->first_value
; av
; av
= av
->next
)
4084 if (av
!= common_av
)
4085 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4087 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4088 fprintf (outf
, " }\n}\n\n");
4089 cached_attr_count
= 0;
4092 /* Given an AND tree of known true terms (because we are inside an `if' with
4093 that as the condition or are in an `else' clause) and an expression,
4094 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4095 the bulk of the work. */
4098 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4102 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4104 if (GET_CODE (known_true
) == AND
)
4106 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4107 insn_code
, insn_index
);
4108 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4109 insn_code
, insn_index
);
4114 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4120 /* Write out a series of tests and assignment statements to perform tests and
4121 sets of an attribute value. We are passed an indentation amount and prefix
4122 and suffix strings to write around each attribute value (e.g., "return"
4126 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
4127 const char *prefix
, const char *suffix
, rtx known_true
,
4128 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4130 if (GET_CODE (value
) == COND
)
4132 /* Assume the default value will be the default of the COND unless we
4133 find an always true expression. */
4134 rtx default_val
= XEXP (value
, 1);
4135 rtx our_known_true
= known_true
;
4140 if (cached_attr_count
)
4142 attrs_seen_once
= 0;
4143 attrs_seen_more_than_once
= 0;
4144 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4145 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4146 attrs_to_cache
|= attrs_seen_more_than_once
;
4149 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4154 /* Reset our_known_true after some time to not accumulate
4155 too much cruft (slowing down genattrtab). */
4157 our_known_true
= known_true
;
4158 testexp
= eliminate_known_true (our_known_true
,
4159 XVECEXP (value
, 0, i
),
4160 insn_code
, insn_index
);
4161 newexp
= attr_rtx (NOT
, testexp
);
4162 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4163 insn_code
, insn_index
);
4165 /* If the test expression is always true or if the next `known_true'
4166 expression is always false, this is the last case, so break
4167 out and let this value be the `else' case. */
4168 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4170 default_val
= XVECEXP (value
, 0, i
+ 1);
4174 /* Compute the expression to pass to our recursive call as being
4176 inner_true
= insert_right_side (AND
, our_known_true
,
4177 testexp
, insn_code
, insn_index
);
4179 /* If this is always false, skip it. */
4180 if (inner_true
== false_rtx
)
4183 attrs_cached_inside
= attrs_cached
;
4184 attrs_cached_after
= attrs_cached
;
4185 write_indent (outf
, indent
);
4186 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4188 write_test_expr (outf
, testexp
, attrs_cached
,
4189 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4190 attrs_cached
= attrs_cached_after
;
4191 fprintf (outf
, "\n");
4192 write_indent (outf
, indent
+ 2);
4193 fprintf (outf
, "{\n");
4195 write_attr_set (outf
, attr
, indent
+ 4,
4196 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4197 inner_true
, insn_code
, insn_index
,
4198 attrs_cached_inside
);
4199 write_indent (outf
, indent
+ 2);
4200 fprintf (outf
, "}\n");
4201 our_known_true
= newexp
;
4206 write_indent (outf
, indent
);
4207 fprintf (outf
, "else\n");
4208 write_indent (outf
, indent
+ 2);
4209 fprintf (outf
, "{\n");
4212 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4213 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4218 write_indent (outf
, indent
+ 2);
4219 fprintf (outf
, "}\n");
4224 write_indent (outf
, indent
);
4225 fprintf (outf
, "%s ", prefix
);
4226 write_attr_value (outf
, attr
, value
);
4227 fprintf (outf
, "%s\n", suffix
);
4231 /* Write a series of case statements for every instruction in list IE.
4232 INDENT is the amount of indentation to write before each case. */
4235 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4237 for (; ie
!= 0; ie
= ie
->next
)
4238 if (ie
->def
->insn_code
!= -1)
4240 write_indent (outf
, indent
);
4241 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4242 fprintf (outf
, "case %d: /* define_peephole, line %d */\n",
4243 ie
->def
->insn_code
, ie
->def
->lineno
);
4245 fprintf (outf
, "case %d: /* %s */\n",
4246 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4250 /* Write out the computation for one attribute value. */
4253 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4254 int write_case_lines
, const char *prefix
, const char *suffix
,
4255 int indent
, rtx known_true
)
4257 if (av
->num_insns
== 0)
4260 if (av
->has_asm_insn
)
4262 write_indent (outf
, indent
);
4263 fprintf (outf
, "case -1:\n");
4264 write_indent (outf
, indent
+ 2);
4265 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4266 write_indent (outf
, indent
+ 2);
4267 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4268 write_indent (outf
, indent
+ 2);
4269 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4272 if (write_case_lines
)
4273 write_insn_cases (outf
, av
->first_insn
, indent
);
4276 write_indent (outf
, indent
);
4277 fprintf (outf
, "default:\n");
4280 /* See what we have to do to output this value. */
4281 must_extract
= must_constrain
= address_used
= 0;
4282 walk_attr_value (av
->value
);
4286 write_indent (outf
, indent
+ 2);
4287 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4289 else if (must_extract
)
4291 write_indent (outf
, indent
+ 2);
4292 fprintf (outf
, "extract_insn_cached (insn);\n");
4296 if (av
->num_insns
== 1)
4297 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4298 known_true
, av
->first_insn
->def
->insn_code
,
4299 av
->first_insn
->def
->insn_index
, 0);
4301 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4302 known_true
, -2, 0, 0);
4304 if (strncmp (prefix
, "return", 6))
4306 write_indent (outf
, indent
+ 2);
4307 fprintf (outf
, "break;\n");
4309 fprintf (outf
, "\n");
4312 /* Utilities to write in various forms. */
4315 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4317 if (attr
->is_numeric
)
4321 fprintf (outf
, "%d", num
);
4323 if (num
> 9 || num
< 0)
4324 fprintf (outf
, " /* %#x */", num
);
4328 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4329 fprintf (outf
, "_");
4330 write_upcase (outf
, s
);
4335 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4339 switch (GET_CODE (value
))
4342 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4346 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4350 fprint_c_condition (outf
, XSTR (value
, 0));
4355 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4356 if (attr
->enum_name
)
4357 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4358 else if (!attr
->is_numeric
)
4359 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4360 else if (!attr2
->is_numeric
)
4361 fprintf (outf
, "(int)");
4363 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4364 (attr2
->is_const
? "" : "insn"));
4385 write_attr_value (outf
, attr
, XEXP (value
, 0));
4389 write_attr_value (outf
, attr
, XEXP (value
, 1));
4398 write_upcase (FILE *outf
, const char *str
)
4402 /* The argument of TOUPPER should not have side effects. */
4403 fputc (TOUPPER (*str
), outf
);
4409 write_indent (FILE *outf
, int indent
)
4411 for (; indent
> 8; indent
-= 8)
4412 fprintf (outf
, "\t");
4414 for (; indent
; indent
--)
4415 fprintf (outf
, " ");
4418 /* Write a subroutine that is given an insn that requires a delay slot, a
4419 delay slot ordinal, and a candidate insn. It returns nonzero if the
4420 candidate can be placed in the specified delay slot of the insn.
4422 We can write as many as three subroutines. `eligible_for_delay'
4423 handles normal delay slots, `eligible_for_annul_true' indicates that
4424 the specified insn can be annulled if the branch is true, and likewise
4425 for `eligible_for_annul_false'.
4427 KIND is a string distinguishing these three cases ("delay", "annul_true",
4428 or "annul_false"). */
4431 write_eligible_delay (FILE *outf
, const char *kind
)
4433 struct delay_desc
*delay
;
4437 struct attr_desc
*attr
;
4438 struct attr_value
*av
, *common_av
;
4441 /* Compute the maximum number of delay slots required. We use the delay
4442 ordinal times this number plus one, plus the slot number as an index into
4443 the appropriate predicate to test. */
4445 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4446 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4447 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4449 /* Write function prelude. */
4451 fprintf (outf
, "int\n");
4452 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4453 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4455 fprintf (outf
, "{\n");
4456 fprintf (outf
, " rtx_insn *insn;\n");
4457 fprintf (outf
, "\n");
4458 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4459 fprintf (outf
, "\n");
4460 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4461 converts a compound instruction into a loop. */
4462 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4463 fprintf (outf
, " return 0;\n");
4464 fprintf (outf
, "\n");
4466 /* If more than one delay type, find out which type the delay insn is. */
4470 attr
= find_attr (&delay_type_str
, 0);
4472 common_av
= find_most_used (attr
);
4474 fprintf (outf
, " insn = delay_insn;\n");
4475 fprintf (outf
, " switch (recog_memoized (insn))\n");
4476 fprintf (outf
, " {\n");
4478 sprintf (str
, " * %d;\n break;", max_slots
);
4479 for (av
= attr
->first_value
; av
; av
= av
->next
)
4480 if (av
!= common_av
)
4481 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4483 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4484 fprintf (outf
, " }\n\n");
4486 /* Ensure matched. Otherwise, shouldn't have been called. */
4487 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4490 /* If just one type of delay slot, write simple switch. */
4491 if (num_delays
== 1 && max_slots
== 1)
4493 fprintf (outf
, " insn = candidate_insn;\n");
4494 fprintf (outf
, " switch (recog_memoized (insn))\n");
4495 fprintf (outf
, " {\n");
4497 attr
= find_attr (&delay_1_0_str
, 0);
4499 common_av
= find_most_used (attr
);
4501 for (av
= attr
->first_value
; av
; av
= av
->next
)
4502 if (av
!= common_av
)
4503 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4505 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4506 fprintf (outf
, " }\n");
4511 /* Write a nested CASE. The first indicates which condition we need to
4512 test, and the inner CASE tests the condition. */
4513 fprintf (outf
, " insn = candidate_insn;\n");
4514 fprintf (outf
, " switch (slot)\n");
4515 fprintf (outf
, " {\n");
4517 for (delay
= delays
; delay
; delay
= delay
->next
)
4518 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4520 fprintf (outf
, " case %d:\n",
4521 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4522 fprintf (outf
, " switch (recog_memoized (insn))\n");
4523 fprintf (outf
, "\t{\n");
4525 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4527 attr
= find_attr (&pstr
, 0);
4529 common_av
= find_most_used (attr
);
4531 for (av
= attr
->first_value
; av
; av
= av
->next
)
4532 if (av
!= common_av
)
4533 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4535 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4536 fprintf (outf
, " }\n");
4539 fprintf (outf
, " default:\n");
4540 fprintf (outf
, " gcc_unreachable ();\n");
4541 fprintf (outf
, " }\n");
4544 fprintf (outf
, "}\n\n");
4547 /* This page contains miscellaneous utility routines. */
4549 /* Given a pointer to a (char *), return a malloc'ed string containing the
4550 next comma-separated element. Advance the pointer to after the string
4551 scanned, or the end-of-string. Return NULL if at end of string. */
4554 next_comma_elt (const char **pstr
)
4558 start
= scan_comma_elt (pstr
);
4563 return attr_string (start
, *pstr
- start
);
4566 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4567 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4568 replaced by a pointer to a canonical copy of the string. */
4570 static struct attr_desc
*
4571 find_attr (const char **name_p
, int create
)
4573 struct attr_desc
*attr
;
4575 const char *name
= *name_p
;
4577 /* Before we resort to using `strcmp', see if the string address matches
4578 anywhere. In most cases, it should have been canonicalized to do so. */
4579 if (name
== alternative_name
)
4582 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4583 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4584 if (name
== attr
->name
)
4587 /* Otherwise, do it the slow way. */
4588 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4589 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4591 *name_p
= attr
->name
;
4598 attr
= oballoc (struct attr_desc
);
4599 attr
->name
= DEF_ATTR_STRING (name
);
4600 attr
->enum_name
= 0;
4601 attr
->first_value
= attr
->default_val
= NULL
;
4602 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4603 attr
->next
= attrs
[index
];
4604 attrs
[index
] = attr
;
4606 *name_p
= attr
->name
;
4611 /* Create internal attribute with the given default value. */
4614 make_internal_attr (const char *name
, rtx value
, int special
)
4616 struct attr_desc
*attr
;
4618 attr
= find_attr (&name
, 1);
4619 gcc_assert (!attr
->default_val
);
4621 attr
->is_numeric
= 1;
4623 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4624 attr
->default_val
= get_attr_value (value
, attr
, -2);
4627 /* Find the most used value of an attribute. */
4629 static struct attr_value
*
4630 find_most_used (struct attr_desc
*attr
)
4632 struct attr_value
*av
;
4633 struct attr_value
*most_used
;
4639 for (av
= attr
->first_value
; av
; av
= av
->next
)
4640 if (av
->num_insns
> nuses
)
4641 nuses
= av
->num_insns
, most_used
= av
;
4646 /* Return (attr_value "n") */
4649 make_numeric_value (int n
)
4651 static rtx int_values
[20];
4655 gcc_assert (n
>= 0);
4657 if (n
< 20 && int_values
[n
])
4658 return int_values
[n
];
4660 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4661 exp
= attr_rtx (CONST_STRING
, p
);
4664 int_values
[n
] = exp
;
4670 copy_rtx_unchanging (rtx orig
)
4672 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4675 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4679 /* Determine if an insn has a constant number of delay slots, i.e., the
4680 number of delay slots is not a function of the length of the insn. */
4683 write_const_num_delay_slots (FILE *outf
)
4685 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4686 struct attr_value
*av
;
4690 fprintf (outf
, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4691 fprintf (outf
, "{\n");
4692 fprintf (outf
, " switch (recog_memoized (insn))\n");
4693 fprintf (outf
, " {\n");
4695 for (av
= attr
->first_value
; av
; av
= av
->next
)
4698 walk_attr_value (av
->value
);
4700 write_insn_cases (outf
, av
->first_insn
, 4);
4703 fprintf (outf
, " default:\n");
4704 fprintf (outf
, " return 1;\n");
4705 fprintf (outf
, " }\n}\n\n");
4709 /* Synthetic attributes used by insn-automata.c and the scheduler.
4710 These are primarily concerned with (define_insn_reservation)
4715 struct insn_reserv
*next
;
4718 int default_latency
;
4721 /* Sequence number of this insn. */
4724 /* Whether a (define_bypass) construct names this insn in its
4729 static struct insn_reserv
*all_insn_reservs
= 0;
4730 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4731 static size_t n_insn_reservs
;
4733 /* Store information from a DEFINE_INSN_RESERVATION for future
4734 attribute generation. */
4736 gen_insn_reserv (rtx def
)
4738 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4740 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4741 decl
->default_latency
= XINT (def
, 1);
4742 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4743 decl
->insn_num
= n_insn_reservs
;
4744 decl
->bypassed
= false;
4747 *last_insn_reserv_p
= decl
;
4748 last_insn_reserv_p
= &decl
->next
;
4752 /* Store information from a DEFINE_BYPASS for future attribute
4753 generation. The only thing we care about is the list of output
4754 insns, which will later be used to tag reservation structures with
4755 a 'bypassed' bit. */
4759 struct bypass_list
*next
;
4760 const char *pattern
;
4763 static struct bypass_list
*all_bypasses
;
4764 static size_t n_bypasses
;
4765 static size_t n_bypassed
;
4768 gen_bypass_1 (const char *s
, size_t len
)
4770 struct bypass_list
*b
;
4775 s
= attr_string (s
, len
);
4776 for (b
= all_bypasses
; b
; b
= b
->next
)
4777 if (s
== b
->pattern
)
4778 return; /* already got that one */
4780 b
= oballoc (struct bypass_list
);
4782 b
->next
= all_bypasses
;
4788 gen_bypass (rtx def
)
4790 const char *p
, *base
;
4792 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4795 gen_bypass_1 (base
, p
- base
);
4798 while (ISSPACE (*p
));
4801 gen_bypass_1 (base
, p
- base
);
4804 /* Find and mark all of the bypassed insns. */
4806 process_bypasses (void)
4808 struct bypass_list
*b
;
4809 struct insn_reserv
*r
;
4813 /* The reservation list is likely to be much longer than the bypass
4815 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4816 for (b
= all_bypasses
; b
; b
= b
->next
)
4817 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4825 /* Check that attribute NAME is used in define_insn_reservation condition
4826 EXP. Return true if it is. */
4828 check_tune_attr (const char *name
, rtx exp
)
4830 switch (GET_CODE (exp
))
4833 if (check_tune_attr (name
, XEXP (exp
, 0)))
4835 return check_tune_attr (name
, XEXP (exp
, 1));
4838 return (check_tune_attr (name
, XEXP (exp
, 0))
4839 && check_tune_attr (name
, XEXP (exp
, 1)));
4842 return XSTR (exp
, 0) == name
;
4849 /* Try to find a const attribute (usually cpu or tune) that is used
4850 in all define_insn_reservation conditions. */
4851 static struct attr_desc
*
4852 find_tune_attr (rtx exp
)
4854 struct attr_desc
*attr
;
4856 switch (GET_CODE (exp
))
4860 attr
= find_tune_attr (XEXP (exp
, 0));
4863 return find_tune_attr (XEXP (exp
, 1));
4866 if (XSTR (exp
, 0) == alternative_name
)
4869 attr
= find_attr (&XSTR (exp
, 0), 0);
4872 if (attr
->is_const
&& !attr
->is_special
)
4874 struct insn_reserv
*decl
;
4876 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4877 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4888 /* Create all of the attributes that describe automaton properties.
4889 Write the DFA and latency function prototypes to the files that
4890 need to have them, and write the init_sched_attrs(). */
4893 make_automaton_attrs (void)
4896 struct insn_reserv
*decl
;
4897 rtx code_exp
, lats_exp
, byps_exp
;
4898 struct attr_desc
*tune_attr
;
4900 if (n_insn_reservs
== 0)
4903 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4904 if (tune_attr
!= NULL
)
4906 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4907 struct attr_value
*val
;
4910 gcc_assert (tune_attr
->is_const
4911 && !tune_attr
->is_special
4912 && !tune_attr
->is_numeric
);
4914 /* Write the prototypes for all DFA functions. */
4915 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4917 if (val
== tune_attr
->default_val
)
4919 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4921 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
4922 XSTR (val
->value
, 0));
4924 fprintf (dfa_file
, "\n");
4926 /* Write the prototypes for all latency functions. */
4927 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4929 if (val
== tune_attr
->default_val
)
4931 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4932 fprintf (latency_file
,
4933 "extern int insn_default_latency_%s (rtx_insn *);\n",
4934 XSTR (val
->value
, 0));
4936 fprintf (latency_file
, "\n");
4938 /* Write the prototypes for all automaton functions. */
4939 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4941 if (val
== tune_attr
->default_val
)
4943 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4945 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
4946 "extern int insn_default_latency_%s (rtx_insn *);\n",
4947 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4949 fprintf (attr_file
, "\n");
4950 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
4951 fprintf (attr_file
, "int (*insn_default_latency) (rtx_insn *);\n");
4952 fprintf (attr_file
, "\n");
4953 fprintf (attr_file
, "void\n");
4954 fprintf (attr_file
, "init_sched_attrs (void)\n");
4955 fprintf (attr_file
, "{\n");
4957 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4961 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
4963 if (val
== tune_attr
->default_val
)
4965 for (decl
= all_insn_reservs
, i
= 0;
4971 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
4972 if (condexp
== false_rtx
)
4974 if (condexp
== true_rtx
)
4976 condexps
[i
] = condexp
;
4977 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
4978 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
4982 code_exp
= rtx_alloc (COND
);
4983 lats_exp
= rtx_alloc (COND
);
4986 XVEC (code_exp
, 0) = rtvec_alloc (j
);
4987 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
4991 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
4992 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
4996 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4997 XEXP (lats_exp
, 1) = make_numeric_value (0);
5004 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
5005 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
5007 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
5008 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5011 name
= XNEWVEC (char,
5012 sizeof ("*internal_dfa_insn_code_")
5013 + strlen (XSTR (val
->value
, 0)));
5014 strcpy (name
, "*internal_dfa_insn_code_");
5015 strcat (name
, XSTR (val
->value
, 0));
5016 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5017 strcpy (name
, "*insn_default_latency_");
5018 strcat (name
, XSTR (val
->value
, 0));
5019 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5024 fprintf (attr_file
, " if (");
5028 fprintf (attr_file
, " else if (");
5029 write_test_expr (attr_file
, test
, 0, 0);
5030 fprintf (attr_file
, ")\n");
5031 fprintf (attr_file
, " {\n");
5032 fprintf (attr_file
, " internal_dfa_insn_code\n");
5033 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5034 XSTR (val
->value
, 0));
5035 fprintf (attr_file
, " insn_default_latency\n");
5036 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5037 XSTR (val
->value
, 0));
5038 fprintf (attr_file
, " }\n");
5041 fprintf (attr_file
, " else\n");
5042 fprintf (attr_file
, " gcc_unreachable ();\n");
5043 fprintf (attr_file
, "}\n");
5044 fprintf (attr_file
, "\n");
5046 XDELETEVEC (condexps
);
5050 code_exp
= rtx_alloc (COND
);
5051 lats_exp
= rtx_alloc (COND
);
5053 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5054 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5056 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5057 XEXP (lats_exp
, 1) = make_numeric_value (0);
5059 for (decl
= all_insn_reservs
, i
= 0;
5061 decl
= decl
->next
, i
+= 2)
5063 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5064 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5066 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5067 XVECEXP (lats_exp
, 0, i
+1)
5068 = make_numeric_value (decl
->default_latency
);
5070 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5071 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5074 if (n_bypasses
== 0)
5075 byps_exp
= make_numeric_value (0);
5078 process_bypasses ();
5080 byps_exp
= rtx_alloc (COND
);
5081 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypassed
* 2);
5082 XEXP (byps_exp
, 1) = make_numeric_value (0);
5083 for (decl
= all_insn_reservs
, i
= 0;
5088 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5089 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5094 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5098 write_header (FILE *outf
)
5100 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5101 " from the machine description file `md'. */\n\n");
5103 fprintf (outf
, "#include \"config.h\"\n");
5104 fprintf (outf
, "#include \"system.h\"\n");
5105 fprintf (outf
, "#include \"coretypes.h\"\n");
5106 fprintf (outf
, "#include \"tm.h\"\n");
5107 fprintf (outf
, "#include \"input.h\"\n");
5108 fprintf (outf
, "#include \"alias.h\"\n");
5109 fprintf (outf
, "#include \"symtab.h\"\n");
5110 fprintf (outf
, "#include \"options.h\"\n");
5111 fprintf (outf
, "#include \"tree.h\"\n");
5112 fprintf (outf
, "#include \"varasm.h\"\n");
5113 fprintf (outf
, "#include \"stor-layout.h\"\n");
5114 fprintf (outf
, "#include \"calls.h\"\n");
5115 fprintf (outf
, "#include \"rtl.h\"\n");
5116 fprintf (outf
, "#include \"insn-attr.h\"\n");
5117 fprintf (outf
, "#include \"tm_p.h\"\n");
5118 fprintf (outf
, "#include \"insn-config.h\"\n");
5119 fprintf (outf
, "#include \"recog.h\"\n");
5120 fprintf (outf
, "#include \"regs.h\"\n");
5121 fprintf (outf
, "#include \"real.h\"\n");
5122 fprintf (outf
, "#include \"output.h\"\n");
5123 fprintf (outf
, "#include \"toplev.h\"\n");
5124 fprintf (outf
, "#include \"flags.h\"\n");
5125 fprintf (outf
, "#include \"function.h\"\n");
5126 fprintf (outf
, "#include \"emit-rtl.h\"\n");
5127 fprintf (outf
, "#include \"predict.h\"\n");
5128 fprintf (outf
, "\n");
5129 fprintf (outf
, "#define operands recog_data.operand\n\n");
5133 open_outfile (const char *file_name
)
5136 outf
= fopen (file_name
, "w");
5138 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5139 write_header (outf
);
5144 handle_arg (const char *arg
)
5149 attr_file_name
= &arg
[2];
5152 dfa_file_name
= &arg
[2];
5155 latency_file_name
= &arg
[2];
5163 main (int argc
, char **argv
)
5166 struct attr_desc
*attr
;
5167 struct insn_def
*id
;
5171 progname
= "genattrtab";
5173 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5174 return FATAL_EXIT_CODE
;
5176 attr_file
= open_outfile (attr_file_name
);
5177 dfa_file
= open_outfile (dfa_file_name
);
5178 latency_file
= open_outfile (latency_file_name
);
5180 obstack_init (hash_obstack
);
5181 obstack_init (temp_obstack
);
5183 /* Set up true and false rtx's */
5184 true_rtx
= rtx_alloc (CONST_INT
);
5185 XWINT (true_rtx
, 0) = 1;
5186 false_rtx
= rtx_alloc (CONST_INT
);
5187 XWINT (false_rtx
, 0) = 0;
5188 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5189 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5191 alternative_name
= DEF_ATTR_STRING ("alternative");
5192 length_str
= DEF_ATTR_STRING ("length");
5193 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5194 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5195 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5197 /* Read the machine description. */
5203 desc
= read_md_rtx (&lineno
, &insn_code_number
);
5207 switch (GET_CODE (desc
))
5210 case DEFINE_PEEPHOLE
:
5211 case DEFINE_ASM_ATTRIBUTES
:
5212 gen_insn (desc
, lineno
);
5216 case DEFINE_ENUM_ATTR
:
5217 gen_attr (desc
, lineno
);
5221 gen_delay (desc
, lineno
);
5224 case DEFINE_INSN_RESERVATION
:
5225 gen_insn_reserv (desc
);
5235 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
5236 insn_index_number
++;
5240 return FATAL_EXIT_CODE
;
5244 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5245 if (! got_define_asm_attributes
)
5247 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5248 XVEC (tem
, 0) = rtvec_alloc (0);
5252 /* Expand DEFINE_DELAY information into new attribute. */
5256 /* Make `insn_alternatives'. */
5257 insn_alternatives
= oballocvec (uint64_t, insn_code_number
);
5258 for (id
= defs
; id
; id
= id
->next
)
5259 if (id
->insn_code
>= 0)
5260 insn_alternatives
[id
->insn_code
]
5261 = (((uint64_t) 1) << id
->num_alternatives
) - 1;
5263 /* Make `insn_n_alternatives'. */
5264 insn_n_alternatives
= oballocvec (int, insn_code_number
);
5265 for (id
= defs
; id
; id
= id
->next
)
5266 if (id
->insn_code
>= 0)
5267 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5269 /* Construct extra attributes for automata. */
5270 make_automaton_attrs ();
5272 /* Prepare to write out attribute subroutines by checking everything stored
5273 away and building the attribute cases. */
5277 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5278 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5279 attr
->default_val
->value
5280 = check_attr_value (attr
->default_val
->value
, attr
);
5283 return FATAL_EXIT_CODE
;
5285 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5286 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5289 /* Construct extra attributes for `length'. */
5290 make_length_attrs ();
5292 /* Perform any possible optimizations to speed up compilation. */
5295 /* Now write out all the `gen_attr_...' routines. Do these before the
5296 special routines so that they get defined before they are used. */
5298 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5299 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5303 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5304 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5306 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5307 outf
= latency_file
;
5310 #undef IS_ATTR_GROUP
5312 if (! attr
->is_special
&& ! attr
->is_const
)
5313 write_attr_get (outf
, attr
);
5316 /* Write out delay eligibility information, if DEFINE_DELAY present.
5317 (The function to compute the number of delay slots will be written
5321 write_eligible_delay (attr_file
, "delay");
5322 if (have_annul_true
)
5323 write_eligible_delay (attr_file
, "annul_true");
5324 if (have_annul_false
)
5325 write_eligible_delay (attr_file
, "annul_false");
5328 /* Write out constant delay slot info. */
5329 write_const_num_delay_slots (attr_file
);
5331 write_length_unit_log (attr_file
);
5333 if (fclose (attr_file
) != 0)
5334 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5335 if (fclose (dfa_file
) != 0)
5336 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5337 if (fclose (latency_file
) != 0)
5338 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5340 return SUCCESS_EXIT_CODE
;