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"
119 /* Flags for make_internal_attr's `special' parameter. */
121 #define ATTR_SPECIAL (1 << 0)
123 static struct obstack obstack1
, obstack2
;
124 static struct obstack
*hash_obstack
= &obstack1
;
125 static struct obstack
*temp_obstack
= &obstack2
;
127 /* enough space to reserve for printing out ints */
128 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
130 /* Define structures used to record attributes and values. */
132 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
133 encountered, we store all the relevant information into a
134 `struct insn_def'. This is done to allow attribute definitions to occur
135 anywhere in the file. */
139 struct insn_def
*next
; /* Next insn in chain. */
140 rtx def
; /* The DEFINE_... */
141 int insn_code
; /* Instruction number. */
142 int insn_index
; /* Expression number in file, for errors. */
143 int lineno
; /* Line number. */
144 int num_alternatives
; /* Number of alternatives. */
145 int vec_idx
; /* Index of attribute vector in `def'. */
148 /* Once everything has been read in, we store in each attribute value a list
149 of insn codes that have that value. Here is the structure used for the
154 struct insn_ent
*next
; /* Next in chain. */
155 struct insn_def
*def
; /* Instruction definition. */
158 /* Each value of an attribute (either constant or computed) is assigned a
159 structure which is used as the listhead of the insns that have that
164 rtx value
; /* Value of attribute. */
165 struct attr_value
*next
; /* Next attribute value in chain. */
166 struct insn_ent
*first_insn
; /* First insn with this value. */
167 int num_insns
; /* Number of insns with this value. */
168 int has_asm_insn
; /* True if this value used for `asm' insns */
171 /* Structure for each attribute. */
175 char *name
; /* Name of attribute. */
176 const char *enum_name
; /* Enum name for DEFINE_ENUM_NAME. */
177 struct attr_desc
*next
; /* Next attribute. */
178 struct attr_value
*first_value
; /* First value of this attribute. */
179 struct attr_value
*default_val
; /* Default value for this attribute. */
180 int lineno
: 24; /* Line number. */
181 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
182 unsigned is_const
: 1; /* Attribute value constant for each run. */
183 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
186 /* Structure for each DEFINE_DELAY. */
190 rtx def
; /* DEFINE_DELAY expression. */
191 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
192 int num
; /* Number of DEFINE_DELAY, starting at 1. */
193 int lineno
; /* Line number. */
196 struct attr_value_list
198 struct attr_value
*av
;
200 struct attr_desc
*attr
;
201 struct attr_value_list
*next
;
204 /* Listheads of above structures. */
206 /* This one is indexed by the first character of the attribute name. */
207 #define MAX_ATTRS_INDEX 256
208 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
209 static struct insn_def
*defs
;
210 static struct delay_desc
*delays
;
211 struct attr_value_list
**insn_code_values
;
213 /* Other variables. */
215 static int insn_code_number
;
216 static int insn_index_number
;
217 static int got_define_asm_attributes
;
218 static int must_extract
;
219 static int must_constrain
;
220 static int address_used
;
221 static int length_used
;
222 static int num_delays
;
223 static int have_annul_true
, have_annul_false
;
224 static int num_insn_ents
;
226 /* Stores, for each insn code, the number of constraint alternatives. */
228 static int *insn_n_alternatives
;
230 /* Stores, for each insn code, a bitmap that has bits on for each possible
233 static int *insn_alternatives
;
235 /* Used to simplify expressions. */
237 static rtx true_rtx
, false_rtx
;
239 /* Used to reduce calls to `strcmp' */
241 static const char *alternative_name
;
242 static const char *length_str
;
243 static const char *delay_type_str
;
244 static const char *delay_1_0_str
;
245 static const char *num_delay_slots_str
;
247 /* Simplify an expression. Only call the routine if there is something to
249 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
250 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
251 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
253 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
255 /* Forward declarations of functions used before their definitions, only. */
256 static char *attr_string (const char *, int);
257 static char *attr_printf (unsigned int, const char *, ...)
259 static rtx
make_numeric_value (int);
260 static struct attr_desc
*find_attr (const char **, int);
261 static rtx
mk_attr_alt (int);
262 static char *next_comma_elt (const char **);
263 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
264 static rtx
copy_boolean (rtx
);
265 static int compares_alternatives_p (rtx
);
266 static void make_internal_attr (const char *, rtx
, int);
267 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
268 static void walk_attr_value (rtx
);
269 static int max_attr_value (rtx
, int*);
270 static int min_attr_value (rtx
, int*);
271 static int or_attr_value (rtx
, int*);
272 static rtx
simplify_test_exp (rtx
, int, int);
273 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
274 static rtx
copy_rtx_unchanging (rtx
);
275 static bool attr_alt_subset_p (rtx
, rtx
);
276 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
277 static void clear_struct_flag (rtx
);
278 static void write_attr_valueq (FILE *, struct attr_desc
*, const char *);
279 static struct attr_value
*find_most_used (struct attr_desc
*);
280 static void write_attr_set (FILE *, struct attr_desc
*, int, rtx
,
281 const char *, const char *, rtx
,
282 int, int, unsigned int);
283 static void write_attr_case (FILE *, struct attr_desc
*,
285 int, const char *, const char *, int, rtx
);
286 static void write_attr_value (FILE *, struct attr_desc
*, rtx
);
287 static void write_upcase (FILE *, const char *);
288 static void write_indent (FILE *, int);
289 static rtx
identity_fn (rtx
);
290 static rtx
zero_fn (rtx
);
291 static rtx
one_fn (rtx
);
292 static rtx
max_fn (rtx
);
293 static rtx
min_fn (rtx
);
295 #define oballoc(T) XOBNEW (hash_obstack, T)
296 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
298 /* This gen* file is unique, in that it writes out multiple files.
300 Before GCC 4.8, insn-attrtab.c was written out containing many large
301 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
302 a parallel build, and even made it impossible to build GCC on machines
303 with relatively small RAM space (PR other/29442). Therefore, the
304 atrribute functions/tables are now written out to three separate
305 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
306 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
307 rest goes to ATTR_FILE_NAME. */
309 static const char *attr_file_name
= NULL
;
310 static const char *dfa_file_name
= NULL
;
311 static const char *latency_file_name
= NULL
;
313 static FILE *attr_file
, *dfa_file
, *latency_file
;
315 /* Hash table for sharing RTL and strings. */
317 /* Each hash table slot is a bucket containing a chain of these structures.
318 Strings are given negative hash codes; RTL expressions are given positive
323 struct attr_hash
*next
; /* Next structure in the bucket. */
324 int hashcode
; /* Hash code of this rtx or string. */
327 char *str
; /* The string (negative hash codes) */
328 rtx rtl
; /* or the RTL recorded here. */
332 /* Now here is the hash table. When recording an RTL, it is added to
333 the slot whose index is the hash code mod the table size. Note
334 that the hash table is used for several kinds of RTL (see attr_rtx)
335 and for strings. While all these live in the same table, they are
336 completely independent, and the hash code is computed differently
339 #define RTL_HASH_SIZE 4093
340 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
342 /* Here is how primitive or already-shared RTL's hash
344 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
346 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
349 attr_hash_add_rtx (int hashcode
, rtx rtl
)
353 h
= XOBNEW (hash_obstack
, struct attr_hash
);
354 h
->hashcode
= hashcode
;
356 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
357 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
360 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
363 attr_hash_add_string (int hashcode
, char *str
)
367 h
= XOBNEW (hash_obstack
, struct attr_hash
);
368 h
->hashcode
= -hashcode
;
370 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
371 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
374 /* Generate an RTL expression, but avoid duplicates.
375 Set the ATTR_PERMANENT_P flag for these permanent objects.
377 In some cases we cannot uniquify; then we return an ordinary
378 impermanent rtx with ATTR_PERMANENT_P clear.
382 rtx attr_rtx (code, [element1, ..., elementn]) */
385 attr_rtx_1 (enum rtx_code code
, va_list p
)
387 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
390 struct obstack
*old_obstack
= rtl_obstack
;
392 /* For each of several cases, search the hash table for an existing entry.
393 Use that entry if one is found; otherwise create a new RTL and add it
396 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
398 rtx arg0
= va_arg (p
, rtx
);
400 /* A permanent object cannot point to impermanent ones. */
401 if (! ATTR_PERMANENT_P (arg0
))
403 rt_val
= rtx_alloc (code
);
404 XEXP (rt_val
, 0) = arg0
;
408 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
409 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
410 if (h
->hashcode
== hashcode
411 && GET_CODE (h
->u
.rtl
) == code
412 && XEXP (h
->u
.rtl
, 0) == arg0
)
417 rtl_obstack
= hash_obstack
;
418 rt_val
= rtx_alloc (code
);
419 XEXP (rt_val
, 0) = arg0
;
422 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
423 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
424 || GET_RTX_CLASS (code
) == RTX_COMPARE
425 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
427 rtx arg0
= va_arg (p
, rtx
);
428 rtx arg1
= va_arg (p
, rtx
);
430 /* A permanent object cannot point to impermanent ones. */
431 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
433 rt_val
= rtx_alloc (code
);
434 XEXP (rt_val
, 0) = arg0
;
435 XEXP (rt_val
, 1) = arg1
;
439 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
440 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
441 if (h
->hashcode
== hashcode
442 && GET_CODE (h
->u
.rtl
) == code
443 && XEXP (h
->u
.rtl
, 0) == arg0
444 && XEXP (h
->u
.rtl
, 1) == arg1
)
449 rtl_obstack
= hash_obstack
;
450 rt_val
= rtx_alloc (code
);
451 XEXP (rt_val
, 0) = arg0
;
452 XEXP (rt_val
, 1) = arg1
;
455 else if (code
== SYMBOL_REF
456 || (GET_RTX_LENGTH (code
) == 1
457 && GET_RTX_FORMAT (code
)[0] == 's'))
459 char *arg0
= va_arg (p
, char *);
461 arg0
= DEF_ATTR_STRING (arg0
);
463 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
464 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
465 if (h
->hashcode
== hashcode
466 && GET_CODE (h
->u
.rtl
) == code
467 && XSTR (h
->u
.rtl
, 0) == arg0
)
472 rtl_obstack
= hash_obstack
;
473 rt_val
= rtx_alloc (code
);
474 XSTR (rt_val
, 0) = arg0
;
475 if (code
== SYMBOL_REF
)
477 X0EXP (rt_val
, 1) = NULL_RTX
;
478 X0EXP (rt_val
, 2) = NULL_RTX
;
482 else if (GET_RTX_LENGTH (code
) == 2
483 && GET_RTX_FORMAT (code
)[0] == 's'
484 && GET_RTX_FORMAT (code
)[1] == 's')
486 char *arg0
= va_arg (p
, char *);
487 char *arg1
= va_arg (p
, char *);
489 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
490 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
491 if (h
->hashcode
== hashcode
492 && GET_CODE (h
->u
.rtl
) == code
493 && XSTR (h
->u
.rtl
, 0) == arg0
494 && XSTR (h
->u
.rtl
, 1) == arg1
)
499 rtl_obstack
= hash_obstack
;
500 rt_val
= rtx_alloc (code
);
501 XSTR (rt_val
, 0) = arg0
;
502 XSTR (rt_val
, 1) = arg1
;
505 else if (code
== CONST_INT
)
507 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
517 int i
; /* Array indices... */
518 const char *fmt
; /* Current rtx's format... */
520 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
522 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
523 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
527 case '0': /* Unused field. */
530 case 'i': /* An integer? */
531 XINT (rt_val
, i
) = va_arg (p
, int);
534 case 'w': /* A wide integer? */
535 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
538 case 's': /* A string? */
539 XSTR (rt_val
, i
) = va_arg (p
, char *);
542 case 'e': /* An expression? */
543 case 'u': /* An insn? Same except when printing. */
544 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
547 case 'E': /* An RTX vector? */
548 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
558 rtl_obstack
= old_obstack
;
559 attr_hash_add_rtx (hashcode
, rt_val
);
560 ATTR_PERMANENT_P (rt_val
) = 1;
565 attr_rtx (enum rtx_code code
, ...)
571 result
= attr_rtx_1 (code
, p
);
576 /* Create a new string printed with the printf line arguments into a space
577 of at most LEN bytes:
579 rtx attr_printf (len, format, [arg1, ..., argn]) */
582 attr_printf (unsigned int len
, const char *fmt
, ...)
589 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
591 vsprintf (str
, fmt
, p
);
594 return DEF_ATTR_STRING (str
);
598 attr_eq (const char *name
, const char *value
)
600 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
606 return XSTR (make_numeric_value (n
), 0);
609 /* Return a permanent (possibly shared) copy of a string STR (not assumed
610 to be null terminated) with LEN bytes. */
613 attr_string (const char *str
, int len
)
620 /* Compute the hash code. */
621 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
622 for (i
= 1; i
< len
; i
+= 2)
623 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
625 hashcode
= -hashcode
;
627 /* Search the table for the string. */
628 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
629 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
630 && !strncmp (h
->u
.str
, str
, len
))
631 return h
->u
.str
; /* <-- return if found. */
633 /* Not found; create a permanent copy and add it to the hash table. */
634 new_str
= XOBNEWVAR (hash_obstack
, char, len
+ 1);
635 memcpy (new_str
, str
, len
);
637 attr_hash_add_string (hashcode
, new_str
);
638 copy_md_ptr_loc (new_str
, str
);
640 return new_str
; /* Return the new string. */
643 /* Check two rtx's for equality of contents,
644 taking advantage of the fact that if both are hashed
645 then they can't be equal unless they are the same object. */
648 attr_equal_p (rtx x
, rtx y
)
650 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
651 && rtx_equal_p (x
, y
)));
654 /* Copy an attribute value expression,
655 descending to all depths, but not copying any
656 permanent hashed subexpressions. */
659 attr_copy_rtx (rtx orig
)
664 const char *format_ptr
;
666 /* No need to copy a permanent object. */
667 if (ATTR_PERMANENT_P (orig
))
670 code
= GET_CODE (orig
);
689 copy
= rtx_alloc (code
);
690 PUT_MODE (copy
, GET_MODE (orig
));
691 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
692 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
693 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
695 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
697 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
699 switch (*format_ptr
++)
702 XEXP (copy
, i
) = XEXP (orig
, i
);
703 if (XEXP (orig
, i
) != NULL
)
704 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
709 XVEC (copy
, i
) = XVEC (orig
, i
);
710 if (XVEC (orig
, i
) != NULL
)
712 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
713 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
714 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
720 XINT (copy
, i
) = XINT (orig
, i
);
724 XWINT (copy
, i
) = XWINT (orig
, i
);
729 XSTR (copy
, i
) = XSTR (orig
, i
);
739 /* Given a test expression for an attribute, ensure it is validly formed.
740 IS_CONST indicates whether the expression is constant for each compiler
741 run (a constant expression may not test any particular insn).
743 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
744 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
745 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
747 Update the string address in EQ_ATTR expression to be the same used
748 in the attribute (or `alternative_name') to speed up subsequent
749 `find_attr' calls and eliminate most `strcmp' calls.
751 Return the new expression, if any. */
754 check_attr_test (rtx exp
, int is_const
, int lineno
)
756 struct attr_desc
*attr
;
757 struct attr_value
*av
;
758 const char *name_ptr
, *p
;
761 switch (GET_CODE (exp
))
764 /* Handle negation test. */
765 if (XSTR (exp
, 1)[0] == '!')
766 return check_attr_test (attr_rtx (NOT
,
767 attr_eq (XSTR (exp
, 0),
771 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
773 attr
= find_attr (&XSTR (exp
, 0), 0);
776 if (! strcmp (XSTR (exp
, 0), "alternative"))
777 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
779 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
782 if (is_const
&& ! attr
->is_const
)
783 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
786 /* Copy this just to make it permanent,
787 so expressions using it can be permanent too. */
788 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
790 /* It shouldn't be possible to simplify the value given to a
791 constant attribute, so don't expand this until it's time to
792 write the test expression. */
794 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
796 if (attr
->is_numeric
)
798 for (p
= XSTR (exp
, 1); *p
; p
++)
800 fatal ("attribute `%s' takes only numeric values",
805 for (av
= attr
->first_value
; av
; av
= av
->next
)
806 if (GET_CODE (av
->value
) == CONST_STRING
807 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
811 fatal ("unknown value `%s' for `%s' attribute",
812 XSTR (exp
, 1), XSTR (exp
, 0));
817 if (! strcmp (XSTR (exp
, 0), "alternative"))
821 name_ptr
= XSTR (exp
, 1);
822 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
823 set
|= 1 << atoi (p
);
825 return mk_attr_alt (set
);
829 /* Make an IOR tree of the possible values. */
831 name_ptr
= XSTR (exp
, 1);
832 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
834 newexp
= attr_eq (XSTR (exp
, 0), p
);
835 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
838 return check_attr_test (orexp
, is_const
, lineno
);
847 /* Either TRUE or FALSE. */
855 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
856 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
860 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
864 exp
= attr_rtx (MATCH_TEST
, XSTR (exp
, 0));
865 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
870 fatal ("RTL operator \"%s\" not valid in constant attribute test",
871 GET_RTX_NAME (GET_CODE (exp
)));
872 /* These cases can't be simplified. */
873 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
876 case LE
: case LT
: case GT
: case GE
:
877 case LEU
: case LTU
: case GTU
: case GEU
:
879 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
880 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
881 exp
= attr_rtx (GET_CODE (exp
),
882 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
883 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
884 /* These cases can't be simplified. */
885 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
891 /* These cases are valid for constant attributes, but can't be
893 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
894 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
898 fatal ("RTL operator \"%s\" not valid in attribute test",
899 GET_RTX_NAME (GET_CODE (exp
)));
905 /* Given an expression, ensure that it is validly formed and that all named
906 attribute values are valid for the given attribute. Issue a fatal error
907 if not. If no attribute is specified, assume a numeric attribute.
909 Return a perhaps modified replacement expression for the value. */
912 check_attr_value (rtx exp
, struct attr_desc
*attr
)
914 struct attr_value
*av
;
918 switch (GET_CODE (exp
))
921 if (attr
&& ! attr
->is_numeric
)
923 error_with_line (attr
->lineno
,
924 "CONST_INT not valid for non-numeric attribute %s",
929 if (INTVAL (exp
) < 0)
931 error_with_line (attr
->lineno
,
932 "negative numeric value specified for attribute %s",
939 if (! strcmp (XSTR (exp
, 0), "*"))
942 if (attr
== 0 || attr
->is_numeric
)
948 error_with_line (attr
? attr
->lineno
: 0,
949 "non-numeric value for numeric attribute %s",
950 attr
? attr
->name
: "internal");
956 for (av
= attr
->first_value
; av
; av
= av
->next
)
957 if (GET_CODE (av
->value
) == CONST_STRING
958 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
962 error_with_line (attr
->lineno
,
963 "unknown value `%s' for `%s' attribute",
964 XSTR (exp
, 0), attr
? attr
->name
: "internal");
968 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
969 attr
? attr
->is_const
: 0,
970 attr
? attr
->lineno
: 0);
971 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
972 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
980 if (attr
&& !attr
->is_numeric
)
982 error_with_line (attr
->lineno
,
983 "invalid operation `%s' for non-numeric"
984 " attribute value", GET_RTX_NAME (GET_CODE (exp
)));
991 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
992 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1001 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1005 if (XVECLEN (exp
, 0) % 2 != 0)
1007 error_with_line (attr
->lineno
,
1008 "first operand of COND must have even length");
1012 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1014 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1015 attr
? attr
->is_const
: 0,
1016 attr
? attr
->lineno
: 0);
1017 XVECEXP (exp
, 0, i
+ 1)
1018 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1021 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1026 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1028 error_with_line (attr
? attr
->lineno
: 0,
1029 "unknown attribute `%s' in ATTR",
1031 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1032 error_with_line (attr
->lineno
,
1033 "non-constant attribute `%s' referenced from `%s'",
1034 XSTR (exp
, 0), attr
->name
);
1036 && attr
->is_numeric
!= attr2
->is_numeric
)
1037 error_with_line (attr
->lineno
,
1038 "numeric attribute mismatch calling `%s' from `%s'",
1039 XSTR (exp
, 0), attr
->name
);
1044 /* A constant SYMBOL_REF is valid as a constant attribute test and
1045 is expanded later by make_canonical into a COND. In a non-constant
1046 attribute test, it is left be. */
1047 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1050 error_with_line (attr
? attr
->lineno
: 0,
1051 "invalid operation `%s' for attribute value",
1052 GET_RTX_NAME (GET_CODE (exp
)));
1059 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1060 It becomes a COND with each test being (eq_attr "alternative" "n") */
1063 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1065 int num_alt
= id
->num_alternatives
;
1069 if (XVECLEN (exp
, 1) != num_alt
)
1071 error_with_line (id
->lineno
,
1072 "bad number of entries in SET_ATTR_ALTERNATIVE");
1076 /* Make a COND with all tests but the last. Select the last value via the
1078 condexp
= rtx_alloc (COND
);
1079 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1081 for (i
= 0; i
< num_alt
- 1; i
++)
1084 p
= attr_numeral (i
);
1086 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1087 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1090 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1092 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1095 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1096 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1099 convert_set_attr (rtx exp
, struct insn_def
*id
)
1102 const char *name_ptr
;
1106 /* See how many alternative specified. */
1107 n
= n_comma_elts (XSTR (exp
, 1));
1109 return attr_rtx (SET
,
1110 attr_rtx (ATTR
, XSTR (exp
, 0)),
1111 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1113 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1114 XSTR (newexp
, 0) = XSTR (exp
, 0);
1115 XVEC (newexp
, 1) = rtvec_alloc (n
);
1117 /* Process each comma-separated name. */
1118 name_ptr
= XSTR (exp
, 1);
1120 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1121 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1123 return convert_set_attr_alternative (newexp
, id
);
1126 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1127 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1133 struct insn_def
*id
;
1134 struct attr_desc
*attr
;
1138 for (id
= defs
; id
; id
= id
->next
)
1140 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1143 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1145 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1146 switch (GET_CODE (value
))
1149 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1151 error_with_line (id
->lineno
, "bad attribute set");
1156 case SET_ATTR_ALTERNATIVE
:
1157 value
= convert_set_attr_alternative (value
, id
);
1161 value
= convert_set_attr (value
, id
);
1165 error_with_line (id
->lineno
, "invalid attribute code %s",
1166 GET_RTX_NAME (GET_CODE (value
)));
1169 if (value
== NULL_RTX
)
1172 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1174 error_with_line (id
->lineno
, "unknown attribute %s",
1175 XSTR (XEXP (value
, 0), 0));
1179 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1180 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1185 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1186 expressions by converting them into a COND. This removes cases from this
1187 program. Also, replace an attribute value of "*" with the default attribute
1191 make_canonical (struct attr_desc
*attr
, rtx exp
)
1196 switch (GET_CODE (exp
))
1199 exp
= make_numeric_value (INTVAL (exp
));
1203 if (! strcmp (XSTR (exp
, 0), "*"))
1205 if (attr
== 0 || attr
->default_val
== 0)
1206 fatal ("(attr_value \"*\") used in invalid context");
1207 exp
= attr
->default_val
->value
;
1210 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1215 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1217 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1218 This makes the COND something that won't be considered an arbitrary
1219 expression by walk_attr_value. */
1220 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1221 exp
= check_attr_value (exp
, attr
);
1225 newexp
= rtx_alloc (COND
);
1226 XVEC (newexp
, 0) = rtvec_alloc (2);
1227 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1228 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1230 XEXP (newexp
, 1) = XEXP (exp
, 2);
1233 /* Fall through to COND case since this is now a COND. */
1240 /* First, check for degenerate COND. */
1241 if (XVECLEN (exp
, 0) == 0)
1242 return make_canonical (attr
, XEXP (exp
, 1));
1243 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1245 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1247 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1248 XVECEXP (exp
, 0, i
+ 1)
1249 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1250 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1266 copy_boolean (rtx exp
)
1268 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1269 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1270 copy_boolean (XEXP (exp
, 1)));
1271 if (GET_CODE (exp
) == MATCH_OPERAND
)
1273 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1274 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1276 else if (GET_CODE (exp
) == EQ_ATTR
)
1278 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1279 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1285 /* Given a value and an attribute description, return a `struct attr_value *'
1286 that represents that value. This is either an existing structure, if the
1287 value has been previously encountered, or a newly-created structure.
1289 `insn_code' is the code of an insn whose attribute has the specified
1290 value (-2 if not processing an insn). We ensure that all insns for
1291 a given value have the same number of alternatives if the value checks
1294 static struct attr_value
*
1295 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1297 struct attr_value
*av
;
1300 value
= make_canonical (attr
, value
);
1301 if (compares_alternatives_p (value
))
1303 if (insn_code
< 0 || insn_alternatives
== NULL
)
1304 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1306 num_alt
= insn_alternatives
[insn_code
];
1309 for (av
= attr
->first_value
; av
; av
= av
->next
)
1310 if (rtx_equal_p (value
, av
->value
)
1311 && (num_alt
== 0 || av
->first_insn
== NULL
1312 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1315 av
= oballoc (struct attr_value
);
1317 av
->next
= attr
->first_value
;
1318 attr
->first_value
= av
;
1319 av
->first_insn
= NULL
;
1321 av
->has_asm_insn
= 0;
1326 /* After all DEFINE_DELAYs have been read in, create internal attributes
1327 to generate the required routines.
1329 First, we compute the number of delay slots for each insn (as a COND of
1330 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1331 delay type is specified, we compute a similar function giving the
1332 DEFINE_DELAY ordinal for each insn.
1334 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1335 tells whether a given insn can be in that delay slot.
1337 Normal attribute filling and optimization expands these to contain the
1338 information needed to handle delay slots. */
1341 expand_delays (void)
1343 struct delay_desc
*delay
;
1349 /* First, generate data for `num_delay_slots' function. */
1351 condexp
= rtx_alloc (COND
);
1352 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1353 XEXP (condexp
, 1) = make_numeric_value (0);
1355 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1357 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1358 XVECEXP (condexp
, 0, i
+ 1)
1359 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1362 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1364 /* If more than one delay type, do the same for computing the delay type. */
1367 condexp
= rtx_alloc (COND
);
1368 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1369 XEXP (condexp
, 1) = make_numeric_value (0);
1371 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1373 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1374 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1377 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1380 /* For each delay possibility and delay slot, compute an eligibility
1381 attribute for non-annulled insns and for each type of annulled (annul
1382 if true and annul if false). */
1383 for (delay
= delays
; delay
; delay
= delay
->next
)
1385 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1387 condexp
= XVECEXP (delay
->def
, 1, i
);
1389 condexp
= false_rtx
;
1390 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1391 make_numeric_value (1), make_numeric_value (0));
1393 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1394 "*delay_%d_%d", delay
->num
, i
/ 3);
1395 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1397 if (have_annul_true
)
1399 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1400 if (condexp
== 0) condexp
= false_rtx
;
1401 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1402 make_numeric_value (1),
1403 make_numeric_value (0));
1404 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1405 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1406 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1409 if (have_annul_false
)
1411 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1412 if (condexp
== 0) condexp
= false_rtx
;
1413 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1414 make_numeric_value (1),
1415 make_numeric_value (0));
1416 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1417 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1418 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1424 /* Once all attributes and insns have been read and checked, we construct for
1425 each attribute value a list of all the insns that have that value for
1429 fill_attr (struct attr_desc
*attr
)
1431 struct attr_value
*av
;
1432 struct insn_ent
*ie
;
1433 struct insn_def
*id
;
1437 /* Don't fill constant attributes. The value is independent of
1438 any particular insn. */
1442 for (id
= defs
; id
; id
= id
->next
)
1444 /* If no value is specified for this insn for this attribute, use the
1447 if (XVEC (id
->def
, id
->vec_idx
))
1448 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1449 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1451 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1454 av
= attr
->default_val
;
1456 av
= get_attr_value (value
, attr
, id
->insn_code
);
1458 ie
= oballoc (struct insn_ent
);
1460 insert_insn_ent (av
, ie
);
1464 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1465 test that checks relative positions of insns (uses MATCH_DUP or PC).
1466 If so, replace it with what is obtained by passing the expression to
1467 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1468 recursively on each value (including the default value). Otherwise,
1469 return the value returned by NO_ADDRESS_FN applied to EXP. */
1472 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1473 rtx (*address_fn
) (rtx
))
1478 if (GET_CODE (exp
) == COND
)
1480 /* See if any tests use addresses. */
1482 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1483 walk_attr_value (XVECEXP (exp
, 0, i
));
1486 return (*address_fn
) (exp
);
1488 /* Make a new copy of this COND, replacing each element. */
1489 newexp
= rtx_alloc (COND
);
1490 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1491 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1493 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1494 XVECEXP (newexp
, 0, i
+ 1)
1495 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1496 no_address_fn
, address_fn
);
1499 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1500 no_address_fn
, address_fn
);
1505 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1508 walk_attr_value (XEXP (exp
, 0));
1510 return (*address_fn
) (exp
);
1512 return attr_rtx (IF_THEN_ELSE
,
1513 substitute_address (XEXP (exp
, 0),
1514 no_address_fn
, address_fn
),
1515 substitute_address (XEXP (exp
, 1),
1516 no_address_fn
, address_fn
),
1517 substitute_address (XEXP (exp
, 2),
1518 no_address_fn
, address_fn
));
1521 return (*no_address_fn
) (exp
);
1524 /* Make new attributes from the `length' attribute. The following are made,
1525 each corresponding to a function called from `shorten_branches' or
1528 *insn_default_length This is the length of the insn to be returned
1529 by `get_attr_length' before `shorten_branches'
1530 has been called. In each case where the length
1531 depends on relative addresses, the largest
1532 possible is used. This routine is also used
1533 to compute the initial size of the insn.
1535 *insn_variable_length_p This returns 1 if the insn's length depends
1536 on relative addresses, zero otherwise.
1538 *insn_current_length This is only called when it is known that the
1539 insn has a variable length and returns the
1540 current length, based on relative addresses.
1544 make_length_attrs (void)
1546 static const char *new_names
[] =
1548 "*insn_default_length",
1550 "*insn_variable_length_p",
1551 "*insn_current_length"
1553 static rtx (*const no_address_fn
[]) (rtx
)
1554 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1555 static rtx (*const address_fn
[]) (rtx
)
1556 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1558 struct attr_desc
*length_attr
, *new_attr
;
1559 struct attr_value
*av
, *new_av
;
1560 struct insn_ent
*ie
, *new_ie
;
1562 /* See if length attribute is defined. If so, it must be numeric. Make
1563 it special so we don't output anything for it. */
1564 length_attr
= find_attr (&length_str
, 0);
1565 if (length_attr
== 0)
1568 if (! length_attr
->is_numeric
)
1569 fatal ("length attribute must be numeric");
1571 length_attr
->is_const
= 0;
1572 length_attr
->is_special
= 1;
1574 /* Make each new attribute, in turn. */
1575 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1577 make_internal_attr (new_names
[i
],
1578 substitute_address (length_attr
->default_val
->value
,
1579 no_address_fn
[i
], address_fn
[i
]),
1581 new_attr
= find_attr (&new_names
[i
], 0);
1582 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1583 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1585 new_av
= get_attr_value (substitute_address (av
->value
,
1588 new_attr
, ie
->def
->insn_code
);
1589 new_ie
= oballoc (struct insn_ent
);
1590 new_ie
->def
= ie
->def
;
1591 insert_insn_ent (new_av
, new_ie
);
1596 /* Utility functions called from above routine. */
1599 identity_fn (rtx exp
)
1605 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1607 return make_numeric_value (0);
1611 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1613 return make_numeric_value (1);
1620 return make_numeric_value (max_attr_value (exp
, &unknown
));
1627 return make_numeric_value (min_attr_value (exp
, &unknown
));
1631 write_length_unit_log (FILE *outf
)
1633 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1634 struct attr_value
*av
;
1635 struct insn_ent
*ie
;
1636 unsigned int length_unit_log
, length_or
;
1639 if (length_attr
== 0)
1641 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1642 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1643 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1644 length_or
|= or_attr_value (av
->value
, &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 /* Take a COND expression and see if any of the conditions in it can be
1658 simplified. If any are known true or known false for the particular insn
1659 code, the COND can be further simplified.
1661 Also call ourselves on any COND operations that are values of this COND.
1663 We do not modify EXP; rather, we make and return a new rtx. */
1666 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1669 /* We store the desired contents here,
1670 then build a new expression if they don't match EXP. */
1671 rtx defval
= XEXP (exp
, 1);
1672 rtx new_defval
= XEXP (exp
, 1);
1673 int len
= XVECLEN (exp
, 0);
1674 rtx
*tests
= XNEWVEC (rtx
, len
);
1678 /* This lets us free all storage allocated below, if appropriate. */
1679 obstack_finish (rtl_obstack
);
1681 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1683 /* See if default value needs simplification. */
1684 if (GET_CODE (defval
) == COND
)
1685 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1687 /* Simplify the subexpressions, and see what tests we can get rid of. */
1689 for (i
= 0; i
< len
; i
+= 2)
1691 rtx newtest
, newval
;
1693 /* Simplify this test. */
1694 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1697 newval
= tests
[i
+ 1];
1698 /* See if this value may need simplification. */
1699 if (GET_CODE (newval
) == COND
)
1700 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1702 /* Look for ways to delete or combine this test. */
1703 if (newtest
== true_rtx
)
1705 /* If test is true, make this value the default
1706 and discard this + any following tests. */
1708 defval
= tests
[i
+ 1];
1709 new_defval
= newval
;
1712 else if (newtest
== false_rtx
)
1714 /* If test is false, discard it and its value. */
1715 for (j
= i
; j
< len
- 2; j
++)
1716 tests
[j
] = tests
[j
+ 2];
1721 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1723 /* If this value and the value for the prev test are the same,
1727 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1728 insn_code
, insn_index
);
1730 /* Delete this test/value. */
1731 for (j
= i
; j
< len
- 2; j
++)
1732 tests
[j
] = tests
[j
+ 2];
1738 tests
[i
+ 1] = newval
;
1741 /* If the last test in a COND has the same value
1742 as the default value, that test isn't needed. */
1744 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1747 /* See if we changed anything. */
1748 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1751 for (i
= 0; i
< len
; i
++)
1752 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1760 if (GET_CODE (defval
) == COND
)
1761 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1769 rtx newexp
= rtx_alloc (COND
);
1771 XVEC (newexp
, 0) = rtvec_alloc (len
);
1772 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1773 XEXP (newexp
, 1) = new_defval
;
1780 /* Remove an insn entry from an attribute value. */
1783 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1785 struct insn_ent
*previe
;
1787 if (av
->first_insn
== ie
)
1788 av
->first_insn
= ie
->next
;
1791 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1793 previe
->next
= ie
->next
;
1797 if (ie
->def
->insn_code
== -1)
1798 av
->has_asm_insn
= 0;
1803 /* Insert an insn entry in an attribute value list. */
1806 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1808 ie
->next
= av
->first_insn
;
1809 av
->first_insn
= ie
;
1811 if (ie
->def
->insn_code
== -1)
1812 av
->has_asm_insn
= 1;
1817 /* This is a utility routine to take an expression that is a tree of either
1818 AND or IOR expressions and insert a new term. The new term will be
1819 inserted at the right side of the first node whose code does not match
1820 the root. A new node will be created with the root's code. Its left
1821 side will be the old right side and its right side will be the new
1824 If the `term' is itself a tree, all its leaves will be inserted. */
1827 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1831 /* Avoid consing in some special cases. */
1832 if (code
== AND
&& term
== true_rtx
)
1834 if (code
== AND
&& term
== false_rtx
)
1836 if (code
== AND
&& exp
== true_rtx
)
1838 if (code
== AND
&& exp
== false_rtx
)
1840 if (code
== IOR
&& term
== true_rtx
)
1842 if (code
== IOR
&& term
== false_rtx
)
1844 if (code
== IOR
&& exp
== true_rtx
)
1846 if (code
== IOR
&& exp
== false_rtx
)
1848 if (attr_equal_p (exp
, term
))
1851 if (GET_CODE (term
) == code
)
1853 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1854 insn_code
, insn_index
);
1855 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1856 insn_code
, insn_index
);
1861 if (GET_CODE (exp
) == code
)
1863 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1864 term
, insn_code
, insn_index
);
1865 if (new_rtx
!= XEXP (exp
, 1))
1866 /* Make a copy of this expression and call recursively. */
1867 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1873 /* Insert the new term. */
1874 newexp
= attr_rtx (code
, exp
, term
);
1877 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1880 /* If we have an expression which AND's a bunch of
1881 (not (eq_attrq "alternative" "n"))
1882 terms, we may have covered all or all but one of the possible alternatives.
1883 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1885 This routine is passed an expression and either AND or IOR. It returns a
1886 bitmask indicating which alternatives are mentioned within EXP. */
1889 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1892 if (GET_CODE (exp
) == code
)
1893 return compute_alternative_mask (XEXP (exp
, 0), code
)
1894 | compute_alternative_mask (XEXP (exp
, 1), code
);
1896 else if (code
== AND
&& GET_CODE (exp
) == NOT
1897 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1898 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1899 string
= XSTR (XEXP (exp
, 0), 1);
1901 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1902 && XSTR (exp
, 0) == alternative_name
)
1903 string
= XSTR (exp
, 1);
1905 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1907 if (code
== AND
&& XINT (exp
, 1))
1908 return XINT (exp
, 0);
1910 if (code
== IOR
&& !XINT (exp
, 1))
1911 return XINT (exp
, 0);
1919 return 1 << (string
[0] - '0');
1920 return 1 << atoi (string
);
1923 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1924 attribute with the value represented by that bit. */
1927 make_alternative_compare (int mask
)
1929 return mk_attr_alt (mask
);
1932 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1933 of "attr" for this insn code. From that value, we can compute a test
1934 showing when the EQ_ATTR will be true. This routine performs that
1935 computation. If a test condition involves an address, we leave the EQ_ATTR
1936 intact because addresses are only valid for the `length' attribute.
1938 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1939 it refers. VALUE is the value of that attribute for the insn
1940 corresponding to INSN_CODE and INSN_INDEX. */
1943 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1944 int insn_code
, int insn_index
)
1951 while (GET_CODE (value
) == ATTR
)
1953 struct attr_value
*av
= NULL
;
1955 attr
= find_attr (&XSTR (value
, 0), 0);
1957 if (insn_code_values
)
1959 struct attr_value_list
*iv
;
1960 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
1961 if (iv
->attr
== attr
)
1969 struct insn_ent
*ie
;
1970 for (av
= attr
->first_value
; av
; av
= av
->next
)
1971 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1972 if (ie
->def
->insn_code
== insn_code
)
1982 switch (GET_CODE (value
))
1985 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
1996 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
1997 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
1998 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
1999 for (p
= string
; *p
; p
++)
2002 newexp
= attr_rtx (EQ
, value
,
2003 attr_rtx (SYMBOL_REF
,
2004 DEF_ATTR_STRING (string
)));
2009 /* We construct an IOR of all the cases for which the
2010 requested attribute value is present. Since we start with
2011 FALSE, if it is not present, FALSE will be returned.
2013 Each case is the AND of the NOT's of the previous conditions with the
2014 current condition; in the default case the current condition is TRUE.
2016 For each possible COND value, call ourselves recursively.
2018 The extra TRUE and FALSE expressions will be eliminated by another
2019 call to the simplification routine. */
2024 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2026 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2027 insn_code
, insn_index
);
2029 right
= insert_right_side (AND
, andexp
, this_cond
,
2030 insn_code
, insn_index
);
2031 right
= insert_right_side (AND
, right
,
2032 evaluate_eq_attr (exp
, attr
,
2035 insn_code
, insn_index
),
2036 insn_code
, insn_index
);
2037 orexp
= insert_right_side (IOR
, orexp
, right
,
2038 insn_code
, insn_index
);
2040 /* Add this condition into the AND expression. */
2041 newexp
= attr_rtx (NOT
, this_cond
);
2042 andexp
= insert_right_side (AND
, andexp
, newexp
,
2043 insn_code
, insn_index
);
2046 /* Handle the default case. */
2047 right
= insert_right_side (AND
, andexp
,
2048 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2049 insn_code
, insn_index
),
2050 insn_code
, insn_index
);
2051 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2058 /* If uses an address, must return original expression. But set the
2059 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2062 walk_attr_value (newexp
);
2066 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2067 return copy_rtx_unchanging (exp
);
2074 /* This routine is called when an AND of a term with a tree of AND's is
2075 encountered. If the term or its complement is present in the tree, it
2076 can be replaced with TRUE or FALSE, respectively.
2078 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2079 be true and hence are complementary.
2081 There is one special case: If we see
2082 (and (not (eq_attr "att" "v1"))
2083 (eq_attr "att" "v2"))
2084 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2085 replace the term, not anything in the AND tree. So we pass a pointer to
2089 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2094 int left_eliminates_term
, right_eliminates_term
;
2096 if (GET_CODE (exp
) == AND
)
2098 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2099 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2100 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2102 newexp
= attr_rtx (AND
, left
, right
);
2104 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2108 else if (GET_CODE (exp
) == IOR
)
2110 /* For the IOR case, we do the same as above, except that we can
2111 only eliminate `term' if both sides of the IOR would do so. */
2113 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2114 left_eliminates_term
= (temp
== true_rtx
);
2117 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2118 right_eliminates_term
= (temp
== true_rtx
);
2120 if (left_eliminates_term
&& right_eliminates_term
)
2123 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2125 newexp
= attr_rtx (IOR
, left
, right
);
2127 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2131 /* Check for simplifications. Do some extra checking here since this
2132 routine is called so many times. */
2137 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2140 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2143 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2145 if (attr_alt_subset_p (*pterm
, exp
))
2148 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2151 if (attr_alt_subset_p (exp
, *pterm
))
2157 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2159 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2162 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2168 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2169 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2171 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2174 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2180 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2181 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2183 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2186 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2192 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2194 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2198 else if (GET_CODE (exp
) == NOT
)
2200 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2204 else if (GET_CODE (*pterm
) == NOT
)
2206 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2210 else if (attr_equal_p (exp
, *pterm
))
2216 /* Similar to `simplify_and_tree', but for IOR trees. */
2219 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2224 int left_eliminates_term
, right_eliminates_term
;
2226 if (GET_CODE (exp
) == IOR
)
2228 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2229 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2230 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2232 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2234 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2238 else if (GET_CODE (exp
) == AND
)
2240 /* For the AND case, we do the same as above, except that we can
2241 only eliminate `term' if both sides of the AND would do so. */
2243 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2244 left_eliminates_term
= (temp
== false_rtx
);
2247 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2248 right_eliminates_term
= (temp
== false_rtx
);
2250 if (left_eliminates_term
&& right_eliminates_term
)
2253 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2255 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2257 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2261 if (attr_equal_p (exp
, *pterm
))
2264 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2267 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2270 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2271 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2272 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2275 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2276 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2277 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2283 /* Compute approximate cost of the expression. Used to decide whether
2284 expression is cheap enough for inline. */
2286 attr_rtx_cost (rtx x
)
2292 code
= GET_CODE (x
);
2305 /* Alternatives don't result into function call. */
2306 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2313 const char *fmt
= GET_RTX_FORMAT (code
);
2314 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2320 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2321 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2324 cost
+= attr_rtx_cost (XEXP (x
, i
));
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
);
2666 /* See if all or all but one of the insn's alternatives are specified
2667 in this tree. Optimize if so. */
2669 else if (insn_code
>= 0
2670 && (GET_CODE (left
) == IOR
2671 || (GET_CODE (left
) == EQ_ATTR_ALT
2673 || (GET_CODE (left
) == EQ_ATTR
2674 && XSTR (left
, 0) == alternative_name
)
2675 || GET_CODE (right
) == IOR
2676 || (GET_CODE (right
) == EQ_ATTR_ALT
2677 && !XINT (right
, 1))
2678 || (GET_CODE (right
) == EQ_ATTR
2679 && XSTR (right
, 0) == alternative_name
)))
2681 i
= compute_alternative_mask (exp
, IOR
);
2682 if (i
& ~insn_alternatives
[insn_code
])
2683 fatal ("invalid alternative specified for pattern number %d",
2686 /* If all alternatives are included, this is true. */
2687 i
^= insn_alternatives
[insn_code
];
2690 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2692 /* If just one excluded, IOR a comparison with that one to the
2693 front of the tree. The others will be eliminated by
2694 optimization. We do not want to do this if the insn has one
2695 alternative and we have tested none of them! */
2696 left
= make_alternative_compare (i
);
2697 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2698 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2700 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2704 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2706 newexp
= attr_rtx (IOR
, left
, right
);
2707 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2712 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2714 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2715 insn_code
, insn_index
);
2719 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2720 if (GET_CODE (left
) == NOT
)
2721 return XEXP (left
, 0);
2723 if (left
== false_rtx
)
2725 if (left
== true_rtx
)
2728 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2730 exp
= attr_alt_complement (left
);
2731 return simplify_test_exp (exp
, insn_code
, insn_index
);
2734 /* Try to apply De`Morgan's laws. */
2735 if (GET_CODE (left
) == IOR
)
2737 newexp
= attr_rtx (AND
,
2738 attr_rtx (NOT
, XEXP (left
, 0)),
2739 attr_rtx (NOT
, XEXP (left
, 1)));
2741 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2743 else if (GET_CODE (left
) == AND
)
2745 newexp
= attr_rtx (IOR
,
2746 attr_rtx (NOT
, XEXP (left
, 0)),
2747 attr_rtx (NOT
, XEXP (left
, 1)));
2749 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2751 else if (left
!= XEXP (exp
, 0))
2753 newexp
= attr_rtx (NOT
, left
);
2759 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2763 if (XSTR (exp
, 0) == alternative_name
)
2765 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2769 /* Look at the value for this insn code in the specified attribute.
2770 We normally can replace this comparison with the condition that
2771 would give this insn the values being tested for. */
2773 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2778 if (insn_code_values
)
2780 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2781 if (iv
->attr
== attr
)
2789 for (av
= attr
->first_value
; av
; av
= av
->next
)
2790 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2791 if (ie
->def
->insn_code
== insn_code
)
2798 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2799 insn_code
, insn_index
);
2800 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2801 if (attr_rtx_cost(x
) < 20)
2811 /* We have already simplified this expression. Simplifying it again
2812 won't buy anything unless we weren't given a valid insn code
2813 to process (i.e., we are canonicalizing something.). */
2815 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2816 return copy_rtx_unchanging (newexp
);
2821 /* Optimize the attribute lists by seeing if we can determine conditional
2822 values from the known values of other attributes. This will save subroutine
2823 calls during the compilation. */
2826 optimize_attrs (void)
2828 struct attr_desc
*attr
;
2829 struct attr_value
*av
;
2830 struct insn_ent
*ie
;
2833 struct attr_value_list
*ivbuf
;
2834 struct attr_value_list
*iv
;
2836 /* For each insn code, make a list of all the insn_ent's for it,
2837 for all values for all attributes. */
2839 if (num_insn_ents
== 0)
2842 /* Make 2 extra elements, for "code" values -2 and -1. */
2843 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2845 /* Offset the table address so we can index by -2 or -1. */
2846 insn_code_values
+= 2;
2848 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2850 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2851 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2852 for (av
= attr
->first_value
; av
; av
= av
->next
)
2853 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2858 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2859 insn_code_values
[ie
->def
->insn_code
] = iv
;
2863 /* Sanity check on num_insn_ents. */
2864 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2866 /* Process one insn code at a time. */
2867 for (i
= -2; i
< insn_code_number
; i
++)
2869 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2870 We use it to mean "already simplified for this insn". */
2871 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2872 clear_struct_flag (iv
->av
->value
);
2874 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2876 struct obstack
*old
= rtl_obstack
;
2881 if (GET_CODE (av
->value
) != COND
)
2884 rtl_obstack
= temp_obstack
;
2886 while (GET_CODE (newexp
) == COND
)
2888 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2889 ie
->def
->insn_index
);
2890 if (newexp2
== newexp
)
2896 if (newexp
!= av
->value
)
2898 newexp
= attr_copy_rtx (newexp
);
2899 remove_insn_ent (av
, ie
);
2900 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2902 insert_insn_ent (av
, ie
);
2908 free (insn_code_values
- 2);
2909 insn_code_values
= NULL
;
2912 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2915 clear_struct_flag (rtx x
)
2922 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2923 if (ATTR_IND_SIMPLIFIED_P (x
))
2926 code
= GET_CODE (x
);
2947 /* Compare the elements. If any pair of corresponding elements
2948 fail to match, return 0 for the whole things. */
2950 fmt
= GET_RTX_FORMAT (code
);
2951 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2957 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2958 clear_struct_flag (XVECEXP (x
, i
, j
));
2962 clear_struct_flag (XEXP (x
, i
));
2968 /* Add attribute value NAME to the beginning of ATTR's list. */
2971 add_attr_value (struct attr_desc
*attr
, const char *name
)
2973 struct attr_value
*av
;
2975 av
= oballoc (struct attr_value
);
2976 av
->value
= attr_rtx (CONST_STRING
, name
);
2977 av
->next
= attr
->first_value
;
2978 attr
->first_value
= av
;
2979 av
->first_insn
= NULL
;
2981 av
->has_asm_insn
= 0;
2984 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
2987 gen_attr (rtx exp
, int lineno
)
2989 struct enum_type
*et
;
2990 struct enum_value
*ev
;
2991 struct attr_desc
*attr
;
2992 const char *name_ptr
;
2995 /* Make a new attribute structure. Check for duplicate by looking at
2996 attr->default_val, since it is initialized by this routine. */
2997 attr
= find_attr (&XSTR (exp
, 0), 1);
2998 if (attr
->default_val
)
3000 error_with_line (lineno
, "duplicate definition for attribute %s",
3002 message_with_line (attr
->lineno
, "previous definition");
3005 attr
->lineno
= lineno
;
3007 if (GET_CODE (exp
) == DEFINE_ENUM_ATTR
)
3009 attr
->enum_name
= XSTR (exp
, 1);
3010 et
= lookup_enum_type (XSTR (exp
, 1));
3011 if (!et
|| !et
->md_p
)
3012 error_with_line (lineno
, "No define_enum called `%s' defined",
3015 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3016 add_attr_value (attr
, ev
->name
);
3018 else if (*XSTR (exp
, 1) == '\0')
3019 attr
->is_numeric
= 1;
3022 name_ptr
= XSTR (exp
, 1);
3023 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3024 add_attr_value (attr
, p
);
3027 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3030 if (attr
->is_numeric
)
3031 error_with_line (lineno
,
3032 "constant attributes may not take numeric values");
3034 /* Get rid of the CONST node. It is allowed only at top-level. */
3035 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3038 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3039 error_with_line (lineno
, "`length' attribute must take numeric values");
3041 /* Set up the default value. */
3042 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3043 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3046 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3047 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3048 number of alternatives as this should be checked elsewhere. */
3051 count_alternatives (rtx exp
)
3056 if (GET_CODE (exp
) == MATCH_OPERAND
)
3057 return n_comma_elts (XSTR (exp
, 2));
3059 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3060 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3065 n
= count_alternatives (XEXP (exp
, i
));
3072 if (XVEC (exp
, i
) != NULL
)
3073 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3075 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3084 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3085 `alternative' attribute. */
3088 compares_alternatives_p (rtx exp
)
3093 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3096 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3097 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3102 if (compares_alternatives_p (XEXP (exp
, i
)))
3107 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3108 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3116 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3119 gen_insn (rtx exp
, int lineno
)
3121 struct insn_def
*id
;
3123 id
= oballoc (struct insn_def
);
3127 id
->lineno
= lineno
;
3129 switch (GET_CODE (exp
))
3132 id
->insn_code
= insn_code_number
;
3133 id
->insn_index
= insn_index_number
;
3134 id
->num_alternatives
= count_alternatives (exp
);
3135 if (id
->num_alternatives
== 0)
3136 id
->num_alternatives
= 1;
3140 case DEFINE_PEEPHOLE
:
3141 id
->insn_code
= insn_code_number
;
3142 id
->insn_index
= insn_index_number
;
3143 id
->num_alternatives
= count_alternatives (exp
);
3144 if (id
->num_alternatives
== 0)
3145 id
->num_alternatives
= 1;
3149 case DEFINE_ASM_ATTRIBUTES
:
3151 id
->insn_index
= -1;
3152 id
->num_alternatives
= 1;
3154 got_define_asm_attributes
= 1;
3162 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3163 true or annul false is specified, and make a `struct delay_desc'. */
3166 gen_delay (rtx def
, int lineno
)
3168 struct delay_desc
*delay
;
3171 if (XVECLEN (def
, 1) % 3 != 0)
3173 error_with_line (lineno
,
3174 "number of elements in DEFINE_DELAY must"
3175 " be multiple of three");
3179 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3181 if (XVECEXP (def
, 1, i
+ 1))
3182 have_annul_true
= 1;
3183 if (XVECEXP (def
, 1, i
+ 2))
3184 have_annul_false
= 1;
3187 delay
= oballoc (struct delay_desc
);
3189 delay
->num
= ++num_delays
;
3190 delay
->next
= delays
;
3191 delay
->lineno
= lineno
;
3195 /* Names of attributes that could be possibly cached. */
3196 static const char *cached_attrs
[32];
3197 /* Number of such attributes. */
3198 static int cached_attr_count
;
3199 /* Bitmasks of possibly cached attributes. */
3200 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3201 static unsigned int attrs_to_cache
;
3202 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3204 /* Finds non-const attributes that could be possibly cached.
3205 When create is TRUE, fills in cached_attrs array.
3206 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3210 find_attrs_to_cache (rtx exp
, bool create
)
3214 struct attr_desc
*attr
;
3219 switch (GET_CODE (exp
))
3222 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3223 find_attrs_to_cache (XEXP (exp
, 0), create
);
3227 name
= XSTR (exp
, 0);
3228 if (name
== alternative_name
)
3230 for (i
= 0; i
< cached_attr_count
; i
++)
3231 if (name
== cached_attrs
[i
])
3233 if ((attrs_seen_once
& (1U << i
)) != 0)
3234 attrs_seen_more_than_once
|= (1U << i
);
3236 attrs_seen_once
|= (1U << i
);
3241 attr
= find_attr (&name
, 0);
3245 if (cached_attr_count
== 32)
3247 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3248 attrs_seen_once
|= (1U << cached_attr_count
);
3249 cached_attr_count
++;
3254 find_attrs_to_cache (XEXP (exp
, 0), create
);
3255 find_attrs_to_cache (XEXP (exp
, 1), create
);
3259 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3260 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3268 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3269 We use AND and IOR both for logical and bit-wise operations, so
3270 interpret them as logical unless they are inside a comparison expression. */
3272 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3273 #define FLG_BITWISE 1
3274 /* Set if cached attribute will be known initialized in else block after
3275 this condition. This is true for LHS of toplevel && and || and
3276 even for RHS of ||, but not for RHS of &&. */
3278 /* Set if cached attribute will be known initialized in then block after
3279 this condition. This is true for LHS of toplevel && and || and
3280 even for RHS of &&, but not for RHS of ||. */
3281 #define FLG_INSIDE 4
3282 /* Cleared when an operand of &&. */
3283 #define FLG_OUTSIDE_AND 8
3286 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
)
3288 int comparison_operator
= 0;
3290 struct attr_desc
*attr
;
3292 /* In order not to worry about operator precedence, surround our part of
3293 the expression with parentheses. */
3295 fprintf (outf
, "(");
3296 code
= GET_CODE (exp
);
3299 /* Binary operators. */
3302 fprintf (outf
, "(unsigned) ");
3308 comparison_operator
= FLG_BITWISE
;
3310 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3311 case AND
: case IOR
: case XOR
:
3312 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3313 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3315 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3316 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3317 flags
| comparison_operator
);
3322 flags
&= ~FLG_OUTSIDE_AND
;
3323 if (GET_CODE (XEXP (exp
, 0)) == code
3324 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3325 || (GET_CODE (XEXP (exp
, 0)) == NOT
3326 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3328 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3330 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3335 fprintf (outf
, " == ");
3338 fprintf (outf
, " != ");
3341 fprintf (outf
, " >= ");
3344 fprintf (outf
, " > ");
3347 fprintf (outf
, " >= (unsigned) ");
3350 fprintf (outf
, " > (unsigned) ");
3353 fprintf (outf
, " <= ");
3356 fprintf (outf
, " < ");
3359 fprintf (outf
, " <= (unsigned) ");
3362 fprintf (outf
, " < (unsigned) ");
3365 fprintf (outf
, " + ");
3368 fprintf (outf
, " - ");
3371 fprintf (outf
, " * ");
3374 fprintf (outf
, " / ");
3377 fprintf (outf
, " %% ");
3380 if (flags
& FLG_BITWISE
)
3381 fprintf (outf
, " & ");
3383 fprintf (outf
, " && ");
3386 if (flags
& FLG_BITWISE
)
3387 fprintf (outf
, " | ");
3389 fprintf (outf
, " || ");
3392 fprintf (outf
, " ^ ");
3395 fprintf (outf
, " << ");
3399 fprintf (outf
, " >> ");
3407 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3408 cached_x is only known to be initialized in then block. */
3409 flags
&= ~FLG_AFTER
;
3411 else if (code
== IOR
)
3413 if (flags
& FLG_OUTSIDE_AND
)
3414 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3415 cached_x is only known to be initialized in else block
3416 and else if conditions. */
3417 flags
&= ~FLG_INSIDE
;
3419 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3421 cached_x is not know to be initialized anywhere. */
3422 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3424 if ((code
== AND
|| code
== IOR
)
3425 && (GET_CODE (XEXP (exp
, 1)) == code
3426 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3427 || (GET_CODE (XEXP (exp
, 1)) == NOT
3428 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3430 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
);
3432 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3433 flags
| comparison_operator
);
3437 /* Special-case (not (eq_attrq "alternative" "x")) */
3438 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3440 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3442 fprintf (outf
, "which_alternative != %s",
3443 XSTR (XEXP (exp
, 0), 1));
3447 fprintf (outf
, "! ");
3449 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3453 /* Otherwise, fall through to normal unary operator. */
3455 /* Unary operators. */
3460 if (flags
& FLG_BITWISE
)
3461 fprintf (outf
, "~ ");
3463 fprintf (outf
, "! ");
3466 fprintf (outf
, "abs ");
3469 fprintf (outf
, "-");
3475 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3476 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3481 int set
= XINT (exp
, 0), bit
= 0;
3483 if (flags
& FLG_BITWISE
)
3484 fatal ("EQ_ATTR_ALT not valid inside comparison");
3487 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3489 if (!(set
& (set
- 1)))
3491 if (!(set
& 0xffff))
3514 fprintf (outf
, "which_alternative %s= %d",
3515 XINT (exp
, 1) ? "!" : "=", bit
);
3519 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3520 XINT (exp
, 1) ? "!" : "", set
);
3525 /* Comparison test of an attribute with a value. Most of these will
3526 have been removed by optimization. Handle "alternative"
3527 specially and give error if EQ_ATTR present inside a comparison. */
3529 if (flags
& FLG_BITWISE
)
3530 fatal ("EQ_ATTR not valid inside comparison");
3532 if (XSTR (exp
, 0) == alternative_name
)
3534 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3538 attr
= find_attr (&XSTR (exp
, 0), 0);
3541 /* Now is the time to expand the value of a constant attribute. */
3544 write_test_expr (outf
,
3545 evaluate_eq_attr (exp
, attr
,
3546 attr
->default_val
->value
,
3553 for (i
= 0; i
< cached_attr_count
; i
++)
3554 if (attr
->name
== cached_attrs
[i
])
3556 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3557 fprintf (outf
, "cached_%s", attr
->name
);
3558 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3560 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3561 attr
->name
, attr
->name
);
3562 if (flags
& FLG_AFTER
)
3563 attrs_cached_after
|= (1U << i
);
3564 if (flags
& FLG_INSIDE
)
3565 attrs_cached_inside
|= (1U << i
);
3566 attrs_cached
|= (1U << i
);
3569 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3570 fprintf (outf
, " == ");
3571 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3575 /* Comparison test of flags for define_delays. */
3577 if (flags
& FLG_BITWISE
)
3578 fatal ("ATTR_FLAG not valid inside comparison");
3579 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3582 /* See if an operand matches a predicate. */
3584 /* If only a mode is given, just ensure the mode matches the operand.
3585 If neither a mode nor predicate is given, error. */
3586 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3588 if (GET_MODE (exp
) == VOIDmode
)
3589 fatal ("null MATCH_OPERAND specified as test");
3591 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3592 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3595 fprintf (outf
, "%s (operands[%d], %smode)",
3596 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3599 /* Constant integer. */
3601 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3605 fprint_c_condition (outf
, XSTR (exp
, 0));
3606 if (flags
& FLG_BITWISE
)
3607 fprintf (outf
, " != 0");
3610 /* A random C expression. */
3612 fprint_c_condition (outf
, XSTR (exp
, 0));
3615 /* The address of the branch target. */
3618 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3619 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3623 /* The address of the current insn. We implement this actually as the
3624 address of the current insn for backward branches, but the last
3625 address of the next insn for forward branches, and both with
3626 adjustments that account for the worst-case possible stretching of
3627 intervening alignments between this insn and its destination. */
3628 fprintf (outf
, "insn_current_reference_address (insn)");
3632 fprintf (outf
, "%s", XSTR (exp
, 0));
3636 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3637 fprintf (outf
, " ? ");
3638 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3639 fprintf (outf
, " : ");
3640 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3644 fatal ("bad RTX code `%s' in attribute calculation\n",
3645 GET_RTX_NAME (code
));
3648 fprintf (outf
, ")");
3649 return attrs_cached
;
3652 /* Given an attribute value, return the maximum CONST_STRING argument
3653 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3656 max_attr_value (rtx exp
, int *unknownp
)
3661 switch (GET_CODE (exp
))
3664 current_max
= atoi (XSTR (exp
, 0));
3668 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3669 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3671 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3672 if (n
> current_max
)
3678 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3679 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3680 if (n
> current_max
)
3686 current_max
= INT_MAX
;
3693 /* Given an attribute value, return the minimum CONST_STRING argument
3694 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3697 min_attr_value (rtx exp
, int *unknownp
)
3702 switch (GET_CODE (exp
))
3705 current_min
= atoi (XSTR (exp
, 0));
3709 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3710 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3712 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3713 if (n
< current_min
)
3719 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3720 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3721 if (n
< current_min
)
3727 current_min
= INT_MAX
;
3734 /* Given an attribute value, return the result of ORing together all
3735 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3736 if the numeric value is not known. */
3739 or_attr_value (rtx exp
, int *unknownp
)
3744 switch (GET_CODE (exp
))
3747 current_or
= atoi (XSTR (exp
, 0));
3751 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3752 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3753 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3757 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3758 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3770 /* Scan an attribute value, possibly a conditional, and record what actions
3771 will be required to do any conditional tests in it.
3774 `must_extract' if we need to extract the insn operands
3775 `must_constrain' if we must compute `which_alternative'
3776 `address_used' if an address expression was used
3777 `length_used' if an (eq_attr "length" ...) was used
3781 walk_attr_value (rtx exp
)
3790 code
= GET_CODE (exp
);
3794 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3795 /* Since this is an arbitrary expression, it can look at anything.
3796 However, constant expressions do not depend on any particular
3798 must_extract
= must_constrain
= 1;
3807 must_extract
= must_constrain
= 1;
3811 if (XSTR (exp
, 0) == alternative_name
)
3812 must_extract
= must_constrain
= 1;
3813 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3833 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3838 walk_attr_value (XEXP (exp
, i
));
3842 if (XVEC (exp
, i
) != NULL
)
3843 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3844 walk_attr_value (XVECEXP (exp
, i
, j
));
3849 /* Write out a function to obtain the attribute for a given INSN. */
3852 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
3854 struct attr_value
*av
, *common_av
;
3857 /* Find the most used attribute value. Handle that as the `default' of the
3858 switch we will generate. */
3859 common_av
= find_most_used (attr
);
3861 /* Write out start of function, then all values with explicit `case' lines,
3862 then a `default', then the value with the most uses. */
3863 if (attr
->enum_name
)
3864 fprintf (outf
, "enum %s\n", attr
->enum_name
);
3865 else if (!attr
->is_numeric
)
3866 fprintf (outf
, "enum attr_%s\n", attr
->name
);
3868 fprintf (outf
, "int\n");
3870 /* If the attribute name starts with a star, the remainder is the name of
3871 the subroutine to use, instead of `get_attr_...'. */
3872 if (attr
->name
[0] == '*')
3873 fprintf (outf
, "%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3874 else if (attr
->is_const
== 0)
3875 fprintf (outf
, "get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3878 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
3879 fprintf (outf
, "{\n");
3881 for (av
= attr
->first_value
; av
; av
= av
->next
)
3882 if (av
->num_insns
== 1)
3883 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
3884 true_rtx
, av
->first_insn
->def
->insn_code
,
3885 av
->first_insn
->def
->insn_index
, 0);
3886 else if (av
->num_insns
!= 0)
3887 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
3888 true_rtx
, -2, 0, 0);
3890 fprintf (outf
, "}\n\n");
3894 fprintf (outf
, "{\n");
3896 /* Find attributes that are worth caching in the conditions. */
3897 cached_attr_count
= 0;
3898 attrs_seen_more_than_once
= 0;
3899 for (av
= attr
->first_value
; av
; av
= av
->next
)
3901 attrs_seen_once
= 0;
3902 find_attrs_to_cache (av
->value
, true);
3904 /* Remove those that aren't worth caching from the array. */
3905 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
3906 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
3908 const char *name
= cached_attrs
[i
];
3909 struct attr_desc
*cached_attr
;
3911 cached_attrs
[j
] = name
;
3912 cached_attr
= find_attr (&name
, 0);
3913 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
3914 if (cached_attr
->enum_name
)
3915 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
3916 else if (!cached_attr
->is_numeric
)
3917 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
3919 fprintf (outf
, " int");
3920 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
3923 cached_attr_count
= j
;
3924 if (cached_attr_count
)
3925 fprintf (outf
, "\n");
3927 fprintf (outf
, " switch (recog_memoized (insn))\n");
3928 fprintf (outf
, " {\n");
3930 for (av
= attr
->first_value
; av
; av
= av
->next
)
3931 if (av
!= common_av
)
3932 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
3934 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3935 fprintf (outf
, " }\n}\n\n");
3936 cached_attr_count
= 0;
3939 /* Given an AND tree of known true terms (because we are inside an `if' with
3940 that as the condition or are in an `else' clause) and an expression,
3941 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3942 the bulk of the work. */
3945 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3949 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3951 if (GET_CODE (known_true
) == AND
)
3953 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3954 insn_code
, insn_index
);
3955 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3956 insn_code
, insn_index
);
3961 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3967 /* Write out a series of tests and assignment statements to perform tests and
3968 sets of an attribute value. We are passed an indentation amount and prefix
3969 and suffix strings to write around each attribute value (e.g., "return"
3973 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
3974 const char *prefix
, const char *suffix
, rtx known_true
,
3975 int insn_code
, int insn_index
, unsigned int attrs_cached
)
3977 if (GET_CODE (value
) == COND
)
3979 /* Assume the default value will be the default of the COND unless we
3980 find an always true expression. */
3981 rtx default_val
= XEXP (value
, 1);
3982 rtx our_known_true
= known_true
;
3987 if (cached_attr_count
)
3989 attrs_seen_once
= 0;
3990 attrs_seen_more_than_once
= 0;
3991 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3992 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
3993 attrs_to_cache
|= attrs_seen_more_than_once
;
3996 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4001 testexp
= eliminate_known_true (our_known_true
,
4002 XVECEXP (value
, 0, i
),
4003 insn_code
, insn_index
);
4004 newexp
= attr_rtx (NOT
, testexp
);
4005 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4006 insn_code
, insn_index
);
4008 /* If the test expression is always true or if the next `known_true'
4009 expression is always false, this is the last case, so break
4010 out and let this value be the `else' case. */
4011 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4013 default_val
= XVECEXP (value
, 0, i
+ 1);
4017 /* Compute the expression to pass to our recursive call as being
4019 inner_true
= insert_right_side (AND
, our_known_true
,
4020 testexp
, insn_code
, insn_index
);
4022 /* If this is always false, skip it. */
4023 if (inner_true
== false_rtx
)
4026 attrs_cached_inside
= attrs_cached
;
4027 attrs_cached_after
= attrs_cached
;
4028 write_indent (outf
, indent
);
4029 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4031 write_test_expr (outf
, testexp
, attrs_cached
,
4032 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4033 attrs_cached
= attrs_cached_after
;
4034 fprintf (outf
, "\n");
4035 write_indent (outf
, indent
+ 2);
4036 fprintf (outf
, "{\n");
4038 write_attr_set (outf
, attr
, indent
+ 4,
4039 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4040 inner_true
, insn_code
, insn_index
,
4041 attrs_cached_inside
);
4042 write_indent (outf
, indent
+ 2);
4043 fprintf (outf
, "}\n");
4044 our_known_true
= newexp
;
4049 write_indent (outf
, indent
);
4050 fprintf (outf
, "else\n");
4051 write_indent (outf
, indent
+ 2);
4052 fprintf (outf
, "{\n");
4055 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4056 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4061 write_indent (outf
, indent
+ 2);
4062 fprintf (outf
, "}\n");
4067 write_indent (outf
, indent
);
4068 fprintf (outf
, "%s ", prefix
);
4069 write_attr_value (outf
, attr
, value
);
4070 fprintf (outf
, "%s\n", suffix
);
4074 /* Write a series of case statements for every instruction in list IE.
4075 INDENT is the amount of indentation to write before each case. */
4078 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4080 for (; ie
!= 0; ie
= ie
->next
)
4081 if (ie
->def
->insn_code
!= -1)
4083 write_indent (outf
, indent
);
4084 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4085 fprintf (outf
, "case %d: /* define_peephole, line %d */\n",
4086 ie
->def
->insn_code
, ie
->def
->lineno
);
4088 fprintf (outf
, "case %d: /* %s */\n",
4089 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4093 /* Write out the computation for one attribute value. */
4096 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4097 int write_case_lines
, const char *prefix
, const char *suffix
,
4098 int indent
, rtx known_true
)
4100 if (av
->num_insns
== 0)
4103 if (av
->has_asm_insn
)
4105 write_indent (outf
, indent
);
4106 fprintf (outf
, "case -1:\n");
4107 write_indent (outf
, indent
+ 2);
4108 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4109 write_indent (outf
, indent
+ 2);
4110 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4111 write_indent (outf
, indent
+ 2);
4112 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4115 if (write_case_lines
)
4116 write_insn_cases (outf
, av
->first_insn
, indent
);
4119 write_indent (outf
, indent
);
4120 fprintf (outf
, "default:\n");
4123 /* See what we have to do to output this value. */
4124 must_extract
= must_constrain
= address_used
= 0;
4125 walk_attr_value (av
->value
);
4129 write_indent (outf
, indent
+ 2);
4130 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4132 else if (must_extract
)
4134 write_indent (outf
, indent
+ 2);
4135 fprintf (outf
, "extract_insn_cached (insn);\n");
4139 if (av
->num_insns
== 1)
4140 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4141 known_true
, av
->first_insn
->def
->insn_code
,
4142 av
->first_insn
->def
->insn_index
, 0);
4144 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4145 known_true
, -2, 0, 0);
4147 if (strncmp (prefix
, "return", 6))
4149 write_indent (outf
, indent
+ 2);
4150 fprintf (outf
, "break;\n");
4152 fprintf (outf
, "\n");
4155 /* Utilities to write in various forms. */
4158 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4160 if (attr
->is_numeric
)
4164 fprintf (outf
, "%d", num
);
4166 if (num
> 9 || num
< 0)
4167 fprintf (outf
, " /* %#x */", num
);
4171 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4172 fprintf (outf
, "_");
4173 write_upcase (outf
, s
);
4178 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4182 switch (GET_CODE (value
))
4185 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4189 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4193 fprint_c_condition (outf
, XSTR (value
, 0));
4198 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4199 if (attr
->enum_name
)
4200 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4201 else if (!attr
->is_numeric
)
4202 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4203 else if (!attr2
->is_numeric
)
4204 fprintf (outf
, "(int)");
4206 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4207 (attr2
->is_const
? "" : "insn"));
4228 write_attr_value (outf
, attr
, XEXP (value
, 0));
4232 write_attr_value (outf
, attr
, XEXP (value
, 1));
4241 write_upcase (FILE *outf
, const char *str
)
4245 /* The argument of TOUPPER should not have side effects. */
4246 fputc (TOUPPER(*str
), outf
);
4252 write_indent (FILE *outf
, int indent
)
4254 for (; indent
> 8; indent
-= 8)
4255 fprintf (outf
, "\t");
4257 for (; indent
; indent
--)
4258 fprintf (outf
, " ");
4261 /* Write a subroutine that is given an insn that requires a delay slot, a
4262 delay slot ordinal, and a candidate insn. It returns nonzero if the
4263 candidate can be placed in the specified delay slot of the insn.
4265 We can write as many as three subroutines. `eligible_for_delay'
4266 handles normal delay slots, `eligible_for_annul_true' indicates that
4267 the specified insn can be annulled if the branch is true, and likewise
4268 for `eligible_for_annul_false'.
4270 KIND is a string distinguishing these three cases ("delay", "annul_true",
4271 or "annul_false"). */
4274 write_eligible_delay (FILE *outf
, const char *kind
)
4276 struct delay_desc
*delay
;
4280 struct attr_desc
*attr
;
4281 struct attr_value
*av
, *common_av
;
4284 /* Compute the maximum number of delay slots required. We use the delay
4285 ordinal times this number plus one, plus the slot number as an index into
4286 the appropriate predicate to test. */
4288 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4289 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4290 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4292 /* Write function prelude. */
4294 fprintf (outf
, "int\n");
4295 fprintf (outf
, "eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4296 " rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4298 fprintf (outf
, "{\n");
4299 fprintf (outf
, " rtx insn;\n");
4300 fprintf (outf
, "\n");
4301 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4302 fprintf (outf
, "\n");
4303 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4304 converts a compound instruction into a loop. */
4305 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4306 fprintf (outf
, " return 0;\n");
4307 fprintf (outf
, "\n");
4309 /* If more than one delay type, find out which type the delay insn is. */
4313 attr
= find_attr (&delay_type_str
, 0);
4315 common_av
= find_most_used (attr
);
4317 fprintf (outf
, " insn = delay_insn;\n");
4318 fprintf (outf
, " switch (recog_memoized (insn))\n");
4319 fprintf (outf
, " {\n");
4321 sprintf (str
, " * %d;\n break;", max_slots
);
4322 for (av
= attr
->first_value
; av
; av
= av
->next
)
4323 if (av
!= common_av
)
4324 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4326 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4327 fprintf (outf
, " }\n\n");
4329 /* Ensure matched. Otherwise, shouldn't have been called. */
4330 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4333 /* If just one type of delay slot, write simple switch. */
4334 if (num_delays
== 1 && max_slots
== 1)
4336 fprintf (outf
, " insn = candidate_insn;\n");
4337 fprintf (outf
, " switch (recog_memoized (insn))\n");
4338 fprintf (outf
, " {\n");
4340 attr
= find_attr (&delay_1_0_str
, 0);
4342 common_av
= find_most_used (attr
);
4344 for (av
= attr
->first_value
; av
; av
= av
->next
)
4345 if (av
!= common_av
)
4346 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4348 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4349 fprintf (outf
, " }\n");
4354 /* Write a nested CASE. The first indicates which condition we need to
4355 test, and the inner CASE tests the condition. */
4356 fprintf (outf
, " insn = candidate_insn;\n");
4357 fprintf (outf
, " switch (slot)\n");
4358 fprintf (outf
, " {\n");
4360 for (delay
= delays
; delay
; delay
= delay
->next
)
4361 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4363 fprintf (outf
, " case %d:\n",
4364 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4365 fprintf (outf
, " switch (recog_memoized (insn))\n");
4366 fprintf (outf
, "\t{\n");
4368 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4370 attr
= find_attr (&pstr
, 0);
4372 common_av
= find_most_used (attr
);
4374 for (av
= attr
->first_value
; av
; av
= av
->next
)
4375 if (av
!= common_av
)
4376 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4378 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4379 fprintf (outf
, " }\n");
4382 fprintf (outf
, " default:\n");
4383 fprintf (outf
, " gcc_unreachable ();\n");
4384 fprintf (outf
, " }\n");
4387 fprintf (outf
, "}\n\n");
4390 /* This page contains miscellaneous utility routines. */
4392 /* Given a pointer to a (char *), return a malloc'ed string containing the
4393 next comma-separated element. Advance the pointer to after the string
4394 scanned, or the end-of-string. Return NULL if at end of string. */
4397 next_comma_elt (const char **pstr
)
4401 start
= scan_comma_elt (pstr
);
4406 return attr_string (start
, *pstr
- start
);
4409 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4410 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4411 replaced by a pointer to a canonical copy of the string. */
4413 static struct attr_desc
*
4414 find_attr (const char **name_p
, int create
)
4416 struct attr_desc
*attr
;
4418 const char *name
= *name_p
;
4420 /* Before we resort to using `strcmp', see if the string address matches
4421 anywhere. In most cases, it should have been canonicalized to do so. */
4422 if (name
== alternative_name
)
4425 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4426 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4427 if (name
== attr
->name
)
4430 /* Otherwise, do it the slow way. */
4431 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4432 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4434 *name_p
= attr
->name
;
4441 attr
= oballoc (struct attr_desc
);
4442 attr
->name
= DEF_ATTR_STRING (name
);
4443 attr
->enum_name
= 0;
4444 attr
->first_value
= attr
->default_val
= NULL
;
4445 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4446 attr
->next
= attrs
[index
];
4447 attrs
[index
] = attr
;
4449 *name_p
= attr
->name
;
4454 /* Create internal attribute with the given default value. */
4457 make_internal_attr (const char *name
, rtx value
, int special
)
4459 struct attr_desc
*attr
;
4461 attr
= find_attr (&name
, 1);
4462 gcc_assert (!attr
->default_val
);
4464 attr
->is_numeric
= 1;
4466 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4467 attr
->default_val
= get_attr_value (value
, attr
, -2);
4470 /* Find the most used value of an attribute. */
4472 static struct attr_value
*
4473 find_most_used (struct attr_desc
*attr
)
4475 struct attr_value
*av
;
4476 struct attr_value
*most_used
;
4482 for (av
= attr
->first_value
; av
; av
= av
->next
)
4483 if (av
->num_insns
> nuses
)
4484 nuses
= av
->num_insns
, most_used
= av
;
4489 /* Return (attr_value "n") */
4492 make_numeric_value (int n
)
4494 static rtx int_values
[20];
4498 gcc_assert (n
>= 0);
4500 if (n
< 20 && int_values
[n
])
4501 return int_values
[n
];
4503 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4504 exp
= attr_rtx (CONST_STRING
, p
);
4507 int_values
[n
] = exp
;
4513 copy_rtx_unchanging (rtx orig
)
4515 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4518 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4522 /* Determine if an insn has a constant number of delay slots, i.e., the
4523 number of delay slots is not a function of the length of the insn. */
4526 write_const_num_delay_slots (FILE *outf
)
4528 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4529 struct attr_value
*av
;
4533 fprintf (outf
, "int\nconst_num_delay_slots (rtx insn)\n");
4534 fprintf (outf
, "{\n");
4535 fprintf (outf
, " switch (recog_memoized (insn))\n");
4536 fprintf (outf
, " {\n");
4538 for (av
= attr
->first_value
; av
; av
= av
->next
)
4541 walk_attr_value (av
->value
);
4543 write_insn_cases (outf
, av
->first_insn
, 4);
4546 fprintf (outf
, " default:\n");
4547 fprintf (outf
, " return 1;\n");
4548 fprintf (outf
, " }\n}\n\n");
4552 /* Synthetic attributes used by insn-automata.c and the scheduler.
4553 These are primarily concerned with (define_insn_reservation)
4558 struct insn_reserv
*next
;
4561 int default_latency
;
4564 /* Sequence number of this insn. */
4567 /* Whether a (define_bypass) construct names this insn in its
4572 static struct insn_reserv
*all_insn_reservs
= 0;
4573 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4574 static size_t n_insn_reservs
;
4576 /* Store information from a DEFINE_INSN_RESERVATION for future
4577 attribute generation. */
4579 gen_insn_reserv (rtx def
)
4581 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4583 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4584 decl
->default_latency
= XINT (def
, 1);
4585 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4586 decl
->insn_num
= n_insn_reservs
;
4587 decl
->bypassed
= false;
4590 *last_insn_reserv_p
= decl
;
4591 last_insn_reserv_p
= &decl
->next
;
4595 /* Store information from a DEFINE_BYPASS for future attribute
4596 generation. The only thing we care about is the list of output
4597 insns, which will later be used to tag reservation structures with
4598 a 'bypassed' bit. */
4602 struct bypass_list
*next
;
4603 const char *pattern
;
4606 static struct bypass_list
*all_bypasses
;
4607 static size_t n_bypasses
;
4610 gen_bypass_1 (const char *s
, size_t len
)
4612 struct bypass_list
*b
;
4617 s
= attr_string (s
, len
);
4618 for (b
= all_bypasses
; b
; b
= b
->next
)
4619 if (s
== b
->pattern
)
4620 return; /* already got that one */
4622 b
= oballoc (struct bypass_list
);
4624 b
->next
= all_bypasses
;
4630 gen_bypass (rtx def
)
4632 const char *p
, *base
;
4634 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4637 gen_bypass_1 (base
, p
- base
);
4640 while (ISSPACE (*p
));
4643 gen_bypass_1 (base
, p
- base
);
4646 /* Find and mark all of the bypassed insns. */
4648 process_bypasses (void)
4650 struct bypass_list
*b
;
4651 struct insn_reserv
*r
;
4653 /* The reservation list is likely to be much longer than the bypass
4655 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4656 for (b
= all_bypasses
; b
; b
= b
->next
)
4657 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4661 /* Check that attribute NAME is used in define_insn_reservation condition
4662 EXP. Return true if it is. */
4664 check_tune_attr (const char *name
, rtx exp
)
4666 switch (GET_CODE (exp
))
4669 if (check_tune_attr (name
, XEXP (exp
, 0)))
4671 return check_tune_attr (name
, XEXP (exp
, 1));
4674 return (check_tune_attr (name
, XEXP (exp
, 0))
4675 && check_tune_attr (name
, XEXP (exp
, 1)));
4678 return XSTR (exp
, 0) == name
;
4685 /* Try to find a const attribute (usually cpu or tune) that is used
4686 in all define_insn_reservation conditions. */
4687 static struct attr_desc
*
4688 find_tune_attr (rtx exp
)
4690 struct attr_desc
*attr
;
4692 switch (GET_CODE (exp
))
4696 attr
= find_tune_attr (XEXP (exp
, 0));
4699 return find_tune_attr (XEXP (exp
, 1));
4702 if (XSTR (exp
, 0) == alternative_name
)
4705 attr
= find_attr (&XSTR (exp
, 0), 0);
4708 if (attr
->is_const
&& !attr
->is_special
)
4710 struct insn_reserv
*decl
;
4712 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4713 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4724 /* Create all of the attributes that describe automaton properties.
4725 Write the DFA and latency function prototypes to the files that
4726 need to have them, and write the init_sched_attrs(). */
4729 make_automaton_attrs (void)
4732 struct insn_reserv
*decl
;
4733 rtx code_exp
, lats_exp
, byps_exp
;
4734 struct attr_desc
*tune_attr
;
4736 if (n_insn_reservs
== 0)
4739 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4740 if (tune_attr
!= NULL
)
4742 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4743 struct attr_value
*val
;
4746 gcc_assert (tune_attr
->is_const
4747 && !tune_attr
->is_special
4748 && !tune_attr
->is_numeric
);
4750 /* Write the prototypes for all DFA functions. */
4751 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4753 if (val
== tune_attr
->default_val
)
4755 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4757 "extern int internal_dfa_insn_code_%s (rtx);\n",
4758 XSTR (val
->value
, 0));
4760 fprintf (dfa_file
, "\n");
4762 /* Write the prototypes for all latency functions. */
4763 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4765 if (val
== tune_attr
->default_val
)
4767 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4768 fprintf (latency_file
,
4769 "extern int insn_default_latency_%s (rtx);\n",
4770 XSTR (val
->value
, 0));
4772 fprintf (latency_file
, "\n");
4774 /* Write the prototypes for all automaton functions. */
4775 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4777 if (val
== tune_attr
->default_val
)
4779 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4781 "extern int internal_dfa_insn_code_%s (rtx);\n"
4782 "extern int insn_default_latency_%s (rtx);\n",
4783 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4785 fprintf (attr_file
, "\n");
4786 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx);\n");
4787 fprintf (attr_file
, "int (*insn_default_latency) (rtx);\n");
4788 fprintf (attr_file
, "\n");
4789 fprintf (attr_file
, "void\n");
4790 fprintf (attr_file
, "init_sched_attrs (void)\n");
4791 fprintf (attr_file
, "{\n");
4793 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4797 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
4799 if (val
== tune_attr
->default_val
)
4801 for (decl
= all_insn_reservs
, i
= 0;
4807 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
4808 if (condexp
== false_rtx
)
4810 if (condexp
== true_rtx
)
4812 condexps
[i
] = condexp
;
4813 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
4814 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
4818 code_exp
= rtx_alloc (COND
);
4819 lats_exp
= rtx_alloc (COND
);
4822 XVEC (code_exp
, 0) = rtvec_alloc (j
);
4823 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
4827 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
4828 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
4832 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4833 XEXP (lats_exp
, 1) = make_numeric_value (0);
4840 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
4841 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
4843 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
4844 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
4847 name
= XNEWVEC (char,
4848 sizeof ("*internal_dfa_insn_code_")
4849 + strlen (XSTR (val
->value
, 0)));
4850 strcpy (name
, "*internal_dfa_insn_code_");
4851 strcat (name
, XSTR (val
->value
, 0));
4852 make_internal_attr (name
, code_exp
, ATTR_NONE
);
4853 strcpy (name
, "*insn_default_latency_");
4854 strcat (name
, XSTR (val
->value
, 0));
4855 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
4860 fprintf (attr_file
, " if (");
4864 fprintf (attr_file
, " else if (");
4865 write_test_expr (attr_file
, test
, 0, 0);
4866 fprintf (attr_file
, ")\n");
4867 fprintf (attr_file
, " {\n");
4868 fprintf (attr_file
, " internal_dfa_insn_code\n");
4869 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
4870 XSTR (val
->value
, 0));
4871 fprintf (attr_file
, " insn_default_latency\n");
4872 fprintf (attr_file
, " = insn_default_latency_%s;\n",
4873 XSTR (val
->value
, 0));
4874 fprintf (attr_file
, " }\n");
4877 fprintf (attr_file
, " else\n");
4878 fprintf (attr_file
, " gcc_unreachable ();\n");
4879 fprintf (attr_file
, "}\n");
4880 fprintf (attr_file
, "\n");
4882 XDELETEVEC (condexps
);
4886 code_exp
= rtx_alloc (COND
);
4887 lats_exp
= rtx_alloc (COND
);
4889 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4890 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4892 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4893 XEXP (lats_exp
, 1) = make_numeric_value (0);
4895 for (decl
= all_insn_reservs
, i
= 0;
4897 decl
= decl
->next
, i
+= 2)
4899 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
4900 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
4902 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
4903 XVECEXP (lats_exp
, 0, i
+1)
4904 = make_numeric_value (decl
->default_latency
);
4906 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
4907 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
4910 if (n_bypasses
== 0)
4911 byps_exp
= make_numeric_value (0);
4914 process_bypasses ();
4916 byps_exp
= rtx_alloc (COND
);
4917 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypasses
* 2);
4918 XEXP (byps_exp
, 1) = make_numeric_value (0);
4919 for (decl
= all_insn_reservs
, i
= 0;
4924 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
4925 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
4930 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
4934 write_header (FILE *outf
)
4936 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
4937 " from the machine description file `md'. */\n\n");
4939 fprintf (outf
, "#include \"config.h\"\n");
4940 fprintf (outf
, "#include \"system.h\"\n");
4941 fprintf (outf
, "#include \"coretypes.h\"\n");
4942 fprintf (outf
, "#include \"tm.h\"\n");
4943 fprintf (outf
, "#include \"rtl.h\"\n");
4944 fprintf (outf
, "#include \"insn-attr.h\"\n");
4945 fprintf (outf
, "#include \"tm_p.h\"\n");
4946 fprintf (outf
, "#include \"insn-config.h\"\n");
4947 fprintf (outf
, "#include \"recog.h\"\n");
4948 fprintf (outf
, "#include \"regs.h\"\n");
4949 fprintf (outf
, "#include \"real.h\"\n");
4950 fprintf (outf
, "#include \"output.h\"\n");
4951 fprintf (outf
, "#include \"toplev.h\"\n");
4952 fprintf (outf
, "#include \"flags.h\"\n");
4953 fprintf (outf
, "#include \"function.h\"\n");
4954 fprintf (outf
, "\n");
4955 fprintf (outf
, "#define operands recog_data.operand\n\n");
4959 open_outfile (const char *file_name
)
4962 outf
= fopen (file_name
, "w");
4964 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
4965 write_header (outf
);
4970 handle_arg (const char *arg
)
4975 attr_file_name
= &arg
[2];
4978 dfa_file_name
= &arg
[2];
4981 latency_file_name
= &arg
[2];
4989 main (int argc
, char **argv
)
4992 struct attr_desc
*attr
;
4993 struct insn_def
*id
;
4997 progname
= "genattrtab";
4999 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5000 return FATAL_EXIT_CODE
;
5002 attr_file
= open_outfile (attr_file_name
);
5003 dfa_file
= open_outfile (dfa_file_name
);
5004 latency_file
= open_outfile (latency_file_name
);
5006 obstack_init (hash_obstack
);
5007 obstack_init (temp_obstack
);
5009 /* Set up true and false rtx's */
5010 true_rtx
= rtx_alloc (CONST_INT
);
5011 XWINT (true_rtx
, 0) = 1;
5012 false_rtx
= rtx_alloc (CONST_INT
);
5013 XWINT (false_rtx
, 0) = 0;
5014 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5015 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5017 alternative_name
= DEF_ATTR_STRING ("alternative");
5018 length_str
= DEF_ATTR_STRING ("length");
5019 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5020 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5021 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5023 /* Read the machine description. */
5029 desc
= read_md_rtx (&lineno
, &insn_code_number
);
5033 switch (GET_CODE (desc
))
5036 case DEFINE_PEEPHOLE
:
5037 case DEFINE_ASM_ATTRIBUTES
:
5038 gen_insn (desc
, lineno
);
5042 case DEFINE_ENUM_ATTR
:
5043 gen_attr (desc
, lineno
);
5047 gen_delay (desc
, lineno
);
5050 case DEFINE_INSN_RESERVATION
:
5051 gen_insn_reserv (desc
);
5061 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
5062 insn_index_number
++;
5066 return FATAL_EXIT_CODE
;
5070 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5071 if (! got_define_asm_attributes
)
5073 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5074 XVEC (tem
, 0) = rtvec_alloc (0);
5078 /* Expand DEFINE_DELAY information into new attribute. */
5082 /* Make `insn_alternatives'. */
5083 insn_alternatives
= oballocvec (int, insn_code_number
);
5084 for (id
= defs
; id
; id
= id
->next
)
5085 if (id
->insn_code
>= 0)
5086 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
5088 /* Make `insn_n_alternatives'. */
5089 insn_n_alternatives
= oballocvec (int, insn_code_number
);
5090 for (id
= defs
; id
; id
= id
->next
)
5091 if (id
->insn_code
>= 0)
5092 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5094 /* Construct extra attributes for automata. */
5095 make_automaton_attrs ();
5097 /* Prepare to write out attribute subroutines by checking everything stored
5098 away and building the attribute cases. */
5102 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5103 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5104 attr
->default_val
->value
5105 = check_attr_value (attr
->default_val
->value
, attr
);
5108 return FATAL_EXIT_CODE
;
5110 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5111 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5114 /* Construct extra attributes for `length'. */
5115 make_length_attrs ();
5117 /* Perform any possible optimizations to speed up compilation. */
5120 /* Now write out all the `gen_attr_...' routines. Do these before the
5121 special routines so that they get defined before they are used. */
5123 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5124 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5128 #define IS_ATTR_GROUP(X) (!strncmp(attr->name,X,strlen(X)))
5129 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5131 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5132 outf
= latency_file
;
5135 #undef IS_ATTR_GROUP
5137 if (! attr
->is_special
&& ! attr
->is_const
)
5138 write_attr_get (outf
, attr
);
5141 /* Write out delay eligibility information, if DEFINE_DELAY present.
5142 (The function to compute the number of delay slots will be written
5146 write_eligible_delay (attr_file
, "delay");
5147 if (have_annul_true
)
5148 write_eligible_delay (attr_file
, "annul_true");
5149 if (have_annul_false
)
5150 write_eligible_delay (attr_file
, "annul_false");
5153 /* Write out constant delay slot info. */
5154 write_const_num_delay_slots (attr_file
);
5156 write_length_unit_log (attr_file
);
5158 if (fclose (attr_file
) != 0)
5159 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5160 if (fclose (dfa_file
) != 0)
5161 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5162 if (fclose (latency_file
) != 0)
5163 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5165 return SUCCESS_EXIT_CODE
;