1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
100 #define strcmp_check(S1, S2) ((S1) == (S2) \
102 : (gcc_assert (strcmp ((S1), (S2))), 1))
104 #define strcmp_check(S1, S2) ((S1) != (S2))
109 #include "coretypes.h"
115 #include "gensupport.h"
120 /* Flags for make_internal_attr's `special' parameter. */
122 #define ATTR_SPECIAL (1 << 0)
124 static struct obstack obstack1
, obstack2
;
125 static struct obstack
*hash_obstack
= &obstack1
;
126 static struct obstack
*temp_obstack
= &obstack2
;
128 /* enough space to reserve for printing out ints */
129 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
131 /* Define structures used to record attributes and values. */
133 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
134 encountered, we store all the relevant information into a
135 `struct insn_def'. This is done to allow attribute definitions to occur
136 anywhere in the file. */
140 struct insn_def
*next
; /* Next insn in chain. */
141 rtx def
; /* The DEFINE_... */
142 int insn_code
; /* Instruction number. */
143 int insn_index
; /* Expression number in file, for errors. */
144 int lineno
; /* Line number. */
145 int num_alternatives
; /* Number of alternatives. */
146 int vec_idx
; /* Index of attribute vector in `def'. */
149 /* Once everything has been read in, we store in each attribute value a list
150 of insn codes that have that value. Here is the structure used for the
155 struct insn_ent
*next
; /* Next in chain. */
156 struct insn_def
*def
; /* Instruction definition. */
159 /* Each value of an attribute (either constant or computed) is assigned a
160 structure which is used as the listhead of the insns that have that
165 rtx value
; /* Value of attribute. */
166 struct attr_value
*next
; /* Next attribute value in chain. */
167 struct insn_ent
*first_insn
; /* First insn with this value. */
168 int num_insns
; /* Number of insns with this value. */
169 int has_asm_insn
; /* True if this value used for `asm' insns */
172 /* Structure for each attribute. */
176 char *name
; /* Name of attribute. */
177 const char *enum_name
; /* Enum name for DEFINE_ENUM_NAME. */
178 struct attr_desc
*next
; /* Next attribute. */
179 struct attr_value
*first_value
; /* First value of this attribute. */
180 struct attr_value
*default_val
; /* Default value for this attribute. */
181 int lineno
: 24; /* Line number. */
182 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
183 unsigned is_const
: 1; /* Attribute value constant for each run. */
184 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
187 /* Structure for each DEFINE_DELAY. */
191 rtx def
; /* DEFINE_DELAY expression. */
192 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
193 int num
; /* Number of DEFINE_DELAY, starting at 1. */
194 int lineno
; /* Line number. */
197 struct attr_value_list
199 struct attr_value
*av
;
201 struct attr_desc
*attr
;
202 struct attr_value_list
*next
;
205 /* Listheads of above structures. */
207 /* This one is indexed by the first character of the attribute name. */
208 #define MAX_ATTRS_INDEX 256
209 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
210 static struct insn_def
*defs
;
211 static struct delay_desc
*delays
;
212 struct attr_value_list
**insn_code_values
;
214 /* Other variables. */
216 static int insn_code_number
;
217 static int insn_index_number
;
218 static int got_define_asm_attributes
;
219 static int must_extract
;
220 static int must_constrain
;
221 static int address_used
;
222 static int length_used
;
223 static int num_delays
;
224 static int have_annul_true
, have_annul_false
;
225 static int num_insn_ents
;
227 /* Stores, for each insn code, the number of constraint alternatives. */
229 static int *insn_n_alternatives
;
231 /* Stores, for each insn code, a bitmap that has bits on for each possible
234 static int *insn_alternatives
;
236 /* Used to simplify expressions. */
238 static rtx true_rtx
, false_rtx
;
240 /* Used to reduce calls to `strcmp' */
242 static const char *alternative_name
;
243 static const char *length_str
;
244 static const char *delay_type_str
;
245 static const char *delay_1_0_str
;
246 static const char *num_delay_slots_str
;
248 /* Simplify an expression. Only call the routine if there is something to
250 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
251 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
252 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
254 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
256 /* Forward declarations of functions used before their definitions, only. */
257 static char *attr_string (const char *, int);
258 static char *attr_printf (unsigned int, const char *, ...)
260 static rtx
make_numeric_value (int);
261 static struct attr_desc
*find_attr (const char **, int);
262 static rtx
mk_attr_alt (int);
263 static char *next_comma_elt (const char **);
264 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
265 static rtx
copy_boolean (rtx
);
266 static int compares_alternatives_p (rtx
);
267 static void make_internal_attr (const char *, rtx
, int);
268 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
269 static void walk_attr_value (rtx
);
270 static int max_attr_value (rtx
, int*);
271 static int min_attr_value (rtx
, int*);
272 static int or_attr_value (rtx
, int*);
273 static rtx
simplify_test_exp (rtx
, int, int);
274 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
275 static rtx
copy_rtx_unchanging (rtx
);
276 static bool attr_alt_subset_p (rtx
, rtx
);
277 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
278 static void clear_struct_flag (rtx
);
279 static void write_attr_valueq (FILE *, struct attr_desc
*, const char *);
280 static struct attr_value
*find_most_used (struct attr_desc
*);
281 static void write_attr_set (FILE *, struct attr_desc
*, int, rtx
,
282 const char *, const char *, rtx
,
283 int, int, unsigned int);
284 static void write_attr_case (FILE *, struct attr_desc
*,
286 int, const char *, const char *, int, rtx
);
287 static void write_attr_value (FILE *, struct attr_desc
*, rtx
);
288 static void write_upcase (FILE *, const char *);
289 static void write_indent (FILE *, int);
290 static rtx
identity_fn (rtx
);
291 static rtx
zero_fn (rtx
);
292 static rtx
one_fn (rtx
);
293 static rtx
max_fn (rtx
);
294 static rtx
min_fn (rtx
);
296 #define oballoc(T) XOBNEW (hash_obstack, T)
297 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
299 /* This gen* file is unique, in that it writes out multiple files.
301 Before GCC 4.8, insn-attrtab.c was written out containing many large
302 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
303 a parallel build, and even made it impossible to build GCC on machines
304 with relatively small RAM space (PR other/29442). Therefore, the
305 atrribute functions/tables are now written out to three separate
306 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
307 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
308 rest goes to ATTR_FILE_NAME. */
310 static const char *attr_file_name
= NULL
;
311 static const char *dfa_file_name
= NULL
;
312 static const char *latency_file_name
= NULL
;
314 static FILE *attr_file
, *dfa_file
, *latency_file
;
316 /* Hash table for sharing RTL and strings. */
318 /* Each hash table slot is a bucket containing a chain of these structures.
319 Strings are given negative hash codes; RTL expressions are given positive
324 struct attr_hash
*next
; /* Next structure in the bucket. */
325 int hashcode
; /* Hash code of this rtx or string. */
328 char *str
; /* The string (negative hash codes) */
329 rtx rtl
; /* or the RTL recorded here. */
333 /* Now here is the hash table. When recording an RTL, it is added to
334 the slot whose index is the hash code mod the table size. Note
335 that the hash table is used for several kinds of RTL (see attr_rtx)
336 and for strings. While all these live in the same table, they are
337 completely independent, and the hash code is computed differently
340 #define RTL_HASH_SIZE 4093
341 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
343 /* Here is how primitive or already-shared RTL's hash
345 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
347 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
350 attr_hash_add_rtx (int hashcode
, rtx rtl
)
354 h
= XOBNEW (hash_obstack
, struct attr_hash
);
355 h
->hashcode
= hashcode
;
357 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
358 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
361 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
364 attr_hash_add_string (int hashcode
, char *str
)
368 h
= XOBNEW (hash_obstack
, struct attr_hash
);
369 h
->hashcode
= -hashcode
;
371 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
372 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
375 /* Generate an RTL expression, but avoid duplicates.
376 Set the ATTR_PERMANENT_P flag for these permanent objects.
378 In some cases we cannot uniquify; then we return an ordinary
379 impermanent rtx with ATTR_PERMANENT_P clear.
383 rtx attr_rtx (code, [element1, ..., elementn]) */
386 attr_rtx_1 (enum rtx_code code
, va_list p
)
388 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
391 struct obstack
*old_obstack
= rtl_obstack
;
393 /* For each of several cases, search the hash table for an existing entry.
394 Use that entry if one is found; otherwise create a new RTL and add it
397 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
399 rtx arg0
= va_arg (p
, rtx
);
401 /* A permanent object cannot point to impermanent ones. */
402 if (! ATTR_PERMANENT_P (arg0
))
404 rt_val
= rtx_alloc (code
);
405 XEXP (rt_val
, 0) = arg0
;
409 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
410 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
411 if (h
->hashcode
== hashcode
412 && GET_CODE (h
->u
.rtl
) == code
413 && XEXP (h
->u
.rtl
, 0) == arg0
)
418 rtl_obstack
= hash_obstack
;
419 rt_val
= rtx_alloc (code
);
420 XEXP (rt_val
, 0) = arg0
;
423 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
424 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
425 || GET_RTX_CLASS (code
) == RTX_COMPARE
426 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
428 rtx arg0
= va_arg (p
, rtx
);
429 rtx arg1
= va_arg (p
, rtx
);
431 /* A permanent object cannot point to impermanent ones. */
432 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
434 rt_val
= rtx_alloc (code
);
435 XEXP (rt_val
, 0) = arg0
;
436 XEXP (rt_val
, 1) = arg1
;
440 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
441 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
442 if (h
->hashcode
== hashcode
443 && GET_CODE (h
->u
.rtl
) == code
444 && XEXP (h
->u
.rtl
, 0) == arg0
445 && XEXP (h
->u
.rtl
, 1) == arg1
)
450 rtl_obstack
= hash_obstack
;
451 rt_val
= rtx_alloc (code
);
452 XEXP (rt_val
, 0) = arg0
;
453 XEXP (rt_val
, 1) = arg1
;
456 else if (code
== SYMBOL_REF
457 || (GET_RTX_LENGTH (code
) == 1
458 && GET_RTX_FORMAT (code
)[0] == 's'))
460 char *arg0
= va_arg (p
, char *);
462 arg0
= DEF_ATTR_STRING (arg0
);
464 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
465 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
466 if (h
->hashcode
== hashcode
467 && GET_CODE (h
->u
.rtl
) == code
468 && XSTR (h
->u
.rtl
, 0) == arg0
)
473 rtl_obstack
= hash_obstack
;
474 rt_val
= rtx_alloc (code
);
475 XSTR (rt_val
, 0) = arg0
;
476 if (code
== SYMBOL_REF
)
478 X0EXP (rt_val
, 1) = NULL_RTX
;
479 X0EXP (rt_val
, 2) = NULL_RTX
;
483 else if (GET_RTX_LENGTH (code
) == 2
484 && GET_RTX_FORMAT (code
)[0] == 's'
485 && GET_RTX_FORMAT (code
)[1] == 's')
487 char *arg0
= va_arg (p
, char *);
488 char *arg1
= va_arg (p
, char *);
490 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
491 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
492 if (h
->hashcode
== hashcode
493 && GET_CODE (h
->u
.rtl
) == code
494 && XSTR (h
->u
.rtl
, 0) == arg0
495 && XSTR (h
->u
.rtl
, 1) == arg1
)
500 rtl_obstack
= hash_obstack
;
501 rt_val
= rtx_alloc (code
);
502 XSTR (rt_val
, 0) = arg0
;
503 XSTR (rt_val
, 1) = arg1
;
506 else if (code
== CONST_INT
)
508 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
518 int i
; /* Array indices... */
519 const char *fmt
; /* Current rtx's format... */
521 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
523 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
524 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
528 case '0': /* Unused field. */
531 case 'i': /* An integer? */
532 XINT (rt_val
, i
) = va_arg (p
, int);
535 case 'w': /* A wide integer? */
536 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
539 case 's': /* A string? */
540 XSTR (rt_val
, i
) = va_arg (p
, char *);
543 case 'e': /* An expression? */
544 case 'u': /* An insn? Same except when printing. */
545 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
548 case 'E': /* An RTX vector? */
549 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
559 rtl_obstack
= old_obstack
;
560 attr_hash_add_rtx (hashcode
, rt_val
);
561 ATTR_PERMANENT_P (rt_val
) = 1;
566 attr_rtx (enum rtx_code code
, ...)
572 result
= attr_rtx_1 (code
, p
);
577 /* Create a new string printed with the printf line arguments into a space
578 of at most LEN bytes:
580 rtx attr_printf (len, format, [arg1, ..., argn]) */
583 attr_printf (unsigned int len
, const char *fmt
, ...)
590 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
592 vsprintf (str
, fmt
, p
);
595 return DEF_ATTR_STRING (str
);
599 attr_eq (const char *name
, const char *value
)
601 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
607 return XSTR (make_numeric_value (n
), 0);
610 /* Return a permanent (possibly shared) copy of a string STR (not assumed
611 to be null terminated) with LEN bytes. */
614 attr_string (const char *str
, int len
)
621 /* Compute the hash code. */
622 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
623 for (i
= 1; i
< len
; i
+= 2)
624 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
626 hashcode
= -hashcode
;
628 /* Search the table for the string. */
629 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
630 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
631 && !strncmp (h
->u
.str
, str
, len
))
632 return h
->u
.str
; /* <-- return if found. */
634 /* Not found; create a permanent copy and add it to the hash table. */
635 new_str
= XOBNEWVAR (hash_obstack
, char, len
+ 1);
636 memcpy (new_str
, str
, len
);
638 attr_hash_add_string (hashcode
, new_str
);
639 copy_md_ptr_loc (new_str
, str
);
641 return new_str
; /* Return the new string. */
644 /* Check two rtx's for equality of contents,
645 taking advantage of the fact that if both are hashed
646 then they can't be equal unless they are the same object. */
649 attr_equal_p (rtx x
, rtx y
)
651 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
652 && rtx_equal_p (x
, y
)));
655 /* Copy an attribute value expression,
656 descending to all depths, but not copying any
657 permanent hashed subexpressions. */
660 attr_copy_rtx (rtx orig
)
665 const char *format_ptr
;
667 /* No need to copy a permanent object. */
668 if (ATTR_PERMANENT_P (orig
))
671 code
= GET_CODE (orig
);
688 copy
= rtx_alloc (code
);
689 PUT_MODE (copy
, GET_MODE (orig
));
690 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
691 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
692 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
694 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
696 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
698 switch (*format_ptr
++)
701 XEXP (copy
, i
) = XEXP (orig
, i
);
702 if (XEXP (orig
, i
) != NULL
)
703 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
708 XVEC (copy
, i
) = XVEC (orig
, i
);
709 if (XVEC (orig
, i
) != NULL
)
711 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
712 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
713 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
719 XINT (copy
, i
) = XINT (orig
, i
);
723 XWINT (copy
, i
) = XWINT (orig
, i
);
728 XSTR (copy
, i
) = XSTR (orig
, i
);
738 /* Given a test expression for an attribute, ensure it is validly formed.
739 IS_CONST indicates whether the expression is constant for each compiler
740 run (a constant expression may not test any particular insn).
742 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
743 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
744 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
746 Update the string address in EQ_ATTR expression to be the same used
747 in the attribute (or `alternative_name') to speed up subsequent
748 `find_attr' calls and eliminate most `strcmp' calls.
750 Return the new expression, if any. */
753 check_attr_test (rtx exp
, int is_const
, int lineno
)
755 struct attr_desc
*attr
;
756 struct attr_value
*av
;
757 const char *name_ptr
, *p
;
760 switch (GET_CODE (exp
))
763 /* Handle negation test. */
764 if (XSTR (exp
, 1)[0] == '!')
765 return check_attr_test (attr_rtx (NOT
,
766 attr_eq (XSTR (exp
, 0),
770 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
772 attr
= find_attr (&XSTR (exp
, 0), 0);
775 if (! strcmp (XSTR (exp
, 0), "alternative"))
776 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
778 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
781 if (is_const
&& ! attr
->is_const
)
782 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
785 /* Copy this just to make it permanent,
786 so expressions using it can be permanent too. */
787 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
789 /* It shouldn't be possible to simplify the value given to a
790 constant attribute, so don't expand this until it's time to
791 write the test expression. */
793 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
795 if (attr
->is_numeric
)
797 for (p
= XSTR (exp
, 1); *p
; p
++)
799 fatal ("attribute `%s' takes only numeric values",
804 for (av
= attr
->first_value
; av
; av
= av
->next
)
805 if (GET_CODE (av
->value
) == CONST_STRING
806 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
810 fatal ("unknown value `%s' for `%s' attribute",
811 XSTR (exp
, 1), XSTR (exp
, 0));
816 if (! strcmp (XSTR (exp
, 0), "alternative"))
820 name_ptr
= XSTR (exp
, 1);
821 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
822 set
|= 1 << atoi (p
);
824 return mk_attr_alt (set
);
828 /* Make an IOR tree of the possible values. */
830 name_ptr
= XSTR (exp
, 1);
831 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
833 newexp
= attr_eq (XSTR (exp
, 0), p
);
834 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
837 return check_attr_test (orexp
, is_const
, lineno
);
846 /* Either TRUE or FALSE. */
854 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
855 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
859 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
863 exp
= attr_rtx (MATCH_TEST
, XSTR (exp
, 0));
864 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
869 fatal ("RTL operator \"%s\" not valid in constant attribute test",
870 GET_RTX_NAME (GET_CODE (exp
)));
871 /* These cases can't be simplified. */
872 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
875 case LE
: case LT
: case GT
: case GE
:
876 case LEU
: case LTU
: case GTU
: case GEU
:
878 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
879 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
880 exp
= attr_rtx (GET_CODE (exp
),
881 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
882 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
883 /* These cases can't be simplified. */
884 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
890 /* These cases are valid for constant attributes, but can't be
892 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
893 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
897 fatal ("RTL operator \"%s\" not valid in attribute test",
898 GET_RTX_NAME (GET_CODE (exp
)));
904 /* Given an expression, ensure that it is validly formed and that all named
905 attribute values are valid for the given attribute. Issue a fatal error
906 if not. If no attribute is specified, assume a numeric attribute.
908 Return a perhaps modified replacement expression for the value. */
911 check_attr_value (rtx exp
, struct attr_desc
*attr
)
913 struct attr_value
*av
;
917 switch (GET_CODE (exp
))
920 if (attr
&& ! attr
->is_numeric
)
922 error_with_line (attr
->lineno
,
923 "CONST_INT not valid for non-numeric attribute %s",
928 if (INTVAL (exp
) < 0)
930 error_with_line (attr
->lineno
,
931 "negative numeric value specified for attribute %s",
938 if (! strcmp (XSTR (exp
, 0), "*"))
941 if (attr
== 0 || attr
->is_numeric
)
947 error_with_line (attr
? attr
->lineno
: 0,
948 "non-numeric value for numeric attribute %s",
949 attr
? attr
->name
: "internal");
955 for (av
= attr
->first_value
; av
; av
= av
->next
)
956 if (GET_CODE (av
->value
) == CONST_STRING
957 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
961 error_with_line (attr
->lineno
,
962 "unknown value `%s' for `%s' attribute",
963 XSTR (exp
, 0), attr
? attr
->name
: "internal");
967 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
968 attr
? attr
->is_const
: 0,
969 attr
? attr
->lineno
: 0);
970 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
971 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
979 if (attr
&& !attr
->is_numeric
)
981 error_with_line (attr
->lineno
,
982 "invalid operation `%s' for non-numeric"
983 " attribute value", GET_RTX_NAME (GET_CODE (exp
)));
990 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
991 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1000 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1004 if (XVECLEN (exp
, 0) % 2 != 0)
1006 error_with_line (attr
->lineno
,
1007 "first operand of COND must have even length");
1011 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1013 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1014 attr
? attr
->is_const
: 0,
1015 attr
? attr
->lineno
: 0);
1016 XVECEXP (exp
, 0, i
+ 1)
1017 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1020 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1025 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1027 error_with_line (attr
? attr
->lineno
: 0,
1028 "unknown attribute `%s' in ATTR",
1030 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1031 error_with_line (attr
->lineno
,
1032 "non-constant attribute `%s' referenced from `%s'",
1033 XSTR (exp
, 0), attr
->name
);
1035 && attr
->is_numeric
!= attr2
->is_numeric
)
1036 error_with_line (attr
->lineno
,
1037 "numeric attribute mismatch calling `%s' from `%s'",
1038 XSTR (exp
, 0), attr
->name
);
1043 /* A constant SYMBOL_REF is valid as a constant attribute test and
1044 is expanded later by make_canonical into a COND. In a non-constant
1045 attribute test, it is left be. */
1046 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1049 error_with_line (attr
? attr
->lineno
: 0,
1050 "invalid operation `%s' for attribute value",
1051 GET_RTX_NAME (GET_CODE (exp
)));
1058 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1059 It becomes a COND with each test being (eq_attr "alternative" "n") */
1062 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1064 int num_alt
= id
->num_alternatives
;
1068 if (XVECLEN (exp
, 1) != num_alt
)
1070 error_with_line (id
->lineno
,
1071 "bad number of entries in SET_ATTR_ALTERNATIVE");
1075 /* Make a COND with all tests but the last. Select the last value via the
1077 condexp
= rtx_alloc (COND
);
1078 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1080 for (i
= 0; i
< num_alt
- 1; i
++)
1083 p
= attr_numeral (i
);
1085 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1086 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1089 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1091 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1094 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1095 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1098 convert_set_attr (rtx exp
, struct insn_def
*id
)
1101 const char *name_ptr
;
1105 /* See how many alternative specified. */
1106 n
= n_comma_elts (XSTR (exp
, 1));
1108 return attr_rtx (SET
,
1109 attr_rtx (ATTR
, XSTR (exp
, 0)),
1110 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1112 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1113 XSTR (newexp
, 0) = XSTR (exp
, 0);
1114 XVEC (newexp
, 1) = rtvec_alloc (n
);
1116 /* Process each comma-separated name. */
1117 name_ptr
= XSTR (exp
, 1);
1119 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1120 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1122 return convert_set_attr_alternative (newexp
, id
);
1125 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1126 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1132 struct insn_def
*id
;
1133 struct attr_desc
*attr
;
1137 for (id
= defs
; id
; id
= id
->next
)
1139 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1142 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1144 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1145 switch (GET_CODE (value
))
1148 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1150 error_with_line (id
->lineno
, "bad attribute set");
1155 case SET_ATTR_ALTERNATIVE
:
1156 value
= convert_set_attr_alternative (value
, id
);
1160 value
= convert_set_attr (value
, id
);
1164 error_with_line (id
->lineno
, "invalid attribute code %s",
1165 GET_RTX_NAME (GET_CODE (value
)));
1168 if (value
== NULL_RTX
)
1171 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1173 error_with_line (id
->lineno
, "unknown attribute %s",
1174 XSTR (XEXP (value
, 0), 0));
1178 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1179 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1184 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1185 expressions by converting them into a COND. This removes cases from this
1186 program. Also, replace an attribute value of "*" with the default attribute
1190 make_canonical (struct attr_desc
*attr
, rtx exp
)
1195 switch (GET_CODE (exp
))
1198 exp
= make_numeric_value (INTVAL (exp
));
1202 if (! strcmp (XSTR (exp
, 0), "*"))
1204 if (attr
== 0 || attr
->default_val
== 0)
1205 fatal ("(attr_value \"*\") used in invalid context");
1206 exp
= attr
->default_val
->value
;
1209 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1214 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1216 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1217 This makes the COND something that won't be considered an arbitrary
1218 expression by walk_attr_value. */
1219 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1220 exp
= check_attr_value (exp
, attr
);
1224 newexp
= rtx_alloc (COND
);
1225 XVEC (newexp
, 0) = rtvec_alloc (2);
1226 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1227 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1229 XEXP (newexp
, 1) = XEXP (exp
, 2);
1232 /* Fall through to COND case since this is now a COND. */
1239 /* First, check for degenerate COND. */
1240 if (XVECLEN (exp
, 0) == 0)
1241 return make_canonical (attr
, XEXP (exp
, 1));
1242 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1244 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1246 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1247 XVECEXP (exp
, 0, i
+ 1)
1248 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1249 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1265 copy_boolean (rtx exp
)
1267 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1268 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1269 copy_boolean (XEXP (exp
, 1)));
1270 if (GET_CODE (exp
) == MATCH_OPERAND
)
1272 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1273 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1275 else if (GET_CODE (exp
) == EQ_ATTR
)
1277 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1278 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1284 /* Given a value and an attribute description, return a `struct attr_value *'
1285 that represents that value. This is either an existing structure, if the
1286 value has been previously encountered, or a newly-created structure.
1288 `insn_code' is the code of an insn whose attribute has the specified
1289 value (-2 if not processing an insn). We ensure that all insns for
1290 a given value have the same number of alternatives if the value checks
1293 static struct attr_value
*
1294 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1296 struct attr_value
*av
;
1299 value
= make_canonical (attr
, value
);
1300 if (compares_alternatives_p (value
))
1302 if (insn_code
< 0 || insn_alternatives
== NULL
)
1303 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1305 num_alt
= insn_alternatives
[insn_code
];
1308 for (av
= attr
->first_value
; av
; av
= av
->next
)
1309 if (rtx_equal_p (value
, av
->value
)
1310 && (num_alt
== 0 || av
->first_insn
== NULL
1311 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1314 av
= oballoc (struct attr_value
);
1316 av
->next
= attr
->first_value
;
1317 attr
->first_value
= av
;
1318 av
->first_insn
= NULL
;
1320 av
->has_asm_insn
= 0;
1325 /* After all DEFINE_DELAYs have been read in, create internal attributes
1326 to generate the required routines.
1328 First, we compute the number of delay slots for each insn (as a COND of
1329 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1330 delay type is specified, we compute a similar function giving the
1331 DEFINE_DELAY ordinal for each insn.
1333 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1334 tells whether a given insn can be in that delay slot.
1336 Normal attribute filling and optimization expands these to contain the
1337 information needed to handle delay slots. */
1340 expand_delays (void)
1342 struct delay_desc
*delay
;
1348 /* First, generate data for `num_delay_slots' function. */
1350 condexp
= rtx_alloc (COND
);
1351 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1352 XEXP (condexp
, 1) = make_numeric_value (0);
1354 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1356 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1357 XVECEXP (condexp
, 0, i
+ 1)
1358 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1361 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1363 /* If more than one delay type, do the same for computing the delay type. */
1366 condexp
= rtx_alloc (COND
);
1367 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1368 XEXP (condexp
, 1) = make_numeric_value (0);
1370 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1372 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1373 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1376 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1379 /* For each delay possibility and delay slot, compute an eligibility
1380 attribute for non-annulled insns and for each type of annulled (annul
1381 if true and annul if false). */
1382 for (delay
= delays
; delay
; delay
= delay
->next
)
1384 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1386 condexp
= XVECEXP (delay
->def
, 1, i
);
1388 condexp
= false_rtx
;
1389 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1390 make_numeric_value (1), make_numeric_value (0));
1392 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1393 "*delay_%d_%d", delay
->num
, i
/ 3);
1394 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1396 if (have_annul_true
)
1398 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1399 if (condexp
== 0) condexp
= false_rtx
;
1400 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1401 make_numeric_value (1),
1402 make_numeric_value (0));
1403 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1404 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1405 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1408 if (have_annul_false
)
1410 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1411 if (condexp
== 0) condexp
= false_rtx
;
1412 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1413 make_numeric_value (1),
1414 make_numeric_value (0));
1415 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1416 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1417 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1423 /* Once all attributes and insns have been read and checked, we construct for
1424 each attribute value a list of all the insns that have that value for
1428 fill_attr (struct attr_desc
*attr
)
1430 struct attr_value
*av
;
1431 struct insn_ent
*ie
;
1432 struct insn_def
*id
;
1436 /* Don't fill constant attributes. The value is independent of
1437 any particular insn. */
1441 for (id
= defs
; id
; id
= id
->next
)
1443 /* If no value is specified for this insn for this attribute, use the
1446 if (XVEC (id
->def
, id
->vec_idx
))
1447 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1448 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1450 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1453 av
= attr
->default_val
;
1455 av
= get_attr_value (value
, attr
, id
->insn_code
);
1457 ie
= oballoc (struct insn_ent
);
1459 insert_insn_ent (av
, ie
);
1463 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1464 test that checks relative positions of insns (uses MATCH_DUP or PC).
1465 If so, replace it with what is obtained by passing the expression to
1466 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1467 recursively on each value (including the default value). Otherwise,
1468 return the value returned by NO_ADDRESS_FN applied to EXP. */
1471 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1472 rtx (*address_fn
) (rtx
))
1477 if (GET_CODE (exp
) == COND
)
1479 /* See if any tests use addresses. */
1481 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1482 walk_attr_value (XVECEXP (exp
, 0, i
));
1485 return (*address_fn
) (exp
);
1487 /* Make a new copy of this COND, replacing each element. */
1488 newexp
= rtx_alloc (COND
);
1489 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1490 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1492 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1493 XVECEXP (newexp
, 0, i
+ 1)
1494 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1495 no_address_fn
, address_fn
);
1498 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1499 no_address_fn
, address_fn
);
1504 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1507 walk_attr_value (XEXP (exp
, 0));
1509 return (*address_fn
) (exp
);
1511 return attr_rtx (IF_THEN_ELSE
,
1512 substitute_address (XEXP (exp
, 0),
1513 no_address_fn
, address_fn
),
1514 substitute_address (XEXP (exp
, 1),
1515 no_address_fn
, address_fn
),
1516 substitute_address (XEXP (exp
, 2),
1517 no_address_fn
, address_fn
));
1520 return (*no_address_fn
) (exp
);
1523 /* Make new attributes from the `length' attribute. The following are made,
1524 each corresponding to a function called from `shorten_branches' or
1527 *insn_default_length This is the length of the insn to be returned
1528 by `get_attr_length' before `shorten_branches'
1529 has been called. In each case where the length
1530 depends on relative addresses, the largest
1531 possible is used. This routine is also used
1532 to compute the initial size of the insn.
1534 *insn_variable_length_p This returns 1 if the insn's length depends
1535 on relative addresses, zero otherwise.
1537 *insn_current_length This is only called when it is known that the
1538 insn has a variable length and returns the
1539 current length, based on relative addresses.
1543 make_length_attrs (void)
1545 static const char *new_names
[] =
1547 "*insn_default_length",
1549 "*insn_variable_length_p",
1550 "*insn_current_length"
1552 static rtx (*const no_address_fn
[]) (rtx
)
1553 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1554 static rtx (*const address_fn
[]) (rtx
)
1555 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1557 struct attr_desc
*length_attr
, *new_attr
;
1558 struct attr_value
*av
, *new_av
;
1559 struct insn_ent
*ie
, *new_ie
;
1561 /* See if length attribute is defined. If so, it must be numeric. Make
1562 it special so we don't output anything for it. */
1563 length_attr
= find_attr (&length_str
, 0);
1564 if (length_attr
== 0)
1567 if (! length_attr
->is_numeric
)
1568 fatal ("length attribute must be numeric");
1570 length_attr
->is_const
= 0;
1571 length_attr
->is_special
= 1;
1573 /* Make each new attribute, in turn. */
1574 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1576 make_internal_attr (new_names
[i
],
1577 substitute_address (length_attr
->default_val
->value
,
1578 no_address_fn
[i
], address_fn
[i
]),
1580 new_attr
= find_attr (&new_names
[i
], 0);
1581 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1582 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1584 new_av
= get_attr_value (substitute_address (av
->value
,
1587 new_attr
, ie
->def
->insn_code
);
1588 new_ie
= oballoc (struct insn_ent
);
1589 new_ie
->def
= ie
->def
;
1590 insert_insn_ent (new_av
, new_ie
);
1595 /* Utility functions called from above routine. */
1598 identity_fn (rtx exp
)
1604 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1606 return make_numeric_value (0);
1610 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1612 return make_numeric_value (1);
1619 return make_numeric_value (max_attr_value (exp
, &unknown
));
1626 return make_numeric_value (min_attr_value (exp
, &unknown
));
1630 write_length_unit_log (FILE *outf
)
1632 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1633 struct attr_value
*av
;
1634 struct insn_ent
*ie
;
1635 unsigned int length_unit_log
, length_or
;
1640 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1641 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1642 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1643 length_or
|= or_attr_value (av
->value
, &unknown
);
1646 if (length_attr
== NULL
|| unknown
)
1647 length_unit_log
= 0;
1650 length_or
= ~length_or
;
1651 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1654 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1657 /* Compute approximate cost of the expression. Used to decide whether
1658 expression is cheap enough for inline. */
1660 attr_rtx_cost (rtx x
)
1666 code
= GET_CODE (x
);
1679 /* Alternatives don't result into function call. */
1680 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1687 const char *fmt
= GET_RTX_FORMAT (code
);
1688 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1694 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1695 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1698 cost
+= attr_rtx_cost (XEXP (x
, i
));
1708 /* Take a COND expression and see if any of the conditions in it can be
1709 simplified. If any are known true or known false for the particular insn
1710 code, the COND can be further simplified.
1712 Also call ourselves on any COND operations that are values of this COND.
1714 We do not modify EXP; rather, we make and return a new rtx. */
1717 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1720 /* We store the desired contents here,
1721 then build a new expression if they don't match EXP. */
1722 rtx defval
= XEXP (exp
, 1);
1723 rtx new_defval
= XEXP (exp
, 1);
1724 int len
= XVECLEN (exp
, 0);
1725 rtx
*tests
= XNEWVEC (rtx
, len
);
1729 /* This lets us free all storage allocated below, if appropriate. */
1730 obstack_finish (rtl_obstack
);
1732 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1734 /* See if default value needs simplification. */
1735 if (GET_CODE (defval
) == COND
)
1736 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1738 /* Simplify the subexpressions, and see what tests we can get rid of. */
1740 for (i
= 0; i
< len
; i
+= 2)
1742 rtx newtest
, newval
;
1744 /* Simplify this test. */
1745 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1748 newval
= tests
[i
+ 1];
1749 /* See if this value may need simplification. */
1750 if (GET_CODE (newval
) == COND
)
1751 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1753 /* Look for ways to delete or combine this test. */
1754 if (newtest
== true_rtx
)
1756 /* If test is true, make this value the default
1757 and discard this + any following tests. */
1759 defval
= tests
[i
+ 1];
1760 new_defval
= newval
;
1763 else if (newtest
== false_rtx
)
1765 /* If test is false, discard it and its value. */
1766 for (j
= i
; j
< len
- 2; j
++)
1767 tests
[j
] = tests
[j
+ 2];
1772 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1774 /* If this value and the value for the prev test are the same,
1778 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1779 insn_code
, insn_index
);
1781 /* Delete this test/value. */
1782 for (j
= i
; j
< len
- 2; j
++)
1783 tests
[j
] = tests
[j
+ 2];
1789 tests
[i
+ 1] = newval
;
1792 /* If the last test in a COND has the same value
1793 as the default value, that test isn't needed. */
1795 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1798 /* See if we changed anything. */
1799 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1802 for (i
= 0; i
< len
; i
++)
1803 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1811 if (GET_CODE (defval
) == COND
)
1812 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1820 rtx newexp
= rtx_alloc (COND
);
1822 XVEC (newexp
, 0) = rtvec_alloc (len
);
1823 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1824 XEXP (newexp
, 1) = new_defval
;
1831 /* Remove an insn entry from an attribute value. */
1834 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1836 struct insn_ent
*previe
;
1838 if (av
->first_insn
== ie
)
1839 av
->first_insn
= ie
->next
;
1842 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1844 previe
->next
= ie
->next
;
1848 if (ie
->def
->insn_code
== -1)
1849 av
->has_asm_insn
= 0;
1854 /* Insert an insn entry in an attribute value list. */
1857 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1859 ie
->next
= av
->first_insn
;
1860 av
->first_insn
= ie
;
1862 if (ie
->def
->insn_code
== -1)
1863 av
->has_asm_insn
= 1;
1868 /* This is a utility routine to take an expression that is a tree of either
1869 AND or IOR expressions and insert a new term. The new term will be
1870 inserted at the right side of the first node whose code does not match
1871 the root. A new node will be created with the root's code. Its left
1872 side will be the old right side and its right side will be the new
1875 If the `term' is itself a tree, all its leaves will be inserted. */
1878 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1882 /* Avoid consing in some special cases. */
1883 if (code
== AND
&& term
== true_rtx
)
1885 if (code
== AND
&& term
== false_rtx
)
1887 if (code
== AND
&& exp
== true_rtx
)
1889 if (code
== AND
&& exp
== false_rtx
)
1891 if (code
== IOR
&& term
== true_rtx
)
1893 if (code
== IOR
&& term
== false_rtx
)
1895 if (code
== IOR
&& exp
== true_rtx
)
1897 if (code
== IOR
&& exp
== false_rtx
)
1899 if (attr_equal_p (exp
, term
))
1902 if (GET_CODE (term
) == code
)
1904 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1905 insn_code
, insn_index
);
1906 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1907 insn_code
, insn_index
);
1912 if (GET_CODE (exp
) == code
)
1914 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1915 term
, insn_code
, insn_index
);
1916 if (new_rtx
!= XEXP (exp
, 1))
1917 /* Make a copy of this expression and call recursively. */
1918 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1924 /* Insert the new term. */
1925 newexp
= attr_rtx (code
, exp
, term
);
1928 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1931 /* If we have an expression which AND's a bunch of
1932 (not (eq_attrq "alternative" "n"))
1933 terms, we may have covered all or all but one of the possible alternatives.
1934 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1936 This routine is passed an expression and either AND or IOR. It returns a
1937 bitmask indicating which alternatives are mentioned within EXP. */
1940 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1943 if (GET_CODE (exp
) == code
)
1944 return compute_alternative_mask (XEXP (exp
, 0), code
)
1945 | compute_alternative_mask (XEXP (exp
, 1), code
);
1947 else if (code
== AND
&& GET_CODE (exp
) == NOT
1948 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1949 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1950 string
= XSTR (XEXP (exp
, 0), 1);
1952 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1953 && XSTR (exp
, 0) == alternative_name
)
1954 string
= XSTR (exp
, 1);
1956 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1958 if (code
== AND
&& XINT (exp
, 1))
1959 return XINT (exp
, 0);
1961 if (code
== IOR
&& !XINT (exp
, 1))
1962 return XINT (exp
, 0);
1970 return 1 << (string
[0] - '0');
1971 return 1 << atoi (string
);
1974 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1975 attribute with the value represented by that bit. */
1978 make_alternative_compare (int mask
)
1980 return mk_attr_alt (mask
);
1983 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1984 of "attr" for this insn code. From that value, we can compute a test
1985 showing when the EQ_ATTR will be true. This routine performs that
1986 computation. If a test condition involves an address, we leave the EQ_ATTR
1987 intact because addresses are only valid for the `length' attribute.
1989 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1990 it refers. VALUE is the value of that attribute for the insn
1991 corresponding to INSN_CODE and INSN_INDEX. */
1994 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1995 int insn_code
, int insn_index
)
2002 while (GET_CODE (value
) == ATTR
)
2004 struct attr_value
*av
= NULL
;
2006 attr
= find_attr (&XSTR (value
, 0), 0);
2008 if (insn_code_values
)
2010 struct attr_value_list
*iv
;
2011 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2012 if (iv
->attr
== attr
)
2020 struct insn_ent
*ie
;
2021 for (av
= attr
->first_value
; av
; av
= av
->next
)
2022 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2023 if (ie
->def
->insn_code
== insn_code
)
2033 switch (GET_CODE (value
))
2036 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2047 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2048 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
2049 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
2050 for (p
= string
; *p
; p
++)
2053 newexp
= attr_rtx (EQ
, value
,
2054 attr_rtx (SYMBOL_REF
,
2055 DEF_ATTR_STRING (string
)));
2060 /* We construct an IOR of all the cases for which the
2061 requested attribute value is present. Since we start with
2062 FALSE, if it is not present, FALSE will be returned.
2064 Each case is the AND of the NOT's of the previous conditions with the
2065 current condition; in the default case the current condition is TRUE.
2067 For each possible COND value, call ourselves recursively.
2069 The extra TRUE and FALSE expressions will be eliminated by another
2070 call to the simplification routine. */
2075 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2077 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2078 insn_code
, insn_index
);
2080 right
= insert_right_side (AND
, andexp
, this_cond
,
2081 insn_code
, insn_index
);
2082 right
= insert_right_side (AND
, right
,
2083 evaluate_eq_attr (exp
, attr
,
2086 insn_code
, insn_index
),
2087 insn_code
, insn_index
);
2088 orexp
= insert_right_side (IOR
, orexp
, right
,
2089 insn_code
, insn_index
);
2091 /* Add this condition into the AND expression. */
2092 newexp
= attr_rtx (NOT
, this_cond
);
2093 andexp
= insert_right_side (AND
, andexp
, newexp
,
2094 insn_code
, insn_index
);
2097 /* Handle the default case. */
2098 right
= insert_right_side (AND
, andexp
,
2099 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2100 insn_code
, insn_index
),
2101 insn_code
, insn_index
);
2102 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2109 /* If uses an address, must return original expression. But set the
2110 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2113 walk_attr_value (newexp
);
2117 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2118 return copy_rtx_unchanging (exp
);
2125 /* This routine is called when an AND of a term with a tree of AND's is
2126 encountered. If the term or its complement is present in the tree, it
2127 can be replaced with TRUE or FALSE, respectively.
2129 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2130 be true and hence are complementary.
2132 There is one special case: If we see
2133 (and (not (eq_attr "att" "v1"))
2134 (eq_attr "att" "v2"))
2135 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2136 replace the term, not anything in the AND tree. So we pass a pointer to
2140 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2145 int left_eliminates_term
, right_eliminates_term
;
2147 if (GET_CODE (exp
) == AND
)
2149 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2150 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2151 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2153 newexp
= attr_rtx (AND
, left
, right
);
2155 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2159 else if (GET_CODE (exp
) == IOR
)
2161 /* For the IOR case, we do the same as above, except that we can
2162 only eliminate `term' if both sides of the IOR would do so. */
2164 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2165 left_eliminates_term
= (temp
== true_rtx
);
2168 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2169 right_eliminates_term
= (temp
== true_rtx
);
2171 if (left_eliminates_term
&& right_eliminates_term
)
2174 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2176 newexp
= attr_rtx (IOR
, left
, right
);
2178 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2182 /* Check for simplifications. Do some extra checking here since this
2183 routine is called so many times. */
2188 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2191 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2194 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2196 if (attr_alt_subset_p (*pterm
, exp
))
2199 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2202 if (attr_alt_subset_p (exp
, *pterm
))
2208 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2210 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2213 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2219 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2220 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2222 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2225 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2231 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2232 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2234 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2237 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2243 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2245 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2249 else if (GET_CODE (exp
) == NOT
)
2251 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2255 else if (GET_CODE (*pterm
) == NOT
)
2257 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2261 else if (attr_equal_p (exp
, *pterm
))
2267 /* Similar to `simplify_and_tree', but for IOR trees. */
2270 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2275 int left_eliminates_term
, right_eliminates_term
;
2277 if (GET_CODE (exp
) == IOR
)
2279 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2280 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2281 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2283 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2285 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2289 else if (GET_CODE (exp
) == AND
)
2291 /* For the AND case, we do the same as above, except that we can
2292 only eliminate `term' if both sides of the AND would do so. */
2294 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2295 left_eliminates_term
= (temp
== false_rtx
);
2298 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2299 right_eliminates_term
= (temp
== false_rtx
);
2301 if (left_eliminates_term
&& right_eliminates_term
)
2304 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2306 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2308 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2312 if (attr_equal_p (exp
, *pterm
))
2315 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2318 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2321 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2322 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2323 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2326 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2327 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2328 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2334 /* Simplify test expression and use temporary obstack in order to avoid
2335 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2336 and avoid unnecessary copying if possible. */
2339 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2342 struct obstack
*old
;
2343 if (ATTR_IND_SIMPLIFIED_P (exp
))
2346 rtl_obstack
= temp_obstack
;
2347 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2349 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2351 return attr_copy_rtx (x
);
2354 /* Returns true if S1 is a subset of S2. */
2357 attr_alt_subset_p (rtx s1
, rtx s2
)
2359 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2362 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2365 return !(XINT (s1
, 0) & XINT (s2
, 0));
2371 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2378 /* Returns true if S1 is a subset of complement of S2. */
2381 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2383 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2386 return !(XINT (s1
, 0) & XINT (s2
, 0));
2389 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2392 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2402 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2405 attr_alt_intersection (rtx s1
, rtx s2
)
2407 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2409 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2412 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2415 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2418 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2421 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2426 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2431 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2434 attr_alt_union (rtx s1
, rtx s2
)
2436 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2438 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2441 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2444 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2447 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2450 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2456 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2460 /* Return EQ_ATTR_ALT expression representing complement of S. */
2463 attr_alt_complement (rtx s
)
2465 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2467 XINT (result
, 0) = XINT (s
, 0);
2468 XINT (result
, 1) = 1 - XINT (s
, 1);
2473 /* Return EQ_ATTR_ALT expression representing set containing elements set
2479 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2481 XINT (result
, 0) = e
;
2482 XINT (result
, 1) = 0;
2487 /* Given an expression, see if it can be simplified for a particular insn
2488 code based on the values of other attributes being tested. This can
2489 eliminate nested get_attr_... calls.
2491 Note that if an endless recursion is specified in the patterns, the
2492 optimization will loop. However, it will do so in precisely the cases where
2493 an infinite recursion loop could occur during compilation. It's better that
2497 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2500 struct attr_desc
*attr
;
2501 struct attr_value
*av
;
2502 struct insn_ent
*ie
;
2503 struct attr_value_list
*iv
;
2506 bool left_alt
, right_alt
;
2508 /* Don't re-simplify something we already simplified. */
2509 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2512 switch (GET_CODE (exp
))
2515 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2516 if (left
== false_rtx
)
2518 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2519 if (right
== false_rtx
)
2522 if (GET_CODE (left
) == EQ_ATTR_ALT
2523 && GET_CODE (right
) == EQ_ATTR_ALT
)
2525 exp
= attr_alt_intersection (left
, right
);
2526 return simplify_test_exp (exp
, insn_code
, insn_index
);
2529 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2530 present on both sides, apply the distributive law since this will
2531 yield simplifications. */
2532 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2533 && compute_alternative_mask (left
, IOR
)
2534 && compute_alternative_mask (right
, IOR
))
2536 if (GET_CODE (left
) == IOR
)
2543 newexp
= attr_rtx (IOR
,
2544 attr_rtx (AND
, left
, XEXP (right
, 0)),
2545 attr_rtx (AND
, left
, XEXP (right
, 1)));
2547 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2550 /* Try with the term on both sides. */
2551 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2552 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2553 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2555 if (left
== false_rtx
|| right
== false_rtx
)
2557 else if (left
== true_rtx
)
2561 else if (right
== true_rtx
)
2565 /* See if all or all but one of the insn's alternatives are specified
2566 in this tree. Optimize if so. */
2568 if (GET_CODE (left
) == NOT
)
2569 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2570 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2572 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2575 if (GET_CODE (right
) == NOT
)
2576 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2577 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2579 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2580 && XINT (right
, 1));
2583 && (GET_CODE (left
) == AND
2585 || GET_CODE (right
) == AND
2588 i
= compute_alternative_mask (exp
, AND
);
2589 if (i
& ~insn_alternatives
[insn_code
])
2590 fatal ("invalid alternative specified for pattern number %d",
2593 /* If all alternatives are excluded, this is false. */
2594 i
^= insn_alternatives
[insn_code
];
2597 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2599 /* If just one excluded, AND a comparison with that one to the
2600 front of the tree. The others will be eliminated by
2601 optimization. We do not want to do this if the insn has one
2602 alternative and we have tested none of them! */
2603 left
= make_alternative_compare (i
);
2604 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2605 newexp
= attr_rtx (AND
, left
, right
);
2607 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2611 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2613 newexp
= attr_rtx (AND
, left
, right
);
2614 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2619 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2620 if (left
== true_rtx
)
2622 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2623 if (right
== true_rtx
)
2626 if (GET_CODE (left
) == EQ_ATTR_ALT
2627 && GET_CODE (right
) == EQ_ATTR_ALT
)
2629 exp
= attr_alt_union (left
, right
);
2630 return simplify_test_exp (exp
, insn_code
, insn_index
);
2633 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2634 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2635 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2637 if (right
== true_rtx
|| left
== true_rtx
)
2639 else if (left
== false_rtx
)
2643 else if (right
== false_rtx
)
2648 /* Test for simple cases where the distributive law is useful. I.e.,
2649 convert (ior (and (x) (y))
2655 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2656 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2658 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2660 left
= XEXP (left
, 0);
2662 newexp
= attr_rtx (AND
, left
, right
);
2663 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2667 convert (ior (and (y) (x))
2669 to (and (ior (y) (z))
2671 Note that we want the common term to stay at the end.
2674 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2675 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2677 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2680 right
= XEXP (right
, 1);
2681 newexp
= attr_rtx (AND
, left
, right
);
2682 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2685 /* See if all or all but one of the insn's alternatives are specified
2686 in this tree. Optimize if so. */
2688 else if (insn_code
>= 0
2689 && (GET_CODE (left
) == IOR
2690 || (GET_CODE (left
) == EQ_ATTR_ALT
2692 || (GET_CODE (left
) == EQ_ATTR
2693 && XSTR (left
, 0) == alternative_name
)
2694 || GET_CODE (right
) == IOR
2695 || (GET_CODE (right
) == EQ_ATTR_ALT
2696 && !XINT (right
, 1))
2697 || (GET_CODE (right
) == EQ_ATTR
2698 && XSTR (right
, 0) == alternative_name
)))
2700 i
= compute_alternative_mask (exp
, IOR
);
2701 if (i
& ~insn_alternatives
[insn_code
])
2702 fatal ("invalid alternative specified for pattern number %d",
2705 /* If all alternatives are included, this is true. */
2706 i
^= insn_alternatives
[insn_code
];
2709 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2711 /* If just one excluded, IOR a comparison with that one to the
2712 front of the tree. The others will be eliminated by
2713 optimization. We do not want to do this if the insn has one
2714 alternative and we have tested none of them! */
2715 left
= make_alternative_compare (i
);
2716 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2717 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2719 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2723 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2725 newexp
= attr_rtx (IOR
, left
, right
);
2726 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2731 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2733 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2734 insn_code
, insn_index
);
2738 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2739 if (GET_CODE (left
) == NOT
)
2740 return XEXP (left
, 0);
2742 if (left
== false_rtx
)
2744 if (left
== true_rtx
)
2747 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2749 exp
= attr_alt_complement (left
);
2750 return simplify_test_exp (exp
, insn_code
, insn_index
);
2753 /* Try to apply De`Morgan's laws. */
2754 if (GET_CODE (left
) == IOR
)
2756 newexp
= attr_rtx (AND
,
2757 attr_rtx (NOT
, XEXP (left
, 0)),
2758 attr_rtx (NOT
, XEXP (left
, 1)));
2760 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2762 else if (GET_CODE (left
) == AND
)
2764 newexp
= attr_rtx (IOR
,
2765 attr_rtx (NOT
, XEXP (left
, 0)),
2766 attr_rtx (NOT
, XEXP (left
, 1)));
2768 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2770 else if (left
!= XEXP (exp
, 0))
2772 newexp
= attr_rtx (NOT
, left
);
2778 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2782 if (XSTR (exp
, 0) == alternative_name
)
2784 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2788 /* Look at the value for this insn code in the specified attribute.
2789 We normally can replace this comparison with the condition that
2790 would give this insn the values being tested for. */
2792 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2797 if (insn_code_values
)
2799 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2800 if (iv
->attr
== attr
)
2808 for (av
= attr
->first_value
; av
; av
= av
->next
)
2809 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2810 if (ie
->def
->insn_code
== insn_code
)
2817 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2818 insn_code
, insn_index
);
2819 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2820 if (attr_rtx_cost(x
) < 7)
2830 /* We have already simplified this expression. Simplifying it again
2831 won't buy anything unless we weren't given a valid insn code
2832 to process (i.e., we are canonicalizing something.). */
2834 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2835 return copy_rtx_unchanging (newexp
);
2840 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2841 otherwise return 0. */
2844 tests_attr_p (rtx p
, struct attr_desc
*attr
)
2849 if (GET_CODE (p
) == EQ_ATTR
)
2851 if (XSTR (p
, 0) != attr
->name
)
2856 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2857 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2858 for (i
= 0; i
< ie
; i
++)
2863 if (tests_attr_p (XEXP (p
, i
), attr
))
2868 je
= XVECLEN (p
, i
);
2869 for (j
= 0; j
< je
; ++j
)
2870 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2879 /* Calculate a topological sorting of all attributes so that
2880 all attributes only depend on attributes in front of it.
2881 Place the result in *RET (which is a pointer to an array of
2882 attr_desc pointers), and return the size of that array. */
2885 get_attr_order (struct attr_desc
***ret
)
2889 struct attr_desc
*attr
;
2890 struct attr_desc
**all
, **sorted
;
2892 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2893 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2895 all
= XNEWVEC (struct attr_desc
*, num
);
2896 sorted
= XNEWVEC (struct attr_desc
*, num
);
2897 handled
= XCNEWVEC (char, num
);
2899 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2900 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2904 for (i
= 0; i
< num
; i
++)
2905 if (all
[i
]->is_const
)
2906 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2908 /* We have only few attributes hence we can live with the inner
2909 loop being O(n^2), unlike the normal fast variants of topological
2913 for (i
= 0; i
< num
; i
++)
2916 /* Let's see if I depends on anything interesting. */
2918 for (k
= 0; k
< num
; k
++)
2921 struct attr_value
*av
;
2922 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2923 if (av
->num_insns
!= 0)
2924 if (tests_attr_p (av
->value
, all
[k
]))
2928 /* Something in I depends on K. */
2933 /* Nothing in I depended on anything intersting, so
2936 sorted
[j
++] = all
[i
];
2942 for (j
= 0; j
< num
; j
++)
2944 struct attr_desc
*attr2
;
2945 struct attr_value
*av
;
2948 fprintf (stderr
, "%s depends on: ", attr
->name
);
2949 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2950 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2951 if (!attr2
->is_const
)
2952 for (av
= attr
->first_value
; av
; av
= av
->next
)
2953 if (av
->num_insns
!= 0)
2954 if (tests_attr_p (av
->value
, attr2
))
2956 fprintf (stderr
, "%s, ", attr2
->name
);
2959 fprintf (stderr
, "\n");
2967 /* Optimize the attribute lists by seeing if we can determine conditional
2968 values from the known values of other attributes. This will save subroutine
2969 calls during the compilation. */
2972 optimize_attrs (void)
2974 struct attr_desc
*attr
;
2975 struct attr_value
*av
;
2976 struct insn_ent
*ie
;
2979 struct attr_value_list
*ivbuf
;
2980 struct attr_value_list
*iv
;
2981 struct attr_desc
**topsort
;
2984 /* For each insn code, make a list of all the insn_ent's for it,
2985 for all values for all attributes. */
2987 if (num_insn_ents
== 0)
2990 /* Make 2 extra elements, for "code" values -2 and -1. */
2991 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2993 /* Offset the table address so we can index by -2 or -1. */
2994 insn_code_values
+= 2;
2996 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2998 /* Create the chain of insn*attr values such that we see dependend
2999 attributes after their dependencies. As we use a stack via the
3000 next pointers start from the end of the topological order. */
3001 topnum
= get_attr_order (&topsort
);
3002 for (i
= topnum
- 1; i
>= 0; i
--)
3003 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
3004 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
3006 iv
->attr
= topsort
[i
];
3009 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
3010 insn_code_values
[ie
->def
->insn_code
] = iv
;
3015 /* Sanity check on num_insn_ents. */
3016 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
3018 /* Process one insn code at a time. */
3019 for (i
= -2; i
< insn_code_number
; i
++)
3021 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3022 We use it to mean "already simplified for this insn". */
3023 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3024 clear_struct_flag (iv
->av
->value
);
3026 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3028 struct obstack
*old
= rtl_obstack
;
3033 if (GET_CODE (av
->value
) != COND
)
3036 rtl_obstack
= temp_obstack
;
3038 while (GET_CODE (newexp
) == COND
)
3040 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
3041 ie
->def
->insn_index
);
3042 if (newexp2
== newexp
)
3048 /* If we created a new value for this instruction, and it's
3049 cheaper than the old value, and overall cheap, use that
3050 one as specific value for the current instruction.
3051 The last test is to avoid exploding the get_attr_ function
3052 sizes for no much gain. */
3053 if (newexp
!= av
->value
3054 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
3055 && attr_rtx_cost (newexp
) < 26
3058 newexp
= attr_copy_rtx (newexp
);
3059 remove_insn_ent (av
, ie
);
3060 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
3062 insert_insn_ent (av
, ie
);
3068 free (insn_code_values
- 2);
3069 insn_code_values
= NULL
;
3072 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3075 clear_struct_flag (rtx x
)
3082 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3083 if (ATTR_IND_SIMPLIFIED_P (x
))
3086 code
= GET_CODE (x
);
3105 /* Compare the elements. If any pair of corresponding elements
3106 fail to match, return 0 for the whole things. */
3108 fmt
= GET_RTX_FORMAT (code
);
3109 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3115 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3116 clear_struct_flag (XVECEXP (x
, i
, j
));
3120 clear_struct_flag (XEXP (x
, i
));
3126 /* Add attribute value NAME to the beginning of ATTR's list. */
3129 add_attr_value (struct attr_desc
*attr
, const char *name
)
3131 struct attr_value
*av
;
3133 av
= oballoc (struct attr_value
);
3134 av
->value
= attr_rtx (CONST_STRING
, name
);
3135 av
->next
= attr
->first_value
;
3136 attr
->first_value
= av
;
3137 av
->first_insn
= NULL
;
3139 av
->has_asm_insn
= 0;
3142 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3145 gen_attr (rtx exp
, int lineno
)
3147 struct enum_type
*et
;
3148 struct enum_value
*ev
;
3149 struct attr_desc
*attr
;
3150 const char *name_ptr
;
3153 /* Make a new attribute structure. Check for duplicate by looking at
3154 attr->default_val, since it is initialized by this routine. */
3155 attr
= find_attr (&XSTR (exp
, 0), 1);
3156 if (attr
->default_val
)
3158 error_with_line (lineno
, "duplicate definition for attribute %s",
3160 message_with_line (attr
->lineno
, "previous definition");
3163 attr
->lineno
= lineno
;
3165 if (GET_CODE (exp
) == DEFINE_ENUM_ATTR
)
3167 attr
->enum_name
= XSTR (exp
, 1);
3168 et
= lookup_enum_type (XSTR (exp
, 1));
3169 if (!et
|| !et
->md_p
)
3170 error_with_line (lineno
, "No define_enum called `%s' defined",
3173 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3174 add_attr_value (attr
, ev
->name
);
3176 else if (*XSTR (exp
, 1) == '\0')
3177 attr
->is_numeric
= 1;
3180 name_ptr
= XSTR (exp
, 1);
3181 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3182 add_attr_value (attr
, p
);
3185 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3188 if (attr
->is_numeric
)
3189 error_with_line (lineno
,
3190 "constant attributes may not take numeric values");
3192 /* Get rid of the CONST node. It is allowed only at top-level. */
3193 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3196 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3197 error_with_line (lineno
, "`length' attribute must take numeric values");
3199 /* Set up the default value. */
3200 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3201 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3204 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3205 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3206 number of alternatives as this should be checked elsewhere. */
3209 count_alternatives (rtx exp
)
3214 if (GET_CODE (exp
) == MATCH_OPERAND
)
3215 return n_comma_elts (XSTR (exp
, 2));
3217 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3218 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3223 n
= count_alternatives (XEXP (exp
, i
));
3230 if (XVEC (exp
, i
) != NULL
)
3231 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3233 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3242 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3243 `alternative' attribute. */
3246 compares_alternatives_p (rtx exp
)
3251 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3254 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3255 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3260 if (compares_alternatives_p (XEXP (exp
, i
)))
3265 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3266 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3274 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3277 gen_insn (rtx exp
, int lineno
)
3279 struct insn_def
*id
;
3281 id
= oballoc (struct insn_def
);
3285 id
->lineno
= lineno
;
3287 switch (GET_CODE (exp
))
3290 id
->insn_code
= insn_code_number
;
3291 id
->insn_index
= insn_index_number
;
3292 id
->num_alternatives
= count_alternatives (exp
);
3293 if (id
->num_alternatives
== 0)
3294 id
->num_alternatives
= 1;
3298 case DEFINE_PEEPHOLE
:
3299 id
->insn_code
= insn_code_number
;
3300 id
->insn_index
= insn_index_number
;
3301 id
->num_alternatives
= count_alternatives (exp
);
3302 if (id
->num_alternatives
== 0)
3303 id
->num_alternatives
= 1;
3307 case DEFINE_ASM_ATTRIBUTES
:
3309 id
->insn_index
= -1;
3310 id
->num_alternatives
= 1;
3312 got_define_asm_attributes
= 1;
3320 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3321 true or annul false is specified, and make a `struct delay_desc'. */
3324 gen_delay (rtx def
, int lineno
)
3326 struct delay_desc
*delay
;
3329 if (XVECLEN (def
, 1) % 3 != 0)
3331 error_with_line (lineno
,
3332 "number of elements in DEFINE_DELAY must"
3333 " be multiple of three");
3337 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3339 if (XVECEXP (def
, 1, i
+ 1))
3340 have_annul_true
= 1;
3341 if (XVECEXP (def
, 1, i
+ 2))
3342 have_annul_false
= 1;
3345 delay
= oballoc (struct delay_desc
);
3347 delay
->num
= ++num_delays
;
3348 delay
->next
= delays
;
3349 delay
->lineno
= lineno
;
3353 /* Names of attributes that could be possibly cached. */
3354 static const char *cached_attrs
[32];
3355 /* Number of such attributes. */
3356 static int cached_attr_count
;
3357 /* Bitmasks of possibly cached attributes. */
3358 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3359 static unsigned int attrs_to_cache
;
3360 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3362 /* Finds non-const attributes that could be possibly cached.
3363 When create is TRUE, fills in cached_attrs array.
3364 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3368 find_attrs_to_cache (rtx exp
, bool create
)
3372 struct attr_desc
*attr
;
3377 switch (GET_CODE (exp
))
3380 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3381 find_attrs_to_cache (XEXP (exp
, 0), create
);
3385 name
= XSTR (exp
, 0);
3386 if (name
== alternative_name
)
3388 for (i
= 0; i
< cached_attr_count
; i
++)
3389 if (name
== cached_attrs
[i
])
3391 if ((attrs_seen_once
& (1U << i
)) != 0)
3392 attrs_seen_more_than_once
|= (1U << i
);
3394 attrs_seen_once
|= (1U << i
);
3399 attr
= find_attr (&name
, 0);
3403 if (cached_attr_count
== 32)
3405 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3406 attrs_seen_once
|= (1U << cached_attr_count
);
3407 cached_attr_count
++;
3412 find_attrs_to_cache (XEXP (exp
, 0), create
);
3413 find_attrs_to_cache (XEXP (exp
, 1), create
);
3417 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3418 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3426 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3427 We use AND and IOR both for logical and bit-wise operations, so
3428 interpret them as logical unless they are inside a comparison expression. */
3430 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3431 #define FLG_BITWISE 1
3432 /* Set if cached attribute will be known initialized in else block after
3433 this condition. This is true for LHS of toplevel && and || and
3434 even for RHS of ||, but not for RHS of &&. */
3436 /* Set if cached attribute will be known initialized in then block after
3437 this condition. This is true for LHS of toplevel && and || and
3438 even for RHS of &&, but not for RHS of ||. */
3439 #define FLG_INSIDE 4
3440 /* Cleared when an operand of &&. */
3441 #define FLG_OUTSIDE_AND 8
3444 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
)
3446 int comparison_operator
= 0;
3448 struct attr_desc
*attr
;
3450 /* In order not to worry about operator precedence, surround our part of
3451 the expression with parentheses. */
3453 fprintf (outf
, "(");
3454 code
= GET_CODE (exp
);
3457 /* Binary operators. */
3460 fprintf (outf
, "(unsigned) ");
3466 comparison_operator
= FLG_BITWISE
;
3468 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3469 case AND
: case IOR
: case XOR
:
3470 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3471 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3473 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3474 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3475 flags
| comparison_operator
);
3480 flags
&= ~FLG_OUTSIDE_AND
;
3481 if (GET_CODE (XEXP (exp
, 0)) == code
3482 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3483 || (GET_CODE (XEXP (exp
, 0)) == NOT
3484 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3486 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3488 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3493 fprintf (outf
, " == ");
3496 fprintf (outf
, " != ");
3499 fprintf (outf
, " >= ");
3502 fprintf (outf
, " > ");
3505 fprintf (outf
, " >= (unsigned) ");
3508 fprintf (outf
, " > (unsigned) ");
3511 fprintf (outf
, " <= ");
3514 fprintf (outf
, " < ");
3517 fprintf (outf
, " <= (unsigned) ");
3520 fprintf (outf
, " < (unsigned) ");
3523 fprintf (outf
, " + ");
3526 fprintf (outf
, " - ");
3529 fprintf (outf
, " * ");
3532 fprintf (outf
, " / ");
3535 fprintf (outf
, " %% ");
3538 if (flags
& FLG_BITWISE
)
3539 fprintf (outf
, " & ");
3541 fprintf (outf
, " && ");
3544 if (flags
& FLG_BITWISE
)
3545 fprintf (outf
, " | ");
3547 fprintf (outf
, " || ");
3550 fprintf (outf
, " ^ ");
3553 fprintf (outf
, " << ");
3557 fprintf (outf
, " >> ");
3565 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3566 cached_x is only known to be initialized in then block. */
3567 flags
&= ~FLG_AFTER
;
3569 else if (code
== IOR
)
3571 if (flags
& FLG_OUTSIDE_AND
)
3572 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3573 cached_x is only known to be initialized in else block
3574 and else if conditions. */
3575 flags
&= ~FLG_INSIDE
;
3577 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3579 cached_x is not know to be initialized anywhere. */
3580 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3582 if ((code
== AND
|| code
== IOR
)
3583 && (GET_CODE (XEXP (exp
, 1)) == code
3584 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3585 || (GET_CODE (XEXP (exp
, 1)) == NOT
3586 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3588 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
);
3590 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3591 flags
| comparison_operator
);
3595 /* Special-case (not (eq_attrq "alternative" "x")) */
3596 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3598 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3600 fprintf (outf
, "which_alternative != %s",
3601 XSTR (XEXP (exp
, 0), 1));
3605 fprintf (outf
, "! ");
3607 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3611 /* Otherwise, fall through to normal unary operator. */
3613 /* Unary operators. */
3618 if (flags
& FLG_BITWISE
)
3619 fprintf (outf
, "~ ");
3621 fprintf (outf
, "! ");
3624 fprintf (outf
, "abs ");
3627 fprintf (outf
, "-");
3633 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3634 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3639 int set
= XINT (exp
, 0), bit
= 0;
3641 if (flags
& FLG_BITWISE
)
3642 fatal ("EQ_ATTR_ALT not valid inside comparison");
3645 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3647 if (!(set
& (set
- 1)))
3649 if (!(set
& 0xffff))
3672 fprintf (outf
, "which_alternative %s= %d",
3673 XINT (exp
, 1) ? "!" : "=", bit
);
3677 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3678 XINT (exp
, 1) ? "!" : "", set
);
3683 /* Comparison test of an attribute with a value. Most of these will
3684 have been removed by optimization. Handle "alternative"
3685 specially and give error if EQ_ATTR present inside a comparison. */
3687 if (flags
& FLG_BITWISE
)
3688 fatal ("EQ_ATTR not valid inside comparison");
3690 if (XSTR (exp
, 0) == alternative_name
)
3692 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3696 attr
= find_attr (&XSTR (exp
, 0), 0);
3699 /* Now is the time to expand the value of a constant attribute. */
3702 write_test_expr (outf
,
3703 evaluate_eq_attr (exp
, attr
,
3704 attr
->default_val
->value
,
3711 for (i
= 0; i
< cached_attr_count
; i
++)
3712 if (attr
->name
== cached_attrs
[i
])
3714 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3715 fprintf (outf
, "cached_%s", attr
->name
);
3716 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3718 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3719 attr
->name
, attr
->name
);
3720 if (flags
& FLG_AFTER
)
3721 attrs_cached_after
|= (1U << i
);
3722 if (flags
& FLG_INSIDE
)
3723 attrs_cached_inside
|= (1U << i
);
3724 attrs_cached
|= (1U << i
);
3727 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3728 fprintf (outf
, " == ");
3729 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3733 /* Comparison test of flags for define_delays. */
3735 if (flags
& FLG_BITWISE
)
3736 fatal ("ATTR_FLAG not valid inside comparison");
3737 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3740 /* See if an operand matches a predicate. */
3742 /* If only a mode is given, just ensure the mode matches the operand.
3743 If neither a mode nor predicate is given, error. */
3744 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3746 if (GET_MODE (exp
) == VOIDmode
)
3747 fatal ("null MATCH_OPERAND specified as test");
3749 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3750 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3753 fprintf (outf
, "%s (operands[%d], %smode)",
3754 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3757 /* Constant integer. */
3759 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3763 fprint_c_condition (outf
, XSTR (exp
, 0));
3764 if (flags
& FLG_BITWISE
)
3765 fprintf (outf
, " != 0");
3768 /* A random C expression. */
3770 fprint_c_condition (outf
, XSTR (exp
, 0));
3773 /* The address of the branch target. */
3776 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3777 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3781 /* The address of the current insn. We implement this actually as the
3782 address of the current insn for backward branches, but the last
3783 address of the next insn for forward branches, and both with
3784 adjustments that account for the worst-case possible stretching of
3785 intervening alignments between this insn and its destination. */
3786 fprintf (outf
, "insn_current_reference_address (insn)");
3790 fprintf (outf
, "%s", XSTR (exp
, 0));
3794 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3795 fprintf (outf
, " ? ");
3796 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3797 fprintf (outf
, " : ");
3798 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3802 fatal ("bad RTX code `%s' in attribute calculation\n",
3803 GET_RTX_NAME (code
));
3806 fprintf (outf
, ")");
3807 return attrs_cached
;
3810 /* Given an attribute value, return the maximum CONST_STRING argument
3811 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3814 max_attr_value (rtx exp
, int *unknownp
)
3819 switch (GET_CODE (exp
))
3822 current_max
= atoi (XSTR (exp
, 0));
3826 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3827 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3829 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3830 if (n
> current_max
)
3836 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3837 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3838 if (n
> current_max
)
3844 current_max
= INT_MAX
;
3851 /* Given an attribute value, return the minimum CONST_STRING argument
3852 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3855 min_attr_value (rtx exp
, int *unknownp
)
3860 switch (GET_CODE (exp
))
3863 current_min
= atoi (XSTR (exp
, 0));
3867 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3868 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3870 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3871 if (n
< current_min
)
3877 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3878 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3879 if (n
< current_min
)
3885 current_min
= INT_MAX
;
3892 /* Given an attribute value, return the result of ORing together all
3893 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3894 if the numeric value is not known. */
3897 or_attr_value (rtx exp
, int *unknownp
)
3902 switch (GET_CODE (exp
))
3905 current_or
= atoi (XSTR (exp
, 0));
3909 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3910 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3911 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3915 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3916 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3928 /* Scan an attribute value, possibly a conditional, and record what actions
3929 will be required to do any conditional tests in it.
3932 `must_extract' if we need to extract the insn operands
3933 `must_constrain' if we must compute `which_alternative'
3934 `address_used' if an address expression was used
3935 `length_used' if an (eq_attr "length" ...) was used
3939 walk_attr_value (rtx exp
)
3948 code
= GET_CODE (exp
);
3952 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3953 /* Since this is an arbitrary expression, it can look at anything.
3954 However, constant expressions do not depend on any particular
3956 must_extract
= must_constrain
= 1;
3965 must_extract
= must_constrain
= 1;
3969 if (XSTR (exp
, 0) == alternative_name
)
3970 must_extract
= must_constrain
= 1;
3971 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3991 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3996 walk_attr_value (XEXP (exp
, i
));
4000 if (XVEC (exp
, i
) != NULL
)
4001 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4002 walk_attr_value (XVECEXP (exp
, i
, j
));
4007 /* Write out a function to obtain the attribute for a given INSN. */
4010 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
4012 struct attr_value
*av
, *common_av
;
4015 /* Find the most used attribute value. Handle that as the `default' of the
4016 switch we will generate. */
4017 common_av
= find_most_used (attr
);
4019 /* Write out start of function, then all values with explicit `case' lines,
4020 then a `default', then the value with the most uses. */
4021 if (attr
->enum_name
)
4022 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4023 else if (!attr
->is_numeric
)
4024 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4026 fprintf (outf
, "int\n");
4028 /* If the attribute name starts with a star, the remainder is the name of
4029 the subroutine to use, instead of `get_attr_...'. */
4030 if (attr
->name
[0] == '*')
4031 fprintf (outf
, "%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4032 else if (attr
->is_const
== 0)
4033 fprintf (outf
, "get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4036 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4037 fprintf (outf
, "{\n");
4039 for (av
= attr
->first_value
; av
; av
= av
->next
)
4040 if (av
->num_insns
== 1)
4041 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4042 true_rtx
, av
->first_insn
->def
->insn_code
,
4043 av
->first_insn
->def
->insn_index
, 0);
4044 else if (av
->num_insns
!= 0)
4045 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4046 true_rtx
, -2, 0, 0);
4048 fprintf (outf
, "}\n\n");
4052 fprintf (outf
, "{\n");
4054 /* Find attributes that are worth caching in the conditions. */
4055 cached_attr_count
= 0;
4056 attrs_seen_more_than_once
= 0;
4057 for (av
= attr
->first_value
; av
; av
= av
->next
)
4059 attrs_seen_once
= 0;
4060 find_attrs_to_cache (av
->value
, true);
4062 /* Remove those that aren't worth caching from the array. */
4063 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4064 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4066 const char *name
= cached_attrs
[i
];
4067 struct attr_desc
*cached_attr
;
4069 cached_attrs
[j
] = name
;
4070 cached_attr
= find_attr (&name
, 0);
4071 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4072 if (cached_attr
->enum_name
)
4073 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4074 else if (!cached_attr
->is_numeric
)
4075 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4077 fprintf (outf
, " int");
4078 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4081 cached_attr_count
= j
;
4082 if (cached_attr_count
)
4083 fprintf (outf
, "\n");
4085 fprintf (outf
, " switch (recog_memoized (insn))\n");
4086 fprintf (outf
, " {\n");
4088 for (av
= attr
->first_value
; av
; av
= av
->next
)
4089 if (av
!= common_av
)
4090 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4092 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4093 fprintf (outf
, " }\n}\n\n");
4094 cached_attr_count
= 0;
4097 /* Given an AND tree of known true terms (because we are inside an `if' with
4098 that as the condition or are in an `else' clause) and an expression,
4099 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4100 the bulk of the work. */
4103 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4107 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4109 if (GET_CODE (known_true
) == AND
)
4111 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4112 insn_code
, insn_index
);
4113 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4114 insn_code
, insn_index
);
4119 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4125 /* Write out a series of tests and assignment statements to perform tests and
4126 sets of an attribute value. We are passed an indentation amount and prefix
4127 and suffix strings to write around each attribute value (e.g., "return"
4131 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
4132 const char *prefix
, const char *suffix
, rtx known_true
,
4133 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4135 if (GET_CODE (value
) == COND
)
4137 /* Assume the default value will be the default of the COND unless we
4138 find an always true expression. */
4139 rtx default_val
= XEXP (value
, 1);
4140 rtx our_known_true
= known_true
;
4145 if (cached_attr_count
)
4147 attrs_seen_once
= 0;
4148 attrs_seen_more_than_once
= 0;
4149 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4150 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4151 attrs_to_cache
|= attrs_seen_more_than_once
;
4154 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4159 /* Reset our_known_true after some time to not accumulate
4160 too much cruft (slowing down genattrtab). */
4162 our_known_true
= known_true
;
4163 testexp
= eliminate_known_true (our_known_true
,
4164 XVECEXP (value
, 0, i
),
4165 insn_code
, insn_index
);
4166 newexp
= attr_rtx (NOT
, testexp
);
4167 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4168 insn_code
, insn_index
);
4170 /* If the test expression is always true or if the next `known_true'
4171 expression is always false, this is the last case, so break
4172 out and let this value be the `else' case. */
4173 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4175 default_val
= XVECEXP (value
, 0, i
+ 1);
4179 /* Compute the expression to pass to our recursive call as being
4181 inner_true
= insert_right_side (AND
, our_known_true
,
4182 testexp
, insn_code
, insn_index
);
4184 /* If this is always false, skip it. */
4185 if (inner_true
== false_rtx
)
4188 attrs_cached_inside
= attrs_cached
;
4189 attrs_cached_after
= attrs_cached
;
4190 write_indent (outf
, indent
);
4191 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4193 write_test_expr (outf
, testexp
, attrs_cached
,
4194 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4195 attrs_cached
= attrs_cached_after
;
4196 fprintf (outf
, "\n");
4197 write_indent (outf
, indent
+ 2);
4198 fprintf (outf
, "{\n");
4200 write_attr_set (outf
, attr
, indent
+ 4,
4201 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4202 inner_true
, insn_code
, insn_index
,
4203 attrs_cached_inside
);
4204 write_indent (outf
, indent
+ 2);
4205 fprintf (outf
, "}\n");
4206 our_known_true
= newexp
;
4211 write_indent (outf
, indent
);
4212 fprintf (outf
, "else\n");
4213 write_indent (outf
, indent
+ 2);
4214 fprintf (outf
, "{\n");
4217 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4218 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4223 write_indent (outf
, indent
+ 2);
4224 fprintf (outf
, "}\n");
4229 write_indent (outf
, indent
);
4230 fprintf (outf
, "%s ", prefix
);
4231 write_attr_value (outf
, attr
, value
);
4232 fprintf (outf
, "%s\n", suffix
);
4236 /* Write a series of case statements for every instruction in list IE.
4237 INDENT is the amount of indentation to write before each case. */
4240 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4242 for (; ie
!= 0; ie
= ie
->next
)
4243 if (ie
->def
->insn_code
!= -1)
4245 write_indent (outf
, indent
);
4246 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4247 fprintf (outf
, "case %d: /* define_peephole, line %d */\n",
4248 ie
->def
->insn_code
, ie
->def
->lineno
);
4250 fprintf (outf
, "case %d: /* %s */\n",
4251 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4255 /* Write out the computation for one attribute value. */
4258 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4259 int write_case_lines
, const char *prefix
, const char *suffix
,
4260 int indent
, rtx known_true
)
4262 if (av
->num_insns
== 0)
4265 if (av
->has_asm_insn
)
4267 write_indent (outf
, indent
);
4268 fprintf (outf
, "case -1:\n");
4269 write_indent (outf
, indent
+ 2);
4270 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4271 write_indent (outf
, indent
+ 2);
4272 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4273 write_indent (outf
, indent
+ 2);
4274 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4277 if (write_case_lines
)
4278 write_insn_cases (outf
, av
->first_insn
, indent
);
4281 write_indent (outf
, indent
);
4282 fprintf (outf
, "default:\n");
4285 /* See what we have to do to output this value. */
4286 must_extract
= must_constrain
= address_used
= 0;
4287 walk_attr_value (av
->value
);
4291 write_indent (outf
, indent
+ 2);
4292 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4294 else if (must_extract
)
4296 write_indent (outf
, indent
+ 2);
4297 fprintf (outf
, "extract_insn_cached (insn);\n");
4301 if (av
->num_insns
== 1)
4302 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4303 known_true
, av
->first_insn
->def
->insn_code
,
4304 av
->first_insn
->def
->insn_index
, 0);
4306 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4307 known_true
, -2, 0, 0);
4309 if (strncmp (prefix
, "return", 6))
4311 write_indent (outf
, indent
+ 2);
4312 fprintf (outf
, "break;\n");
4314 fprintf (outf
, "\n");
4317 /* Utilities to write in various forms. */
4320 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4322 if (attr
->is_numeric
)
4326 fprintf (outf
, "%d", num
);
4328 if (num
> 9 || num
< 0)
4329 fprintf (outf
, " /* %#x */", num
);
4333 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4334 fprintf (outf
, "_");
4335 write_upcase (outf
, s
);
4340 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4344 switch (GET_CODE (value
))
4347 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4351 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4355 fprint_c_condition (outf
, XSTR (value
, 0));
4360 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4361 if (attr
->enum_name
)
4362 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4363 else if (!attr
->is_numeric
)
4364 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4365 else if (!attr2
->is_numeric
)
4366 fprintf (outf
, "(int)");
4368 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4369 (attr2
->is_const
? "" : "insn"));
4390 write_attr_value (outf
, attr
, XEXP (value
, 0));
4394 write_attr_value (outf
, attr
, XEXP (value
, 1));
4403 write_upcase (FILE *outf
, const char *str
)
4407 /* The argument of TOUPPER should not have side effects. */
4408 fputc (TOUPPER(*str
), outf
);
4414 write_indent (FILE *outf
, int indent
)
4416 for (; indent
> 8; indent
-= 8)
4417 fprintf (outf
, "\t");
4419 for (; indent
; indent
--)
4420 fprintf (outf
, " ");
4423 /* Write a subroutine that is given an insn that requires a delay slot, a
4424 delay slot ordinal, and a candidate insn. It returns nonzero if the
4425 candidate can be placed in the specified delay slot of the insn.
4427 We can write as many as three subroutines. `eligible_for_delay'
4428 handles normal delay slots, `eligible_for_annul_true' indicates that
4429 the specified insn can be annulled if the branch is true, and likewise
4430 for `eligible_for_annul_false'.
4432 KIND is a string distinguishing these three cases ("delay", "annul_true",
4433 or "annul_false"). */
4436 write_eligible_delay (FILE *outf
, const char *kind
)
4438 struct delay_desc
*delay
;
4442 struct attr_desc
*attr
;
4443 struct attr_value
*av
, *common_av
;
4446 /* Compute the maximum number of delay slots required. We use the delay
4447 ordinal times this number plus one, plus the slot number as an index into
4448 the appropriate predicate to test. */
4450 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4451 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4452 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4454 /* Write function prelude. */
4456 fprintf (outf
, "int\n");
4457 fprintf (outf
, "eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4458 " rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4460 fprintf (outf
, "{\n");
4461 fprintf (outf
, " rtx insn;\n");
4462 fprintf (outf
, "\n");
4463 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4464 fprintf (outf
, "\n");
4465 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4466 converts a compound instruction into a loop. */
4467 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4468 fprintf (outf
, " return 0;\n");
4469 fprintf (outf
, "\n");
4471 /* If more than one delay type, find out which type the delay insn is. */
4475 attr
= find_attr (&delay_type_str
, 0);
4477 common_av
= find_most_used (attr
);
4479 fprintf (outf
, " insn = delay_insn;\n");
4480 fprintf (outf
, " switch (recog_memoized (insn))\n");
4481 fprintf (outf
, " {\n");
4483 sprintf (str
, " * %d;\n break;", max_slots
);
4484 for (av
= attr
->first_value
; av
; av
= av
->next
)
4485 if (av
!= common_av
)
4486 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4488 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4489 fprintf (outf
, " }\n\n");
4491 /* Ensure matched. Otherwise, shouldn't have been called. */
4492 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4495 /* If just one type of delay slot, write simple switch. */
4496 if (num_delays
== 1 && max_slots
== 1)
4498 fprintf (outf
, " insn = candidate_insn;\n");
4499 fprintf (outf
, " switch (recog_memoized (insn))\n");
4500 fprintf (outf
, " {\n");
4502 attr
= find_attr (&delay_1_0_str
, 0);
4504 common_av
= find_most_used (attr
);
4506 for (av
= attr
->first_value
; av
; av
= av
->next
)
4507 if (av
!= common_av
)
4508 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4510 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4511 fprintf (outf
, " }\n");
4516 /* Write a nested CASE. The first indicates which condition we need to
4517 test, and the inner CASE tests the condition. */
4518 fprintf (outf
, " insn = candidate_insn;\n");
4519 fprintf (outf
, " switch (slot)\n");
4520 fprintf (outf
, " {\n");
4522 for (delay
= delays
; delay
; delay
= delay
->next
)
4523 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4525 fprintf (outf
, " case %d:\n",
4526 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4527 fprintf (outf
, " switch (recog_memoized (insn))\n");
4528 fprintf (outf
, "\t{\n");
4530 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4532 attr
= find_attr (&pstr
, 0);
4534 common_av
= find_most_used (attr
);
4536 for (av
= attr
->first_value
; av
; av
= av
->next
)
4537 if (av
!= common_av
)
4538 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4540 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4541 fprintf (outf
, " }\n");
4544 fprintf (outf
, " default:\n");
4545 fprintf (outf
, " gcc_unreachable ();\n");
4546 fprintf (outf
, " }\n");
4549 fprintf (outf
, "}\n\n");
4552 /* This page contains miscellaneous utility routines. */
4554 /* Given a pointer to a (char *), return a malloc'ed string containing the
4555 next comma-separated element. Advance the pointer to after the string
4556 scanned, or the end-of-string. Return NULL if at end of string. */
4559 next_comma_elt (const char **pstr
)
4563 start
= scan_comma_elt (pstr
);
4568 return attr_string (start
, *pstr
- start
);
4571 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4572 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4573 replaced by a pointer to a canonical copy of the string. */
4575 static struct attr_desc
*
4576 find_attr (const char **name_p
, int create
)
4578 struct attr_desc
*attr
;
4580 const char *name
= *name_p
;
4582 /* Before we resort to using `strcmp', see if the string address matches
4583 anywhere. In most cases, it should have been canonicalized to do so. */
4584 if (name
== alternative_name
)
4587 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4588 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4589 if (name
== attr
->name
)
4592 /* Otherwise, do it the slow way. */
4593 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4594 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4596 *name_p
= attr
->name
;
4603 attr
= oballoc (struct attr_desc
);
4604 attr
->name
= DEF_ATTR_STRING (name
);
4605 attr
->enum_name
= 0;
4606 attr
->first_value
= attr
->default_val
= NULL
;
4607 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4608 attr
->next
= attrs
[index
];
4609 attrs
[index
] = attr
;
4611 *name_p
= attr
->name
;
4616 /* Create internal attribute with the given default value. */
4619 make_internal_attr (const char *name
, rtx value
, int special
)
4621 struct attr_desc
*attr
;
4623 attr
= find_attr (&name
, 1);
4624 gcc_assert (!attr
->default_val
);
4626 attr
->is_numeric
= 1;
4628 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4629 attr
->default_val
= get_attr_value (value
, attr
, -2);
4632 /* Find the most used value of an attribute. */
4634 static struct attr_value
*
4635 find_most_used (struct attr_desc
*attr
)
4637 struct attr_value
*av
;
4638 struct attr_value
*most_used
;
4644 for (av
= attr
->first_value
; av
; av
= av
->next
)
4645 if (av
->num_insns
> nuses
)
4646 nuses
= av
->num_insns
, most_used
= av
;
4651 /* Return (attr_value "n") */
4654 make_numeric_value (int n
)
4656 static rtx int_values
[20];
4660 gcc_assert (n
>= 0);
4662 if (n
< 20 && int_values
[n
])
4663 return int_values
[n
];
4665 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4666 exp
= attr_rtx (CONST_STRING
, p
);
4669 int_values
[n
] = exp
;
4675 copy_rtx_unchanging (rtx orig
)
4677 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4680 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4684 /* Determine if an insn has a constant number of delay slots, i.e., the
4685 number of delay slots is not a function of the length of the insn. */
4688 write_const_num_delay_slots (FILE *outf
)
4690 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4691 struct attr_value
*av
;
4695 fprintf (outf
, "int\nconst_num_delay_slots (rtx insn)\n");
4696 fprintf (outf
, "{\n");
4697 fprintf (outf
, " switch (recog_memoized (insn))\n");
4698 fprintf (outf
, " {\n");
4700 for (av
= attr
->first_value
; av
; av
= av
->next
)
4703 walk_attr_value (av
->value
);
4705 write_insn_cases (outf
, av
->first_insn
, 4);
4708 fprintf (outf
, " default:\n");
4709 fprintf (outf
, " return 1;\n");
4710 fprintf (outf
, " }\n}\n\n");
4714 /* Synthetic attributes used by insn-automata.c and the scheduler.
4715 These are primarily concerned with (define_insn_reservation)
4720 struct insn_reserv
*next
;
4723 int default_latency
;
4726 /* Sequence number of this insn. */
4729 /* Whether a (define_bypass) construct names this insn in its
4734 static struct insn_reserv
*all_insn_reservs
= 0;
4735 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4736 static size_t n_insn_reservs
;
4738 /* Store information from a DEFINE_INSN_RESERVATION for future
4739 attribute generation. */
4741 gen_insn_reserv (rtx def
)
4743 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4745 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4746 decl
->default_latency
= XINT (def
, 1);
4747 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4748 decl
->insn_num
= n_insn_reservs
;
4749 decl
->bypassed
= false;
4752 *last_insn_reserv_p
= decl
;
4753 last_insn_reserv_p
= &decl
->next
;
4757 /* Store information from a DEFINE_BYPASS for future attribute
4758 generation. The only thing we care about is the list of output
4759 insns, which will later be used to tag reservation structures with
4760 a 'bypassed' bit. */
4764 struct bypass_list
*next
;
4765 const char *pattern
;
4768 static struct bypass_list
*all_bypasses
;
4769 static size_t n_bypasses
;
4772 gen_bypass_1 (const char *s
, size_t len
)
4774 struct bypass_list
*b
;
4779 s
= attr_string (s
, len
);
4780 for (b
= all_bypasses
; b
; b
= b
->next
)
4781 if (s
== b
->pattern
)
4782 return; /* already got that one */
4784 b
= oballoc (struct bypass_list
);
4786 b
->next
= all_bypasses
;
4792 gen_bypass (rtx def
)
4794 const char *p
, *base
;
4796 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4799 gen_bypass_1 (base
, p
- base
);
4802 while (ISSPACE (*p
));
4805 gen_bypass_1 (base
, p
- base
);
4808 /* Find and mark all of the bypassed insns. */
4810 process_bypasses (void)
4812 struct bypass_list
*b
;
4813 struct insn_reserv
*r
;
4815 /* The reservation list is likely to be much longer than the bypass
4817 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4818 for (b
= all_bypasses
; b
; b
= b
->next
)
4819 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4823 /* Check that attribute NAME is used in define_insn_reservation condition
4824 EXP. Return true if it is. */
4826 check_tune_attr (const char *name
, rtx exp
)
4828 switch (GET_CODE (exp
))
4831 if (check_tune_attr (name
, XEXP (exp
, 0)))
4833 return check_tune_attr (name
, XEXP (exp
, 1));
4836 return (check_tune_attr (name
, XEXP (exp
, 0))
4837 && check_tune_attr (name
, XEXP (exp
, 1)));
4840 return XSTR (exp
, 0) == name
;
4847 /* Try to find a const attribute (usually cpu or tune) that is used
4848 in all define_insn_reservation conditions. */
4849 static struct attr_desc
*
4850 find_tune_attr (rtx exp
)
4852 struct attr_desc
*attr
;
4854 switch (GET_CODE (exp
))
4858 attr
= find_tune_attr (XEXP (exp
, 0));
4861 return find_tune_attr (XEXP (exp
, 1));
4864 if (XSTR (exp
, 0) == alternative_name
)
4867 attr
= find_attr (&XSTR (exp
, 0), 0);
4870 if (attr
->is_const
&& !attr
->is_special
)
4872 struct insn_reserv
*decl
;
4874 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4875 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4886 /* Create all of the attributes that describe automaton properties.
4887 Write the DFA and latency function prototypes to the files that
4888 need to have them, and write the init_sched_attrs(). */
4891 make_automaton_attrs (void)
4894 struct insn_reserv
*decl
;
4895 rtx code_exp
, lats_exp
, byps_exp
;
4896 struct attr_desc
*tune_attr
;
4898 if (n_insn_reservs
== 0)
4901 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4902 if (tune_attr
!= NULL
)
4904 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4905 struct attr_value
*val
;
4908 gcc_assert (tune_attr
->is_const
4909 && !tune_attr
->is_special
4910 && !tune_attr
->is_numeric
);
4912 /* Write the prototypes for all DFA functions. */
4913 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4915 if (val
== tune_attr
->default_val
)
4917 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4919 "extern int internal_dfa_insn_code_%s (rtx);\n",
4920 XSTR (val
->value
, 0));
4922 fprintf (dfa_file
, "\n");
4924 /* Write the prototypes for all latency functions. */
4925 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4927 if (val
== tune_attr
->default_val
)
4929 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4930 fprintf (latency_file
,
4931 "extern int insn_default_latency_%s (rtx);\n",
4932 XSTR (val
->value
, 0));
4934 fprintf (latency_file
, "\n");
4936 /* Write the prototypes for all automaton functions. */
4937 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4939 if (val
== tune_attr
->default_val
)
4941 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4943 "extern int internal_dfa_insn_code_%s (rtx);\n"
4944 "extern int insn_default_latency_%s (rtx);\n",
4945 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4947 fprintf (attr_file
, "\n");
4948 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx);\n");
4949 fprintf (attr_file
, "int (*insn_default_latency) (rtx);\n");
4950 fprintf (attr_file
, "\n");
4951 fprintf (attr_file
, "void\n");
4952 fprintf (attr_file
, "init_sched_attrs (void)\n");
4953 fprintf (attr_file
, "{\n");
4955 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4959 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
4961 if (val
== tune_attr
->default_val
)
4963 for (decl
= all_insn_reservs
, i
= 0;
4969 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
4970 if (condexp
== false_rtx
)
4972 if (condexp
== true_rtx
)
4974 condexps
[i
] = condexp
;
4975 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
4976 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
4980 code_exp
= rtx_alloc (COND
);
4981 lats_exp
= rtx_alloc (COND
);
4984 XVEC (code_exp
, 0) = rtvec_alloc (j
);
4985 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
4989 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
4990 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
4994 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4995 XEXP (lats_exp
, 1) = make_numeric_value (0);
5002 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
5003 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
5005 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
5006 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5009 name
= XNEWVEC (char,
5010 sizeof ("*internal_dfa_insn_code_")
5011 + strlen (XSTR (val
->value
, 0)));
5012 strcpy (name
, "*internal_dfa_insn_code_");
5013 strcat (name
, XSTR (val
->value
, 0));
5014 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5015 strcpy (name
, "*insn_default_latency_");
5016 strcat (name
, XSTR (val
->value
, 0));
5017 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5022 fprintf (attr_file
, " if (");
5026 fprintf (attr_file
, " else if (");
5027 write_test_expr (attr_file
, test
, 0, 0);
5028 fprintf (attr_file
, ")\n");
5029 fprintf (attr_file
, " {\n");
5030 fprintf (attr_file
, " internal_dfa_insn_code\n");
5031 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5032 XSTR (val
->value
, 0));
5033 fprintf (attr_file
, " insn_default_latency\n");
5034 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5035 XSTR (val
->value
, 0));
5036 fprintf (attr_file
, " }\n");
5039 fprintf (attr_file
, " else\n");
5040 fprintf (attr_file
, " gcc_unreachable ();\n");
5041 fprintf (attr_file
, "}\n");
5042 fprintf (attr_file
, "\n");
5044 XDELETEVEC (condexps
);
5048 code_exp
= rtx_alloc (COND
);
5049 lats_exp
= rtx_alloc (COND
);
5051 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5052 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5054 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5055 XEXP (lats_exp
, 1) = make_numeric_value (0);
5057 for (decl
= all_insn_reservs
, i
= 0;
5059 decl
= decl
->next
, i
+= 2)
5061 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5062 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5064 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5065 XVECEXP (lats_exp
, 0, i
+1)
5066 = make_numeric_value (decl
->default_latency
);
5068 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5069 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5072 if (n_bypasses
== 0)
5073 byps_exp
= make_numeric_value (0);
5076 process_bypasses ();
5078 byps_exp
= rtx_alloc (COND
);
5079 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypasses
* 2);
5080 XEXP (byps_exp
, 1) = make_numeric_value (0);
5081 for (decl
= all_insn_reservs
, i
= 0;
5086 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5087 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5092 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5096 write_header (FILE *outf
)
5098 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5099 " from the machine description file `md'. */\n\n");
5101 fprintf (outf
, "#include \"config.h\"\n");
5102 fprintf (outf
, "#include \"system.h\"\n");
5103 fprintf (outf
, "#include \"coretypes.h\"\n");
5104 fprintf (outf
, "#include \"tm.h\"\n");
5105 fprintf (outf
, "#include \"rtl.h\"\n");
5106 fprintf (outf
, "#include \"insn-attr.h\"\n");
5107 fprintf (outf
, "#include \"tm_p.h\"\n");
5108 fprintf (outf
, "#include \"insn-config.h\"\n");
5109 fprintf (outf
, "#include \"recog.h\"\n");
5110 fprintf (outf
, "#include \"regs.h\"\n");
5111 fprintf (outf
, "#include \"real.h\"\n");
5112 fprintf (outf
, "#include \"output.h\"\n");
5113 fprintf (outf
, "#include \"toplev.h\"\n");
5114 fprintf (outf
, "#include \"flags.h\"\n");
5115 fprintf (outf
, "#include \"function.h\"\n");
5116 fprintf (outf
, "\n");
5117 fprintf (outf
, "#define operands recog_data.operand\n\n");
5121 open_outfile (const char *file_name
)
5124 outf
= fopen (file_name
, "w");
5126 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5127 write_header (outf
);
5132 handle_arg (const char *arg
)
5137 attr_file_name
= &arg
[2];
5140 dfa_file_name
= &arg
[2];
5143 latency_file_name
= &arg
[2];
5151 main (int argc
, char **argv
)
5154 struct attr_desc
*attr
;
5155 struct insn_def
*id
;
5159 progname
= "genattrtab";
5161 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5162 return FATAL_EXIT_CODE
;
5164 attr_file
= open_outfile (attr_file_name
);
5165 dfa_file
= open_outfile (dfa_file_name
);
5166 latency_file
= open_outfile (latency_file_name
);
5168 obstack_init (hash_obstack
);
5169 obstack_init (temp_obstack
);
5171 /* Set up true and false rtx's */
5172 true_rtx
= rtx_alloc (CONST_INT
);
5173 XWINT (true_rtx
, 0) = 1;
5174 false_rtx
= rtx_alloc (CONST_INT
);
5175 XWINT (false_rtx
, 0) = 0;
5176 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5177 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5179 alternative_name
= DEF_ATTR_STRING ("alternative");
5180 length_str
= DEF_ATTR_STRING ("length");
5181 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5182 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5183 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5185 /* Read the machine description. */
5191 desc
= read_md_rtx (&lineno
, &insn_code_number
);
5195 switch (GET_CODE (desc
))
5198 case DEFINE_PEEPHOLE
:
5199 case DEFINE_ASM_ATTRIBUTES
:
5200 gen_insn (desc
, lineno
);
5204 case DEFINE_ENUM_ATTR
:
5205 gen_attr (desc
, lineno
);
5209 gen_delay (desc
, lineno
);
5212 case DEFINE_INSN_RESERVATION
:
5213 gen_insn_reserv (desc
);
5223 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
5224 insn_index_number
++;
5228 return FATAL_EXIT_CODE
;
5232 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5233 if (! got_define_asm_attributes
)
5235 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5236 XVEC (tem
, 0) = rtvec_alloc (0);
5240 /* Expand DEFINE_DELAY information into new attribute. */
5244 /* Make `insn_alternatives'. */
5245 insn_alternatives
= oballocvec (int, insn_code_number
);
5246 for (id
= defs
; id
; id
= id
->next
)
5247 if (id
->insn_code
>= 0)
5248 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
5250 /* Make `insn_n_alternatives'. */
5251 insn_n_alternatives
= oballocvec (int, insn_code_number
);
5252 for (id
= defs
; id
; id
= id
->next
)
5253 if (id
->insn_code
>= 0)
5254 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5256 /* Construct extra attributes for automata. */
5257 make_automaton_attrs ();
5259 /* Prepare to write out attribute subroutines by checking everything stored
5260 away and building the attribute cases. */
5264 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5265 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5266 attr
->default_val
->value
5267 = check_attr_value (attr
->default_val
->value
, attr
);
5270 return FATAL_EXIT_CODE
;
5272 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5273 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5276 /* Construct extra attributes for `length'. */
5277 make_length_attrs ();
5279 /* Perform any possible optimizations to speed up compilation. */
5282 /* Now write out all the `gen_attr_...' routines. Do these before the
5283 special routines so that they get defined before they are used. */
5285 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5286 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5290 #define IS_ATTR_GROUP(X) (!strncmp(attr->name,X,strlen(X)))
5291 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5293 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5294 outf
= latency_file
;
5297 #undef IS_ATTR_GROUP
5299 if (! attr
->is_special
&& ! attr
->is_const
)
5300 write_attr_get (outf
, attr
);
5303 /* Write out delay eligibility information, if DEFINE_DELAY present.
5304 (The function to compute the number of delay slots will be written
5308 write_eligible_delay (attr_file
, "delay");
5309 if (have_annul_true
)
5310 write_eligible_delay (attr_file
, "annul_true");
5311 if (have_annul_false
)
5312 write_eligible_delay (attr_file
, "annul_false");
5315 /* Write out constant delay slot info. */
5316 write_const_num_delay_slots (attr_file
);
5318 write_length_unit_log (attr_file
);
5320 if (fclose (attr_file
) != 0)
5321 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5322 if (fclose (dfa_file
) != 0)
5323 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5324 if (fclose (latency_file
) != 0)
5325 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5327 return SUCCESS_EXIT_CODE
;