1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
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"
113 #include "gensupport.h"
115 #ifdef HAVE_SYS_RESOURCE_H
116 # include <sys/resource.h>
119 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
120 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
124 #include "genattrtab.h"
126 static struct obstack obstack1
, obstack2
;
127 struct obstack
*hash_obstack
= &obstack1
;
128 struct obstack
*temp_obstack
= &obstack2
;
130 /* enough space to reserve for printing out ints */
131 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
133 /* Define structures used to record attributes and values. */
135 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
136 encountered, we store all the relevant information into a
137 `struct insn_def'. This is done to allow attribute definitions to occur
138 anywhere in the file. */
142 struct insn_def
*next
; /* Next insn in chain. */
143 rtx def
; /* The DEFINE_... */
144 int insn_code
; /* Instruction number. */
145 int insn_index
; /* Expression numer in file, for errors. */
146 int lineno
; /* Line number. */
147 int num_alternatives
; /* Number of alternatives. */
148 int vec_idx
; /* Index of attribute vector in `def'. */
151 /* Once everything has been read in, we store in each attribute value a list
152 of insn codes that have that value. Here is the structure used for the
157 struct insn_ent
*next
; /* Next in chain. */
158 struct insn_def
*def
; /* Instruction definition. */
161 /* Each value of an attribute (either constant or computed) is assigned a
162 structure which is used as the listhead of the insns that have that
167 rtx value
; /* Value of attribute. */
168 struct attr_value
*next
; /* Next attribute value in chain. */
169 struct insn_ent
*first_insn
; /* First insn with this value. */
170 int num_insns
; /* Number of insns with this value. */
171 int has_asm_insn
; /* True if this value used for `asm' insns */
174 /* Structure for each attribute. */
178 char *name
; /* Name of attribute. */
179 struct attr_desc
*next
; /* Next attribute. */
180 struct attr_value
*first_value
; /* First value of this attribute. */
181 struct attr_value
*default_val
; /* Default value for this attribute. */
182 int lineno
: 24; /* Line number. */
183 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
184 unsigned is_const
: 1; /* Attribute value constant for each run. */
185 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
186 unsigned static_p
: 1; /* Make the output function static. */
189 /* Structure for each DEFINE_DELAY. */
193 rtx def
; /* DEFINE_DELAY expression. */
194 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
195 int num
; /* Number of DEFINE_DELAY, starting at 1. */
196 int lineno
; /* Line number. */
199 /* Listheads of above structures. */
201 /* This one is indexed by the first character of the attribute name. */
202 #define MAX_ATTRS_INDEX 256
203 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
204 static struct insn_def
*defs
;
205 static struct delay_desc
*delays
;
207 /* Other variables. */
209 static int insn_code_number
;
210 static int insn_index_number
;
211 static int got_define_asm_attributes
;
212 static int must_extract
;
213 static int must_constrain
;
214 static int address_used
;
215 static int length_used
;
216 static int num_delays
;
217 static int have_annul_true
, have_annul_false
;
218 static int num_insn_ents
;
222 /* Stores, for each insn code, the number of constraint alternatives. */
224 static int *insn_n_alternatives
;
226 /* Stores, for each insn code, a bitmap that has bits on for each possible
229 static int *insn_alternatives
;
231 /* Used to simplify expressions. */
233 static rtx true_rtx
, false_rtx
;
235 /* Used to reduce calls to `strcmp' */
237 static const char *alternative_name
;
238 static const char *length_str
;
239 static const char *delay_type_str
;
240 static const char *delay_1_0_str
;
241 static const char *num_delay_slots_str
;
243 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
246 int reload_completed
= 0;
248 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
249 to define it here. */
253 /* Simplify an expression. Only call the routine if there is something to
255 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
256 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
257 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
259 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
261 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
262 They won't actually be used. */
264 rtx global_rtl
[GR_MAX
];
265 rtx pic_offset_table_rtx
;
267 static void attr_hash_add_rtx (int, rtx
);
268 static void attr_hash_add_string (int, char *);
269 static rtx
attr_rtx (enum rtx_code
, ...);
270 static rtx
attr_rtx_1 (enum rtx_code
, va_list);
271 static char *attr_string (const char *, int);
272 static rtx
check_attr_value (rtx
, struct attr_desc
*);
273 static rtx
convert_set_attr_alternative (rtx
, struct insn_def
*);
274 static rtx
convert_set_attr (rtx
, struct insn_def
*);
275 static void check_defs (void);
276 static rtx
make_canonical (struct attr_desc
*, rtx
);
277 static struct attr_value
*get_attr_value (rtx
, struct attr_desc
*, int);
278 static rtx
copy_rtx_unchanging (rtx
);
279 static rtx
copy_boolean (rtx
);
280 static void expand_delays (void);
281 static void fill_attr (struct attr_desc
*);
282 static rtx
substitute_address (rtx
, rtx (*) (rtx
), rtx (*) (rtx
));
283 static void make_length_attrs (void);
284 static rtx
identity_fn (rtx
);
285 static rtx
zero_fn (rtx
);
286 static rtx
one_fn (rtx
);
287 static rtx
max_fn (rtx
);
288 static void write_length_unit_log (void);
289 static rtx
simplify_cond (rtx
, int, int);
290 static void clear_struct_flag (rtx
);
291 static void remove_insn_ent (struct attr_value
*, struct insn_ent
*);
292 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
293 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
294 static rtx
make_alternative_compare (int);
295 static int compute_alternative_mask (rtx
, enum rtx_code
);
296 static rtx
evaluate_eq_attr (rtx
, rtx
, int, int);
297 static rtx
simplify_and_tree (rtx
, rtx
*, int, int);
298 static rtx
simplify_or_tree (rtx
, rtx
*, int, int);
299 static rtx
simplify_test_exp (rtx
, int, int);
300 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
301 static void optimize_attrs (void);
302 static void gen_attr (rtx
, int);
303 static int count_alternatives (rtx
);
304 static int compares_alternatives_p (rtx
);
305 static int contained_in_p (rtx
, rtx
);
306 static void gen_insn (rtx
, int);
307 static void gen_delay (rtx
, int);
308 static void write_test_expr (rtx
, int);
309 static int max_attr_value (rtx
, int*);
310 static int or_attr_value (rtx
, int*);
311 static void walk_attr_value (rtx
);
312 static void write_attr_get (struct attr_desc
*);
313 static rtx
eliminate_known_true (rtx
, rtx
, int, int);
314 static void write_attr_set (struct attr_desc
*, int, rtx
,
315 const char *, const char *, rtx
,
317 static void write_insn_cases (struct insn_ent
*, int);
318 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
319 int, const char *, const char *, int, rtx
);
320 static void write_attr_valueq (struct attr_desc
*, const char *);
321 static void write_attr_value (struct attr_desc
*, rtx
);
322 static void write_upcase (const char *);
323 static void write_indent (int);
324 static void write_eligible_delay (const char *);
325 static int write_expr_attr_cache (rtx
, struct attr_desc
*);
326 static void write_const_num_delay_slots (void);
327 static char *next_comma_elt (const char **);
328 static struct attr_desc
*find_attr (const char **, int);
329 static struct attr_value
*find_most_used (struct attr_desc
*);
330 static rtx
attr_eq (const char *, const char *);
331 static const char *attr_numeral (int);
332 static int attr_equal_p (rtx
, rtx
);
333 static rtx
attr_copy_rtx (rtx
);
334 static int attr_rtx_cost (rtx
);
335 static bool attr_alt_subset_p (rtx
, rtx
);
336 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
337 static rtx
attr_alt_intersection (rtx
, rtx
);
338 static rtx
attr_alt_union (rtx
, rtx
);
339 static rtx
attr_alt_complement (rtx
);
340 static rtx
mk_attr_alt (int);
342 #define oballoc(size) obstack_alloc (hash_obstack, size)
344 /* Hash table for sharing RTL and strings. */
346 /* Each hash table slot is a bucket containing a chain of these structures.
347 Strings are given negative hash codes; RTL expressions are given positive
352 struct attr_hash
*next
; /* Next structure in the bucket. */
353 int hashcode
; /* Hash code of this rtx or string. */
356 char *str
; /* The string (negative hash codes) */
357 rtx rtl
; /* or the RTL recorded here. */
361 /* Now here is the hash table. When recording an RTL, it is added to
362 the slot whose index is the hash code mod the table size. Note
363 that the hash table is used for several kinds of RTL (see attr_rtx)
364 and for strings. While all these live in the same table, they are
365 completely independent, and the hash code is computed differently
368 #define RTL_HASH_SIZE 4093
369 struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
371 /* Here is how primitive or already-shared RTL's hash
373 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
375 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
378 attr_hash_add_rtx (int hashcode
, rtx rtl
)
382 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
383 h
->hashcode
= hashcode
;
385 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
386 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
389 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
392 attr_hash_add_string (int hashcode
, char *str
)
396 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
397 h
->hashcode
= -hashcode
;
399 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
400 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
403 /* Generate an RTL expression, but avoid duplicates.
404 Set the ATTR_PERMANENT_P flag for these permanent objects.
406 In some cases we cannot uniquify; then we return an ordinary
407 impermanent rtx with ATTR_PERMANENT_P clear.
411 rtx attr_rtx (code, [element1, ..., elementn]) */
414 attr_rtx_1 (enum rtx_code code
, va_list p
)
416 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
419 struct obstack
*old_obstack
= rtl_obstack
;
421 /* For each of several cases, search the hash table for an existing entry.
422 Use that entry if one is found; otherwise create a new RTL and add it
425 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
427 rtx arg0
= va_arg (p
, rtx
);
429 /* A permanent object cannot point to impermanent ones. */
430 if (! ATTR_PERMANENT_P (arg0
))
432 rt_val
= rtx_alloc (code
);
433 XEXP (rt_val
, 0) = arg0
;
437 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
438 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
439 if (h
->hashcode
== hashcode
440 && GET_CODE (h
->u
.rtl
) == code
441 && XEXP (h
->u
.rtl
, 0) == arg0
)
446 rtl_obstack
= hash_obstack
;
447 rt_val
= rtx_alloc (code
);
448 XEXP (rt_val
, 0) = arg0
;
451 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
452 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
453 || GET_RTX_CLASS (code
) == RTX_COMPARE
454 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
456 rtx arg0
= va_arg (p
, rtx
);
457 rtx arg1
= va_arg (p
, rtx
);
459 /* A permanent object cannot point to impermanent ones. */
460 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
462 rt_val
= rtx_alloc (code
);
463 XEXP (rt_val
, 0) = arg0
;
464 XEXP (rt_val
, 1) = arg1
;
468 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
469 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
470 if (h
->hashcode
== hashcode
471 && GET_CODE (h
->u
.rtl
) == code
472 && XEXP (h
->u
.rtl
, 0) == arg0
473 && XEXP (h
->u
.rtl
, 1) == arg1
)
478 rtl_obstack
= hash_obstack
;
479 rt_val
= rtx_alloc (code
);
480 XEXP (rt_val
, 0) = arg0
;
481 XEXP (rt_val
, 1) = arg1
;
484 else if (GET_RTX_LENGTH (code
) == 1
485 && GET_RTX_FORMAT (code
)[0] == 's')
487 char *arg0
= va_arg (p
, char *);
489 arg0
= DEF_ATTR_STRING (arg0
);
491 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
492 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
493 if (h
->hashcode
== hashcode
494 && GET_CODE (h
->u
.rtl
) == code
495 && XSTR (h
->u
.rtl
, 0) == arg0
)
500 rtl_obstack
= hash_obstack
;
501 rt_val
= rtx_alloc (code
);
502 XSTR (rt_val
, 0) = arg0
;
505 else if (GET_RTX_LENGTH (code
) == 2
506 && GET_RTX_FORMAT (code
)[0] == 's'
507 && GET_RTX_FORMAT (code
)[1] == 's')
509 char *arg0
= va_arg (p
, char *);
510 char *arg1
= va_arg (p
, char *);
512 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
513 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
514 if (h
->hashcode
== hashcode
515 && GET_CODE (h
->u
.rtl
) == code
516 && XSTR (h
->u
.rtl
, 0) == arg0
517 && XSTR (h
->u
.rtl
, 1) == arg1
)
522 rtl_obstack
= hash_obstack
;
523 rt_val
= rtx_alloc (code
);
524 XSTR (rt_val
, 0) = arg0
;
525 XSTR (rt_val
, 1) = arg1
;
528 else if (code
== CONST_INT
)
530 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
540 int i
; /* Array indices... */
541 const char *fmt
; /* Current rtx's format... */
543 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
545 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
546 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
550 case '0': /* Unused field. */
553 case 'i': /* An integer? */
554 XINT (rt_val
, i
) = va_arg (p
, int);
557 case 'w': /* A wide integer? */
558 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
561 case 's': /* A string? */
562 XSTR (rt_val
, i
) = va_arg (p
, char *);
565 case 'e': /* An expression? */
566 case 'u': /* An insn? Same except when printing. */
567 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
570 case 'E': /* An RTX vector? */
571 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
581 rtl_obstack
= old_obstack
;
582 attr_hash_add_rtx (hashcode
, rt_val
);
583 ATTR_PERMANENT_P (rt_val
) = 1;
588 attr_rtx (enum rtx_code code
, ...)
594 result
= attr_rtx_1 (code
, p
);
599 /* Create a new string printed with the printf line arguments into a space
600 of at most LEN bytes:
602 rtx attr_printf (len, format, [arg1, ..., argn]) */
605 attr_printf (unsigned int len
, const char *fmt
, ...)
612 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
614 vsprintf (str
, fmt
, p
);
617 return DEF_ATTR_STRING (str
);
621 attr_eq (const char *name
, const char *value
)
623 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
629 return XSTR (make_numeric_value (n
), 0);
632 /* Return a permanent (possibly shared) copy of a string STR (not assumed
633 to be null terminated) with LEN bytes. */
636 attr_string (const char *str
, int len
)
643 /* Compute the hash code. */
644 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
645 for (i
= 1; i
<= len
; i
+= 2)
646 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
648 hashcode
= -hashcode
;
650 /* Search the table for the string. */
651 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
652 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
653 && !strncmp (h
->u
.str
, str
, len
))
654 return h
->u
.str
; /* <-- return if found. */
656 /* Not found; create a permanent copy and add it to the hash table. */
657 new_str
= obstack_alloc (hash_obstack
, len
+ 1);
658 memcpy (new_str
, str
, len
);
660 attr_hash_add_string (hashcode
, new_str
);
662 return new_str
; /* Return the new string. */
665 /* Check two rtx's for equality of contents,
666 taking advantage of the fact that if both are hashed
667 then they can't be equal unless they are the same object. */
670 attr_equal_p (rtx x
, rtx y
)
672 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
673 && rtx_equal_p (x
, y
)));
676 /* Copy an attribute value expression,
677 descending to all depths, but not copying any
678 permanent hashed subexpressions. */
681 attr_copy_rtx (rtx orig
)
686 const char *format_ptr
;
688 /* No need to copy a permanent object. */
689 if (ATTR_PERMANENT_P (orig
))
692 code
= GET_CODE (orig
);
710 copy
= rtx_alloc (code
);
711 PUT_MODE (copy
, GET_MODE (orig
));
712 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
713 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
714 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
716 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
718 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
720 switch (*format_ptr
++)
723 XEXP (copy
, i
) = XEXP (orig
, i
);
724 if (XEXP (orig
, i
) != NULL
)
725 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
730 XVEC (copy
, i
) = XVEC (orig
, i
);
731 if (XVEC (orig
, i
) != NULL
)
733 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
734 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
735 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
741 XINT (copy
, i
) = XINT (orig
, i
);
745 XWINT (copy
, i
) = XWINT (orig
, i
);
750 XSTR (copy
, i
) = XSTR (orig
, i
);
760 /* Given a test expression for an attribute, ensure it is validly formed.
761 IS_CONST indicates whether the expression is constant for each compiler
762 run (a constant expression may not test any particular insn).
764 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
765 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
766 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
768 Update the string address in EQ_ATTR expression to be the same used
769 in the attribute (or `alternative_name') to speed up subsequent
770 `find_attr' calls and eliminate most `strcmp' calls.
772 Return the new expression, if any. */
775 check_attr_test (rtx exp
, int is_const
, int lineno
)
777 struct attr_desc
*attr
;
778 struct attr_value
*av
;
779 const char *name_ptr
, *p
;
782 switch (GET_CODE (exp
))
785 /* Handle negation test. */
786 if (XSTR (exp
, 1)[0] == '!')
787 return check_attr_test (attr_rtx (NOT
,
788 attr_eq (XSTR (exp
, 0),
792 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
794 attr
= find_attr (&XSTR (exp
, 0), 0);
797 if (! strcmp (XSTR (exp
, 0), "alternative"))
798 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
800 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
803 if (is_const
&& ! attr
->is_const
)
804 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
807 /* Copy this just to make it permanent,
808 so expressions using it can be permanent too. */
809 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
811 /* It shouldn't be possible to simplify the value given to a
812 constant attribute, so don't expand this until it's time to
813 write the test expression. */
815 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
817 if (attr
->is_numeric
)
819 for (p
= XSTR (exp
, 1); *p
; p
++)
821 fatal ("attribute `%s' takes only numeric values",
826 for (av
= attr
->first_value
; av
; av
= av
->next
)
827 if (GET_CODE (av
->value
) == CONST_STRING
828 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
832 fatal ("unknown value `%s' for `%s' attribute",
833 XSTR (exp
, 1), XSTR (exp
, 0));
838 if (! strcmp (XSTR (exp
, 0), "alternative"))
842 name_ptr
= XSTR (exp
, 1);
843 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
844 set
|= 1 << atoi (p
);
846 return mk_attr_alt (set
);
850 /* Make an IOR tree of the possible values. */
852 name_ptr
= XSTR (exp
, 1);
853 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
855 newexp
= attr_eq (XSTR (exp
, 0), p
);
856 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
859 return check_attr_test (orexp
, is_const
, lineno
);
868 /* Either TRUE or FALSE. */
876 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
877 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
881 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
886 fatal ("RTL operator \"%s\" not valid in constant attribute test",
887 GET_RTX_NAME (GET_CODE (exp
)));
888 /* These cases can't be simplified. */
889 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
892 case LE
: case LT
: case GT
: case GE
:
893 case LEU
: case LTU
: case GTU
: case GEU
:
895 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
896 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
897 exp
= attr_rtx (GET_CODE (exp
),
898 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
899 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
900 /* These cases can't be simplified. */
901 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
907 /* These cases are valid for constant attributes, but can't be
909 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
910 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
914 fatal ("RTL operator \"%s\" not valid in attribute test",
915 GET_RTX_NAME (GET_CODE (exp
)));
921 /* Given an expression, ensure that it is validly formed and that all named
922 attribute values are valid for the given attribute. Issue a fatal error
923 if not. If no attribute is specified, assume a numeric attribute.
925 Return a perhaps modified replacement expression for the value. */
928 check_attr_value (rtx exp
, struct attr_desc
*attr
)
930 struct attr_value
*av
;
934 switch (GET_CODE (exp
))
937 if (attr
&& ! attr
->is_numeric
)
939 message_with_line (attr
->lineno
,
940 "CONST_INT not valid for non-numeric attribute %s",
946 if (INTVAL (exp
) < 0)
948 message_with_line (attr
->lineno
,
949 "negative numeric value specified for attribute %s",
957 if (! strcmp (XSTR (exp
, 0), "*"))
960 if (attr
== 0 || attr
->is_numeric
)
966 message_with_line (attr
? attr
->lineno
: 0,
967 "non-numeric value for numeric attribute %s",
968 attr
? attr
->name
: "internal");
975 for (av
= attr
->first_value
; av
; av
= av
->next
)
976 if (GET_CODE (av
->value
) == CONST_STRING
977 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
982 message_with_line (attr
->lineno
,
983 "unknown value `%s' for `%s' attribute",
984 XSTR (exp
, 0), attr
? attr
->name
: "internal");
990 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
991 attr
? attr
->is_const
: 0,
992 attr
? attr
->lineno
: 0);
993 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
994 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
1002 if (attr
&& !attr
->is_numeric
)
1004 message_with_line (attr
->lineno
,
1005 "invalid operation `%s' for non-numeric attribute value",
1006 GET_RTX_NAME (GET_CODE (exp
)));
1014 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1015 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1023 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1027 if (XVECLEN (exp
, 0) % 2 != 0)
1029 message_with_line (attr
->lineno
,
1030 "first operand of COND must have even length");
1035 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1037 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1038 attr
? attr
->is_const
: 0,
1039 attr
? attr
->lineno
: 0);
1040 XVECEXP (exp
, 0, i
+ 1)
1041 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1044 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1049 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1052 message_with_line (attr
? attr
->lineno
: 0,
1053 "unknown attribute `%s' in ATTR",
1057 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1059 message_with_line (attr
->lineno
,
1060 "non-constant attribute `%s' referenced from `%s'",
1061 XSTR (exp
, 0), attr
->name
);
1065 && attr
->is_numeric
!= attr2
->is_numeric
)
1067 message_with_line (attr
->lineno
,
1068 "numeric attribute mismatch calling `%s' from `%s'",
1069 XSTR (exp
, 0), attr
->name
);
1076 /* A constant SYMBOL_REF is valid as a constant attribute test and
1077 is expanded later by make_canonical into a COND. In a non-constant
1078 attribute test, it is left be. */
1079 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1082 message_with_line (attr
? attr
->lineno
: 0,
1083 "invalid operation `%s' for attribute value",
1084 GET_RTX_NAME (GET_CODE (exp
)));
1092 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1093 It becomes a COND with each test being (eq_attr "alternative" "n") */
1096 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1098 int num_alt
= id
->num_alternatives
;
1102 if (XVECLEN (exp
, 1) != num_alt
)
1104 message_with_line (id
->lineno
,
1105 "bad number of entries in SET_ATTR_ALTERNATIVE");
1110 /* Make a COND with all tests but the last. Select the last value via the
1112 condexp
= rtx_alloc (COND
);
1113 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1115 for (i
= 0; i
< num_alt
- 1; i
++)
1118 p
= attr_numeral (i
);
1120 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1121 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1124 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1126 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1129 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1130 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1133 convert_set_attr (rtx exp
, struct insn_def
*id
)
1136 const char *name_ptr
;
1140 /* See how many alternative specified. */
1141 n
= n_comma_elts (XSTR (exp
, 1));
1143 return attr_rtx (SET
,
1144 attr_rtx (ATTR
, XSTR (exp
, 0)),
1145 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1147 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1148 XSTR (newexp
, 0) = XSTR (exp
, 0);
1149 XVEC (newexp
, 1) = rtvec_alloc (n
);
1151 /* Process each comma-separated name. */
1152 name_ptr
= XSTR (exp
, 1);
1154 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1155 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1157 return convert_set_attr_alternative (newexp
, id
);
1160 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1161 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1167 struct insn_def
*id
;
1168 struct attr_desc
*attr
;
1172 for (id
= defs
; id
; id
= id
->next
)
1174 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1177 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1179 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1180 switch (GET_CODE (value
))
1183 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1185 message_with_line (id
->lineno
, "bad attribute set");
1191 case SET_ATTR_ALTERNATIVE
:
1192 value
= convert_set_attr_alternative (value
, id
);
1196 value
= convert_set_attr (value
, id
);
1200 message_with_line (id
->lineno
, "invalid attribute code %s",
1201 GET_RTX_NAME (GET_CODE (value
)));
1205 if (value
== NULL_RTX
)
1208 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1210 message_with_line (id
->lineno
, "unknown attribute %s",
1211 XSTR (XEXP (value
, 0), 0));
1216 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1217 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1222 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1223 expressions by converting them into a COND. This removes cases from this
1224 program. Also, replace an attribute value of "*" with the default attribute
1228 make_canonical (struct attr_desc
*attr
, rtx exp
)
1233 switch (GET_CODE (exp
))
1236 exp
= make_numeric_value (INTVAL (exp
));
1240 if (! strcmp (XSTR (exp
, 0), "*"))
1242 if (attr
== 0 || attr
->default_val
== 0)
1243 fatal ("(attr_value \"*\") used in invalid context");
1244 exp
= attr
->default_val
->value
;
1247 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1252 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1254 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1255 This makes the COND something that won't be considered an arbitrary
1256 expression by walk_attr_value. */
1257 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1258 exp
= check_attr_value (exp
, attr
);
1262 newexp
= rtx_alloc (COND
);
1263 XVEC (newexp
, 0) = rtvec_alloc (2);
1264 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1265 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1267 XEXP (newexp
, 1) = XEXP (exp
, 2);
1270 /* Fall through to COND case since this is now a COND. */
1277 /* First, check for degenerate COND. */
1278 if (XVECLEN (exp
, 0) == 0)
1279 return make_canonical (attr
, XEXP (exp
, 1));
1280 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1282 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1284 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1285 XVECEXP (exp
, 0, i
+ 1)
1286 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1287 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1303 copy_boolean (rtx exp
)
1305 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1306 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1307 copy_boolean (XEXP (exp
, 1)));
1308 if (GET_CODE (exp
) == MATCH_OPERAND
)
1310 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1311 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1313 else if (GET_CODE (exp
) == EQ_ATTR
)
1315 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1316 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1322 /* Given a value and an attribute description, return a `struct attr_value *'
1323 that represents that value. This is either an existing structure, if the
1324 value has been previously encountered, or a newly-created structure.
1326 `insn_code' is the code of an insn whose attribute has the specified
1327 value (-2 if not processing an insn). We ensure that all insns for
1328 a given value have the same number of alternatives if the value checks
1331 static struct attr_value
*
1332 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1334 struct attr_value
*av
;
1337 value
= make_canonical (attr
, value
);
1338 if (compares_alternatives_p (value
))
1340 if (insn_code
< 0 || insn_alternatives
== NULL
)
1341 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1343 num_alt
= insn_alternatives
[insn_code
];
1346 for (av
= attr
->first_value
; av
; av
= av
->next
)
1347 if (rtx_equal_p (value
, av
->value
)
1348 && (num_alt
== 0 || av
->first_insn
== NULL
1349 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1352 av
= oballoc (sizeof (struct attr_value
));
1354 av
->next
= attr
->first_value
;
1355 attr
->first_value
= av
;
1356 av
->first_insn
= NULL
;
1358 av
->has_asm_insn
= 0;
1363 /* After all DEFINE_DELAYs have been read in, create internal attributes
1364 to generate the required routines.
1366 First, we compute the number of delay slots for each insn (as a COND of
1367 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1368 delay type is specified, we compute a similar function giving the
1369 DEFINE_DELAY ordinal for each insn.
1371 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1372 tells whether a given insn can be in that delay slot.
1374 Normal attribute filling and optimization expands these to contain the
1375 information needed to handle delay slots. */
1378 expand_delays (void)
1380 struct delay_desc
*delay
;
1386 /* First, generate data for `num_delay_slots' function. */
1388 condexp
= rtx_alloc (COND
);
1389 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1390 XEXP (condexp
, 1) = make_numeric_value (0);
1392 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1394 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1395 XVECEXP (condexp
, 0, i
+ 1)
1396 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1399 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1401 /* If more than one delay type, do the same for computing the delay type. */
1404 condexp
= rtx_alloc (COND
);
1405 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1406 XEXP (condexp
, 1) = make_numeric_value (0);
1408 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1410 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1411 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1414 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1417 /* For each delay possibility and delay slot, compute an eligibility
1418 attribute for non-annulled insns and for each type of annulled (annul
1419 if true and annul if false). */
1420 for (delay
= delays
; delay
; delay
= delay
->next
)
1422 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1424 condexp
= XVECEXP (delay
->def
, 1, i
);
1426 condexp
= false_rtx
;
1427 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1428 make_numeric_value (1), make_numeric_value (0));
1430 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1431 "*delay_%d_%d", delay
->num
, i
/ 3);
1432 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1434 if (have_annul_true
)
1436 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1437 if (condexp
== 0) condexp
= false_rtx
;
1438 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1439 make_numeric_value (1),
1440 make_numeric_value (0));
1441 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1442 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1443 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1446 if (have_annul_false
)
1448 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1449 if (condexp
== 0) condexp
= false_rtx
;
1450 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1451 make_numeric_value (1),
1452 make_numeric_value (0));
1453 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1454 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1455 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1461 /* Once all attributes and insns have been read and checked, we construct for
1462 each attribute value a list of all the insns that have that value for
1466 fill_attr (struct attr_desc
*attr
)
1468 struct attr_value
*av
;
1469 struct insn_ent
*ie
;
1470 struct insn_def
*id
;
1474 /* Don't fill constant attributes. The value is independent of
1475 any particular insn. */
1479 for (id
= defs
; id
; id
= id
->next
)
1481 /* If no value is specified for this insn for this attribute, use the
1484 if (XVEC (id
->def
, id
->vec_idx
))
1485 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1486 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1488 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1491 av
= attr
->default_val
;
1493 av
= get_attr_value (value
, attr
, id
->insn_code
);
1495 ie
= oballoc (sizeof (struct insn_ent
));
1497 insert_insn_ent (av
, ie
);
1501 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1502 test that checks relative positions of insns (uses MATCH_DUP or PC).
1503 If so, replace it with what is obtained by passing the expression to
1504 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1505 recursively on each value (including the default value). Otherwise,
1506 return the value returned by NO_ADDRESS_FN applied to EXP. */
1509 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1510 rtx (*address_fn
) (rtx
))
1515 if (GET_CODE (exp
) == COND
)
1517 /* See if any tests use addresses. */
1519 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1520 walk_attr_value (XVECEXP (exp
, 0, i
));
1523 return (*address_fn
) (exp
);
1525 /* Make a new copy of this COND, replacing each element. */
1526 newexp
= rtx_alloc (COND
);
1527 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1528 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1530 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1531 XVECEXP (newexp
, 0, i
+ 1)
1532 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1533 no_address_fn
, address_fn
);
1536 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1537 no_address_fn
, address_fn
);
1542 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1545 walk_attr_value (XEXP (exp
, 0));
1547 return (*address_fn
) (exp
);
1549 return attr_rtx (IF_THEN_ELSE
,
1550 substitute_address (XEXP (exp
, 0),
1551 no_address_fn
, address_fn
),
1552 substitute_address (XEXP (exp
, 1),
1553 no_address_fn
, address_fn
),
1554 substitute_address (XEXP (exp
, 2),
1555 no_address_fn
, address_fn
));
1558 return (*no_address_fn
) (exp
);
1561 /* Make new attributes from the `length' attribute. The following are made,
1562 each corresponding to a function called from `shorten_branches' or
1565 *insn_default_length This is the length of the insn to be returned
1566 by `get_attr_length' before `shorten_branches'
1567 has been called. In each case where the length
1568 depends on relative addresses, the largest
1569 possible is used. This routine is also used
1570 to compute the initial size of the insn.
1572 *insn_variable_length_p This returns 1 if the insn's length depends
1573 on relative addresses, zero otherwise.
1575 *insn_current_length This is only called when it is known that the
1576 insn has a variable length and returns the
1577 current length, based on relative addresses.
1581 make_length_attrs (void)
1583 static const char *new_names
[] =
1585 "*insn_default_length",
1586 "*insn_variable_length_p",
1587 "*insn_current_length"
1589 static rtx (*const no_address_fn
[]) (rtx
) = {identity_fn
, zero_fn
, zero_fn
};
1590 static rtx (*const address_fn
[]) (rtx
) = {max_fn
, one_fn
, identity_fn
};
1592 struct attr_desc
*length_attr
, *new_attr
;
1593 struct attr_value
*av
, *new_av
;
1594 struct insn_ent
*ie
, *new_ie
;
1596 /* See if length attribute is defined. If so, it must be numeric. Make
1597 it special so we don't output anything for it. */
1598 length_attr
= find_attr (&length_str
, 0);
1599 if (length_attr
== 0)
1602 if (! length_attr
->is_numeric
)
1603 fatal ("length attribute must be numeric");
1605 length_attr
->is_const
= 0;
1606 length_attr
->is_special
= 1;
1608 /* Make each new attribute, in turn. */
1609 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1611 make_internal_attr (new_names
[i
],
1612 substitute_address (length_attr
->default_val
->value
,
1613 no_address_fn
[i
], address_fn
[i
]),
1615 new_attr
= find_attr (&new_names
[i
], 0);
1616 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1617 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1619 new_av
= get_attr_value (substitute_address (av
->value
,
1622 new_attr
, ie
->def
->insn_code
);
1623 new_ie
= oballoc (sizeof (struct insn_ent
));
1624 new_ie
->def
= ie
->def
;
1625 insert_insn_ent (new_av
, new_ie
);
1630 /* Utility functions called from above routine. */
1633 identity_fn (rtx exp
)
1639 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1641 return make_numeric_value (0);
1645 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1647 return make_numeric_value (1);
1654 return make_numeric_value (max_attr_value (exp
, &unknown
));
1658 write_length_unit_log (void)
1660 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1661 struct attr_value
*av
;
1662 struct insn_ent
*ie
;
1663 unsigned int length_unit_log
, length_or
;
1666 if (length_attr
== 0)
1668 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1669 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1670 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1671 length_or
|= or_attr_value (av
->value
, &unknown
);
1674 length_unit_log
= 0;
1677 length_or
= ~length_or
;
1678 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1681 printf ("int length_unit_log = %u;\n", length_unit_log
);
1684 /* Take a COND expression and see if any of the conditions in it can be
1685 simplified. If any are known true or known false for the particular insn
1686 code, the COND can be further simplified.
1688 Also call ourselves on any COND operations that are values of this COND.
1690 We do not modify EXP; rather, we make and return a new rtx. */
1693 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1696 /* We store the desired contents here,
1697 then build a new expression if they don't match EXP. */
1698 rtx defval
= XEXP (exp
, 1);
1699 rtx new_defval
= XEXP (exp
, 1);
1700 int len
= XVECLEN (exp
, 0);
1701 rtx
*tests
= xmalloc (len
* sizeof (rtx
));
1705 /* This lets us free all storage allocated below, if appropriate. */
1706 obstack_finish (rtl_obstack
);
1708 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1710 /* See if default value needs simplification. */
1711 if (GET_CODE (defval
) == COND
)
1712 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1714 /* Simplify the subexpressions, and see what tests we can get rid of. */
1716 for (i
= 0; i
< len
; i
+= 2)
1718 rtx newtest
, newval
;
1720 /* Simplify this test. */
1721 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1724 newval
= tests
[i
+ 1];
1725 /* See if this value may need simplification. */
1726 if (GET_CODE (newval
) == COND
)
1727 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1729 /* Look for ways to delete or combine this test. */
1730 if (newtest
== true_rtx
)
1732 /* If test is true, make this value the default
1733 and discard this + any following tests. */
1735 defval
= tests
[i
+ 1];
1736 new_defval
= newval
;
1739 else if (newtest
== false_rtx
)
1741 /* If test is false, discard it and its value. */
1742 for (j
= i
; j
< len
- 2; j
++)
1743 tests
[j
] = tests
[j
+ 2];
1748 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1750 /* If this value and the value for the prev test are the same,
1754 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1755 insn_code
, insn_index
);
1757 /* Delete this test/value. */
1758 for (j
= i
; j
< len
- 2; j
++)
1759 tests
[j
] = tests
[j
+ 2];
1765 tests
[i
+ 1] = newval
;
1768 /* If the last test in a COND has the same value
1769 as the default value, that test isn't needed. */
1771 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1774 /* See if we changed anything. */
1775 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1778 for (i
= 0; i
< len
; i
++)
1779 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1787 if (GET_CODE (defval
) == COND
)
1788 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1796 rtx newexp
= rtx_alloc (COND
);
1798 XVEC (newexp
, 0) = rtvec_alloc (len
);
1799 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1800 XEXP (newexp
, 1) = new_defval
;
1807 /* Remove an insn entry from an attribute value. */
1810 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1812 struct insn_ent
*previe
;
1814 if (av
->first_insn
== ie
)
1815 av
->first_insn
= ie
->next
;
1818 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1820 previe
->next
= ie
->next
;
1824 if (ie
->def
->insn_code
== -1)
1825 av
->has_asm_insn
= 0;
1830 /* Insert an insn entry in an attribute value list. */
1833 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1835 ie
->next
= av
->first_insn
;
1836 av
->first_insn
= ie
;
1838 if (ie
->def
->insn_code
== -1)
1839 av
->has_asm_insn
= 1;
1844 /* This is a utility routine to take an expression that is a tree of either
1845 AND or IOR expressions and insert a new term. The new term will be
1846 inserted at the right side of the first node whose code does not match
1847 the root. A new node will be created with the root's code. Its left
1848 side will be the old right side and its right side will be the new
1851 If the `term' is itself a tree, all its leaves will be inserted. */
1854 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1858 /* Avoid consing in some special cases. */
1859 if (code
== AND
&& term
== true_rtx
)
1861 if (code
== AND
&& term
== false_rtx
)
1863 if (code
== AND
&& exp
== true_rtx
)
1865 if (code
== AND
&& exp
== false_rtx
)
1867 if (code
== IOR
&& term
== true_rtx
)
1869 if (code
== IOR
&& term
== false_rtx
)
1871 if (code
== IOR
&& exp
== true_rtx
)
1873 if (code
== IOR
&& exp
== false_rtx
)
1875 if (attr_equal_p (exp
, term
))
1878 if (GET_CODE (term
) == code
)
1880 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1881 insn_code
, insn_index
);
1882 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1883 insn_code
, insn_index
);
1888 if (GET_CODE (exp
) == code
)
1890 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1891 term
, insn_code
, insn_index
);
1892 if (new != XEXP (exp
, 1))
1893 /* Make a copy of this expression and call recursively. */
1894 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1900 /* Insert the new term. */
1901 newexp
= attr_rtx (code
, exp
, term
);
1904 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1907 /* If we have an expression which AND's a bunch of
1908 (not (eq_attrq "alternative" "n"))
1909 terms, we may have covered all or all but one of the possible alternatives.
1910 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1912 This routine is passed an expression and either AND or IOR. It returns a
1913 bitmask indicating which alternatives are mentioned within EXP. */
1916 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1919 if (GET_CODE (exp
) == code
)
1920 return compute_alternative_mask (XEXP (exp
, 0), code
)
1921 | compute_alternative_mask (XEXP (exp
, 1), code
);
1923 else if (code
== AND
&& GET_CODE (exp
) == NOT
1924 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1925 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1926 string
= XSTR (XEXP (exp
, 0), 1);
1928 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1929 && XSTR (exp
, 0) == alternative_name
)
1930 string
= XSTR (exp
, 1);
1932 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1934 if (code
== AND
&& XINT (exp
, 1))
1935 return XINT (exp
, 0);
1937 if (code
== IOR
&& !XINT (exp
, 1))
1938 return XINT (exp
, 0);
1946 return 1 << (string
[0] - '0');
1947 return 1 << atoi (string
);
1950 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1951 attribute with the value represented by that bit. */
1954 make_alternative_compare (int mask
)
1956 return mk_attr_alt (mask
);
1959 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1960 of "attr" for this insn code. From that value, we can compute a test
1961 showing when the EQ_ATTR will be true. This routine performs that
1962 computation. If a test condition involves an address, we leave the EQ_ATTR
1963 intact because addresses are only valid for the `length' attribute.
1965 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1966 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1969 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
1976 switch (GET_CODE (value
))
1979 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
1990 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
1991 gcc_assert (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2
1994 strcpy (string
, XSTR (exp
, 0));
1995 strcat (string
, "_");
1996 strcat (string
, XSTR (exp
, 1));
1997 for (p
= string
; *p
; p
++)
2000 newexp
= attr_rtx (EQ
, value
,
2001 attr_rtx (SYMBOL_REF
,
2002 DEF_ATTR_STRING (string
)));
2007 /* We construct an IOR of all the cases for which the
2008 requested attribute value is present. Since we start with
2009 FALSE, if it is not present, FALSE will be returned.
2011 Each case is the AND of the NOT's of the previous conditions with the
2012 current condition; in the default case the current condition is TRUE.
2014 For each possible COND value, call ourselves recursively.
2016 The extra TRUE and FALSE expressions will be eliminated by another
2017 call to the simplification routine. */
2022 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2024 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2025 insn_code
, insn_index
);
2027 right
= insert_right_side (AND
, andexp
, this,
2028 insn_code
, insn_index
);
2029 right
= insert_right_side (AND
, right
,
2030 evaluate_eq_attr (exp
,
2033 insn_code
, insn_index
),
2034 insn_code
, insn_index
);
2035 orexp
= insert_right_side (IOR
, orexp
, right
,
2036 insn_code
, insn_index
);
2038 /* Add this condition into the AND expression. */
2039 newexp
= attr_rtx (NOT
, this);
2040 andexp
= insert_right_side (AND
, andexp
, newexp
,
2041 insn_code
, insn_index
);
2044 /* Handle the default case. */
2045 right
= insert_right_side (AND
, andexp
,
2046 evaluate_eq_attr (exp
, XEXP (value
, 1),
2047 insn_code
, insn_index
),
2048 insn_code
, insn_index
);
2049 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2056 /* If uses an address, must return original expression. But set the
2057 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2060 walk_attr_value (newexp
);
2064 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2065 return copy_rtx_unchanging (exp
);
2072 /* This routine is called when an AND of a term with a tree of AND's is
2073 encountered. If the term or its complement is present in the tree, it
2074 can be replaced with TRUE or FALSE, respectively.
2076 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2077 be true and hence are complementary.
2079 There is one special case: If we see
2080 (and (not (eq_attr "att" "v1"))
2081 (eq_attr "att" "v2"))
2082 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2083 replace the term, not anything in the AND tree. So we pass a pointer to
2087 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2092 int left_eliminates_term
, right_eliminates_term
;
2094 if (GET_CODE (exp
) == AND
)
2096 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2097 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2098 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2100 newexp
= attr_rtx (AND
, left
, right
);
2102 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2106 else if (GET_CODE (exp
) == IOR
)
2108 /* For the IOR case, we do the same as above, except that we can
2109 only eliminate `term' if both sides of the IOR would do so. */
2111 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2112 left_eliminates_term
= (temp
== true_rtx
);
2115 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2116 right_eliminates_term
= (temp
== true_rtx
);
2118 if (left_eliminates_term
&& right_eliminates_term
)
2121 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2123 newexp
= attr_rtx (IOR
, left
, right
);
2125 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2129 /* Check for simplifications. Do some extra checking here since this
2130 routine is called so many times. */
2135 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2138 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2141 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2143 if (attr_alt_subset_p (*pterm
, exp
))
2146 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2149 if (attr_alt_subset_p (exp
, *pterm
))
2155 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2157 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2160 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2166 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2167 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2169 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2172 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2178 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2179 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2181 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2184 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2190 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2192 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2196 else if (GET_CODE (exp
) == NOT
)
2198 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2202 else if (GET_CODE (*pterm
) == NOT
)
2204 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2208 else if (attr_equal_p (exp
, *pterm
))
2214 /* Similar to `simplify_and_tree', but for IOR trees. */
2217 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2222 int left_eliminates_term
, right_eliminates_term
;
2224 if (GET_CODE (exp
) == IOR
)
2226 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2227 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2228 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2230 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2232 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2236 else if (GET_CODE (exp
) == AND
)
2238 /* For the AND case, we do the same as above, except that we can
2239 only eliminate `term' if both sides of the AND would do so. */
2241 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2242 left_eliminates_term
= (temp
== false_rtx
);
2245 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2246 right_eliminates_term
= (temp
== false_rtx
);
2248 if (left_eliminates_term
&& right_eliminates_term
)
2251 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2253 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2255 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2259 if (attr_equal_p (exp
, *pterm
))
2262 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2265 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2268 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2269 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2270 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2273 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2274 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2275 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2281 /* Compute approximate cost of the expression. Used to decide whether
2282 expression is cheap enough for inline. */
2284 attr_rtx_cost (rtx x
)
2290 code
= GET_CODE (x
);
2303 /* Alternatives don't result into function call. */
2304 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2311 const char *fmt
= GET_RTX_FORMAT (code
);
2312 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2318 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2319 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2322 cost
+= attr_rtx_cost (XEXP (x
, i
));
2332 /* Simplify test expression and use temporary obstack in order to avoid
2333 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2334 and avoid unnecessary copying if possible. */
2337 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2340 struct obstack
*old
;
2341 if (ATTR_IND_SIMPLIFIED_P (exp
))
2344 rtl_obstack
= temp_obstack
;
2345 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2347 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2349 return attr_copy_rtx (x
);
2352 /* Returns true if S1 is a subset of S2. */
2355 attr_alt_subset_p (rtx s1
, rtx s2
)
2357 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2360 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2363 return !(XINT (s1
, 0) & XINT (s2
, 0));
2369 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2376 /* Returns true if S1 is a subset of complement of S2. */
2379 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2381 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2384 return !(XINT (s1
, 0) & XINT (s2
, 0));
2387 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2390 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2400 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2403 attr_alt_intersection (rtx s1
, rtx s2
)
2405 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2407 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2410 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2413 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2416 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2419 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2424 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2429 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2432 attr_alt_union (rtx s1
, rtx s2
)
2434 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2436 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2439 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2442 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2445 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2448 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2454 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2458 /* Return EQ_ATTR_ALT expression representing complement of S. */
2461 attr_alt_complement (rtx s
)
2463 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2465 XINT (result
, 0) = XINT (s
, 0);
2466 XINT (result
, 1) = 1 - XINT (s
, 1);
2471 /* Return EQ_ATTR_ALT expression representing set containing elements set
2477 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2479 XINT (result
, 0) = e
;
2480 XINT (result
, 1) = 0;
2485 /* Given an expression, see if it can be simplified for a particular insn
2486 code based on the values of other attributes being tested. This can
2487 eliminate nested get_attr_... calls.
2489 Note that if an endless recursion is specified in the patterns, the
2490 optimization will loop. However, it will do so in precisely the cases where
2491 an infinite recursion loop could occur during compilation. It's better that
2495 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2498 struct attr_desc
*attr
;
2499 struct attr_value
*av
;
2500 struct insn_ent
*ie
;
2503 bool left_alt
, right_alt
;
2505 /* Don't re-simplify something we already simplified. */
2506 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2509 switch (GET_CODE (exp
))
2512 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2513 if (left
== false_rtx
)
2515 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2516 if (right
== false_rtx
)
2519 if (GET_CODE (left
) == EQ_ATTR_ALT
2520 && GET_CODE (right
) == EQ_ATTR_ALT
)
2522 exp
= attr_alt_intersection (left
, right
);
2523 return simplify_test_exp (exp
, insn_code
, insn_index
);
2526 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2527 present on both sides, apply the distributive law since this will
2528 yield simplifications. */
2529 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2530 && compute_alternative_mask (left
, IOR
)
2531 && compute_alternative_mask (right
, IOR
))
2533 if (GET_CODE (left
) == IOR
)
2540 newexp
= attr_rtx (IOR
,
2541 attr_rtx (AND
, left
, XEXP (right
, 0)),
2542 attr_rtx (AND
, left
, XEXP (right
, 1)));
2544 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2547 /* Try with the term on both sides. */
2548 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2549 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2550 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2552 if (left
== false_rtx
|| right
== false_rtx
)
2554 else if (left
== true_rtx
)
2558 else if (right
== true_rtx
)
2562 /* See if all or all but one of the insn's alternatives are specified
2563 in this tree. Optimize if so. */
2565 if (GET_CODE (left
) == NOT
)
2566 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2567 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2569 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2572 if (GET_CODE (right
) == NOT
)
2573 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2574 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2576 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2577 && XINT (right
, 1));
2580 && (GET_CODE (left
) == AND
2582 || GET_CODE (right
) == AND
2585 i
= compute_alternative_mask (exp
, AND
);
2586 if (i
& ~insn_alternatives
[insn_code
])
2587 fatal ("invalid alternative specified for pattern number %d",
2590 /* If all alternatives are excluded, this is false. */
2591 i
^= insn_alternatives
[insn_code
];
2594 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2596 /* If just one excluded, AND a comparison with that one to the
2597 front of the tree. The others will be eliminated by
2598 optimization. We do not want to do this if the insn has one
2599 alternative and we have tested none of them! */
2600 left
= make_alternative_compare (i
);
2601 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2602 newexp
= attr_rtx (AND
, left
, right
);
2604 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2608 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2610 newexp
= attr_rtx (AND
, left
, right
);
2611 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2616 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2617 if (left
== true_rtx
)
2619 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2620 if (right
== true_rtx
)
2623 if (GET_CODE (left
) == EQ_ATTR_ALT
2624 && GET_CODE (right
) == EQ_ATTR_ALT
)
2626 exp
= attr_alt_union (left
, right
);
2627 return simplify_test_exp (exp
, insn_code
, insn_index
);
2630 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2631 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2632 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2634 if (right
== true_rtx
|| left
== true_rtx
)
2636 else if (left
== false_rtx
)
2640 else if (right
== false_rtx
)
2645 /* Test for simple cases where the distributive law is useful. I.e.,
2646 convert (ior (and (x) (y))
2652 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2653 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2655 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2657 left
= XEXP (left
, 0);
2659 newexp
= attr_rtx (AND
, left
, right
);
2660 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2663 /* See if all or all but one of the insn's alternatives are specified
2664 in this tree. Optimize if so. */
2666 else if (insn_code
>= 0
2667 && (GET_CODE (left
) == IOR
2668 || (GET_CODE (left
) == EQ_ATTR_ALT
2670 || (GET_CODE (left
) == EQ_ATTR
2671 && XSTR (left
, 0) == alternative_name
)
2672 || GET_CODE (right
) == IOR
2673 || (GET_CODE (right
) == EQ_ATTR_ALT
2674 && !XINT (right
, 1))
2675 || (GET_CODE (right
) == EQ_ATTR
2676 && XSTR (right
, 0) == alternative_name
)))
2678 i
= compute_alternative_mask (exp
, IOR
);
2679 if (i
& ~insn_alternatives
[insn_code
])
2680 fatal ("invalid alternative specified for pattern number %d",
2683 /* If all alternatives are included, this is true. */
2684 i
^= insn_alternatives
[insn_code
];
2687 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2689 /* If just one excluded, IOR a comparison with that one to the
2690 front of the tree. The others will be eliminated by
2691 optimization. We do not want to do this if the insn has one
2692 alternative and we have tested none of them! */
2693 left
= make_alternative_compare (i
);
2694 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2695 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2697 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2701 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2703 newexp
= attr_rtx (IOR
, left
, right
);
2704 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2709 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2711 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2712 insn_code
, insn_index
);
2716 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2717 if (GET_CODE (left
) == NOT
)
2718 return XEXP (left
, 0);
2720 if (left
== false_rtx
)
2722 if (left
== true_rtx
)
2725 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2727 exp
= attr_alt_complement (left
);
2728 return simplify_test_exp (exp
, insn_code
, insn_index
);
2731 /* Try to apply De`Morgan's laws. */
2732 if (GET_CODE (left
) == IOR
)
2734 newexp
= attr_rtx (AND
,
2735 attr_rtx (NOT
, XEXP (left
, 0)),
2736 attr_rtx (NOT
, XEXP (left
, 1)));
2738 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2740 else if (GET_CODE (left
) == AND
)
2742 newexp
= attr_rtx (IOR
,
2743 attr_rtx (NOT
, XEXP (left
, 0)),
2744 attr_rtx (NOT
, XEXP (left
, 1)));
2746 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2748 else if (left
!= XEXP (exp
, 0))
2750 newexp
= attr_rtx (NOT
, left
);
2756 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2760 if (XSTR (exp
, 0) == alternative_name
)
2762 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2766 /* Look at the value for this insn code in the specified attribute.
2767 We normally can replace this comparison with the condition that
2768 would give this insn the values being tested for. */
2770 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2771 for (av
= attr
->first_value
; av
; av
= av
->next
)
2772 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2773 if (ie
->def
->insn_code
== insn_code
)
2776 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2777 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2778 if (attr_rtx_cost(x
) < 20)
2787 /* We have already simplified this expression. Simplifying it again
2788 won't buy anything unless we weren't given a valid insn code
2789 to process (i.e., we are canonicalizing something.). */
2791 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2792 return copy_rtx_unchanging (newexp
);
2797 /* Optimize the attribute lists by seeing if we can determine conditional
2798 values from the known values of other attributes. This will save subroutine
2799 calls during the compilation. */
2802 optimize_attrs (void)
2804 struct attr_desc
*attr
;
2805 struct attr_value
*av
;
2806 struct insn_ent
*ie
;
2809 struct attr_value_list
2811 struct attr_value
*av
;
2812 struct insn_ent
*ie
;
2813 struct attr_desc
*attr
;
2814 struct attr_value_list
*next
;
2816 struct attr_value_list
**insn_code_values
;
2817 struct attr_value_list
*ivbuf
;
2818 struct attr_value_list
*iv
;
2820 /* For each insn code, make a list of all the insn_ent's for it,
2821 for all values for all attributes. */
2823 if (num_insn_ents
== 0)
2826 /* Make 2 extra elements, for "code" values -2 and -1. */
2827 insn_code_values
= xcalloc ((insn_code_number
+ 2),
2828 sizeof (struct attr_value_list
*));
2830 /* Offset the table address so we can index by -2 or -1. */
2831 insn_code_values
+= 2;
2833 iv
= ivbuf
= xmalloc (num_insn_ents
* sizeof (struct attr_value_list
));
2835 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2836 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2837 for (av
= attr
->first_value
; av
; av
= av
->next
)
2838 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2843 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2844 insn_code_values
[ie
->def
->insn_code
] = iv
;
2848 /* Sanity check on num_insn_ents. */
2849 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2851 /* Process one insn code at a time. */
2852 for (i
= -2; i
< insn_code_number
; i
++)
2854 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2855 We use it to mean "already simplified for this insn". */
2856 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2857 clear_struct_flag (iv
->av
->value
);
2859 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2861 struct obstack
*old
= rtl_obstack
;
2866 if (GET_CODE (av
->value
) != COND
)
2869 rtl_obstack
= temp_obstack
;
2871 while (GET_CODE (newexp
) == COND
)
2873 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2874 ie
->def
->insn_index
);
2875 if (newexp2
== newexp
)
2881 if (newexp
!= av
->value
)
2883 newexp
= attr_copy_rtx (newexp
);
2884 remove_insn_ent (av
, ie
);
2885 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2887 insert_insn_ent (av
, ie
);
2893 free (insn_code_values
- 2);
2896 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2899 clear_struct_flag (rtx x
)
2906 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2907 if (ATTR_IND_SIMPLIFIED_P (x
))
2910 code
= GET_CODE (x
);
2930 /* Compare the elements. If any pair of corresponding elements
2931 fail to match, return 0 for the whole things. */
2933 fmt
= GET_RTX_FORMAT (code
);
2934 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2940 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2941 clear_struct_flag (XVECEXP (x
, i
, j
));
2945 clear_struct_flag (XEXP (x
, i
));
2951 /* Create table entries for DEFINE_ATTR. */
2954 gen_attr (rtx exp
, int lineno
)
2956 struct attr_desc
*attr
;
2957 struct attr_value
*av
;
2958 const char *name_ptr
;
2961 /* Make a new attribute structure. Check for duplicate by looking at
2962 attr->default_val, since it is initialized by this routine. */
2963 attr
= find_attr (&XSTR (exp
, 0), 1);
2964 if (attr
->default_val
)
2966 message_with_line (lineno
, "duplicate definition for attribute %s",
2968 message_with_line (attr
->lineno
, "previous definition");
2972 attr
->lineno
= lineno
;
2974 if (*XSTR (exp
, 1) == '\0')
2975 attr
->is_numeric
= 1;
2978 name_ptr
= XSTR (exp
, 1);
2979 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
2981 av
= oballoc (sizeof (struct attr_value
));
2982 av
->value
= attr_rtx (CONST_STRING
, p
);
2983 av
->next
= attr
->first_value
;
2984 attr
->first_value
= av
;
2985 av
->first_insn
= NULL
;
2987 av
->has_asm_insn
= 0;
2991 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
2994 if (attr
->is_numeric
)
2996 message_with_line (lineno
,
2997 "constant attributes may not take numeric values");
3001 /* Get rid of the CONST node. It is allowed only at top-level. */
3002 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3005 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3007 message_with_line (lineno
,
3008 "`length' attribute must take numeric values");
3012 /* Set up the default value. */
3013 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3014 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3017 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3018 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3019 number of alternatives as this should be checked elsewhere. */
3022 count_alternatives (rtx exp
)
3027 if (GET_CODE (exp
) == MATCH_OPERAND
)
3028 return n_comma_elts (XSTR (exp
, 2));
3030 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3031 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3036 n
= count_alternatives (XEXP (exp
, i
));
3043 if (XVEC (exp
, i
) != NULL
)
3044 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3046 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3055 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3056 `alternative' attribute. */
3059 compares_alternatives_p (rtx exp
)
3064 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3067 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3068 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3073 if (compares_alternatives_p (XEXP (exp
, i
)))
3078 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3079 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3087 /* Returns nonzero is INNER is contained in EXP. */
3090 contained_in_p (rtx inner
, rtx exp
)
3095 if (rtx_equal_p (inner
, exp
))
3098 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3099 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3104 if (contained_in_p (inner
, XEXP (exp
, i
)))
3109 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3110 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
3118 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3121 gen_insn (rtx exp
, int lineno
)
3123 struct insn_def
*id
;
3125 id
= oballoc (sizeof (struct insn_def
));
3129 id
->lineno
= lineno
;
3131 switch (GET_CODE (exp
))
3134 id
->insn_code
= insn_code_number
;
3135 id
->insn_index
= insn_index_number
;
3136 id
->num_alternatives
= count_alternatives (exp
);
3137 if (id
->num_alternatives
== 0)
3138 id
->num_alternatives
= 1;
3142 case DEFINE_PEEPHOLE
:
3143 id
->insn_code
= insn_code_number
;
3144 id
->insn_index
= insn_index_number
;
3145 id
->num_alternatives
= count_alternatives (exp
);
3146 if (id
->num_alternatives
== 0)
3147 id
->num_alternatives
= 1;
3151 case DEFINE_ASM_ATTRIBUTES
:
3153 id
->insn_index
= -1;
3154 id
->num_alternatives
= 1;
3156 got_define_asm_attributes
= 1;
3164 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3165 true or annul false is specified, and make a `struct delay_desc'. */
3168 gen_delay (rtx def
, int lineno
)
3170 struct delay_desc
*delay
;
3173 if (XVECLEN (def
, 1) % 3 != 0)
3175 message_with_line (lineno
,
3176 "number of elements in DEFINE_DELAY must be multiple of three");
3181 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3183 if (XVECEXP (def
, 1, i
+ 1))
3184 have_annul_true
= 1;
3185 if (XVECEXP (def
, 1, i
+ 2))
3186 have_annul_false
= 1;
3189 delay
= oballoc (sizeof (struct delay_desc
));
3191 delay
->num
= ++num_delays
;
3192 delay
->next
= delays
;
3193 delay
->lineno
= lineno
;
3197 /* Given a piece of RTX, print a C expression to test its truth value.
3198 We use AND and IOR both for logical and bit-wise operations, so
3199 interpret them as logical unless they are inside a comparison expression.
3200 The first bit of FLAGS will be nonzero in that case.
3202 Set the second bit of FLAGS to make references to attribute values use
3203 a cached local variable instead of calling a function. */
3206 write_test_expr (rtx exp
, int flags
)
3208 int comparison_operator
= 0;
3210 struct attr_desc
*attr
;
3212 /* In order not to worry about operator precedence, surround our part of
3213 the expression with parentheses. */
3216 code
= GET_CODE (exp
);
3219 /* Binary operators. */
3222 printf ("(unsigned) ");
3228 comparison_operator
= 1;
3230 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3231 case AND
: case IOR
: case XOR
:
3232 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3233 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3249 printf (" >= (unsigned) ");
3252 printf (" > (unsigned) ");
3261 printf (" <= (unsigned) ");
3264 printf (" < (unsigned) ");
3307 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3311 /* Special-case (not (eq_attrq "alternative" "x")) */
3312 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3313 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3315 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3319 /* Otherwise, fall through to normal unary operator. */
3321 /* Unary operators. */
3341 write_test_expr (XEXP (exp
, 0), flags
);
3346 int set
= XINT (exp
, 0), bit
= 0;
3349 fatal ("EQ_ATTR_ALT not valid inside comparison");
3352 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3354 if (!(set
& (set
- 1)))
3356 if (!(set
& 0xffff))
3379 printf ("which_alternative %s= %d",
3380 XINT (exp
, 1) ? "!" : "=", bit
);
3384 printf ("%s((1 << which_alternative) & 0x%x)",
3385 XINT (exp
, 1) ? "!" : "", set
);
3390 /* Comparison test of an attribute with a value. Most of these will
3391 have been removed by optimization. Handle "alternative"
3392 specially and give error if EQ_ATTR present inside a comparison. */
3395 fatal ("EQ_ATTR not valid inside comparison");
3397 if (XSTR (exp
, 0) == alternative_name
)
3399 printf ("which_alternative == %s", XSTR (exp
, 1));
3403 attr
= find_attr (&XSTR (exp
, 0), 0);
3406 /* Now is the time to expand the value of a constant attribute. */
3409 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3416 printf ("attr_%s", attr
->name
);
3418 printf ("get_attr_%s (insn)", attr
->name
);
3420 write_attr_valueq (attr
, XSTR (exp
, 1));
3424 /* Comparison test of flags for define_delays. */
3427 fatal ("ATTR_FLAG not valid inside comparison");
3428 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3431 /* See if an operand matches a predicate. */
3433 /* If only a mode is given, just ensure the mode matches the operand.
3434 If neither a mode nor predicate is given, error. */
3435 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3437 if (GET_MODE (exp
) == VOIDmode
)
3438 fatal ("null MATCH_OPERAND specified as test");
3440 printf ("GET_MODE (operands[%d]) == %smode",
3441 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3444 printf ("%s (operands[%d], %smode)",
3445 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3448 /* Constant integer. */
3450 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3453 /* A random C expression. */
3455 print_c_condition (XSTR (exp
, 0));
3458 /* The address of the branch target. */
3460 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3461 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3465 /* The address of the current insn. We implement this actually as the
3466 address of the current insn for backward branches, but the last
3467 address of the next insn for forward branches, and both with
3468 adjustments that account for the worst-case possible stretching of
3469 intervening alignments between this insn and its destination. */
3470 printf ("insn_current_reference_address (insn)");
3474 printf ("%s", XSTR (exp
, 0));
3478 write_test_expr (XEXP (exp
, 0), flags
& 2);
3480 write_test_expr (XEXP (exp
, 1), flags
| 1);
3482 write_test_expr (XEXP (exp
, 2), flags
| 1);
3486 fatal ("bad RTX code `%s' in attribute calculation\n",
3487 GET_RTX_NAME (code
));
3493 /* Given an attribute value, return the maximum CONST_STRING argument
3494 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3497 max_attr_value (rtx exp
, int *unknownp
)
3502 switch (GET_CODE (exp
))
3505 current_max
= atoi (XSTR (exp
, 0));
3509 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3510 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3512 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3513 if (n
> current_max
)
3519 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3520 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3521 if (n
> current_max
)
3527 current_max
= INT_MAX
;
3534 /* Given an attribute value, return the result of ORing together all
3535 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3536 if the numeric value is not known. */
3539 or_attr_value (rtx exp
, int *unknownp
)
3544 switch (GET_CODE (exp
))
3547 current_or
= atoi (XSTR (exp
, 0));
3551 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3552 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3553 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3557 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3558 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3570 /* Scan an attribute value, possibly a conditional, and record what actions
3571 will be required to do any conditional tests in it.
3574 `must_extract' if we need to extract the insn operands
3575 `must_constrain' if we must compute `which_alternative'
3576 `address_used' if an address expression was used
3577 `length_used' if an (eq_attr "length" ...) was used
3581 walk_attr_value (rtx exp
)
3590 code
= GET_CODE (exp
);
3594 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3595 /* Since this is an arbitrary expression, it can look at anything.
3596 However, constant expressions do not depend on any particular
3598 must_extract
= must_constrain
= 1;
3606 must_extract
= must_constrain
= 1;
3610 if (XSTR (exp
, 0) == alternative_name
)
3611 must_extract
= must_constrain
= 1;
3612 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3632 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3637 walk_attr_value (XEXP (exp
, i
));
3641 if (XVEC (exp
, i
) != NULL
)
3642 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3643 walk_attr_value (XVECEXP (exp
, i
, j
));
3648 /* Write out a function to obtain the attribute for a given INSN. */
3651 write_attr_get (struct attr_desc
*attr
)
3653 struct attr_value
*av
, *common_av
;
3655 /* Find the most used attribute value. Handle that as the `default' of the
3656 switch we will generate. */
3657 common_av
= find_most_used (attr
);
3659 /* Write out start of function, then all values with explicit `case' lines,
3660 then a `default', then the value with the most uses. */
3663 if (!attr
->is_numeric
)
3664 printf ("enum attr_%s\n", attr
->name
);
3668 /* If the attribute name starts with a star, the remainder is the name of
3669 the subroutine to use, instead of `get_attr_...'. */
3670 if (attr
->name
[0] == '*')
3671 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3672 else if (attr
->is_const
== 0)
3673 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3676 printf ("get_attr_%s (void)\n", attr
->name
);
3679 for (av
= attr
->first_value
; av
; av
= av
->next
)
3680 if (av
->num_insns
== 1)
3681 write_attr_set (attr
, 2, av
->value
, "return", ";",
3682 true_rtx
, av
->first_insn
->def
->insn_code
,
3683 av
->first_insn
->def
->insn_index
);
3684 else if (av
->num_insns
!= 0)
3685 write_attr_set (attr
, 2, av
->value
, "return", ";",
3693 printf (" switch (recog_memoized (insn))\n");
3696 for (av
= attr
->first_value
; av
; av
= av
->next
)
3697 if (av
!= common_av
)
3698 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3700 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3701 printf (" }\n}\n\n");
3704 /* Given an AND tree of known true terms (because we are inside an `if' with
3705 that as the condition or are in an `else' clause) and an expression,
3706 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3707 the bulk of the work. */
3710 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3714 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3716 if (GET_CODE (known_true
) == AND
)
3718 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3719 insn_code
, insn_index
);
3720 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3721 insn_code
, insn_index
);
3726 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3732 /* Write out a series of tests and assignment statements to perform tests and
3733 sets of an attribute value. We are passed an indentation amount and prefix
3734 and suffix strings to write around each attribute value (e.g., "return"
3738 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3739 const char *prefix
, const char *suffix
, rtx known_true
,
3740 int insn_code
, int insn_index
)
3742 if (GET_CODE (value
) == COND
)
3744 /* Assume the default value will be the default of the COND unless we
3745 find an always true expression. */
3746 rtx default_val
= XEXP (value
, 1);
3747 rtx our_known_true
= known_true
;
3752 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3757 testexp
= eliminate_known_true (our_known_true
,
3758 XVECEXP (value
, 0, i
),
3759 insn_code
, insn_index
);
3760 newexp
= attr_rtx (NOT
, testexp
);
3761 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3762 insn_code
, insn_index
);
3764 /* If the test expression is always true or if the next `known_true'
3765 expression is always false, this is the last case, so break
3766 out and let this value be the `else' case. */
3767 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3769 default_val
= XVECEXP (value
, 0, i
+ 1);
3773 /* Compute the expression to pass to our recursive call as being
3775 inner_true
= insert_right_side (AND
, our_known_true
,
3776 testexp
, insn_code
, insn_index
);
3778 /* If this is always false, skip it. */
3779 if (inner_true
== false_rtx
)
3782 write_indent (indent
);
3783 printf ("%sif ", first_if
? "" : "else ");
3785 write_test_expr (testexp
, 0);
3787 write_indent (indent
+ 2);
3790 write_attr_set (attr
, indent
+ 4,
3791 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3792 inner_true
, insn_code
, insn_index
);
3793 write_indent (indent
+ 2);
3795 our_known_true
= newexp
;
3800 write_indent (indent
);
3802 write_indent (indent
+ 2);
3806 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
3807 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
3811 write_indent (indent
+ 2);
3817 write_indent (indent
);
3818 printf ("%s ", prefix
);
3819 write_attr_value (attr
, value
);
3820 printf ("%s\n", suffix
);
3824 /* Write a series of case statements for every instruction in list IE.
3825 INDENT is the amount of indentation to write before each case. */
3828 write_insn_cases (struct insn_ent
*ie
, int indent
)
3830 for (; ie
!= 0; ie
= ie
->next
)
3831 if (ie
->def
->insn_code
!= -1)
3833 write_indent (indent
);
3834 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
3835 printf ("case %d: /* define_peephole, line %d */\n",
3836 ie
->def
->insn_code
, ie
->def
->lineno
);
3838 printf ("case %d: /* %s */\n",
3839 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
3843 /* Write out the computation for one attribute value. */
3846 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
3847 int write_case_lines
, const char *prefix
, const char *suffix
,
3848 int indent
, rtx known_true
)
3850 if (av
->num_insns
== 0)
3853 if (av
->has_asm_insn
)
3855 write_indent (indent
);
3856 printf ("case -1:\n");
3857 write_indent (indent
+ 2);
3858 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3859 write_indent (indent
+ 2);
3860 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3861 write_indent (indent
+ 2);
3862 printf (" fatal_insn_not_found (insn);\n");
3865 if (write_case_lines
)
3866 write_insn_cases (av
->first_insn
, indent
);
3869 write_indent (indent
);
3870 printf ("default:\n");
3873 /* See what we have to do to output this value. */
3874 must_extract
= must_constrain
= address_used
= 0;
3875 walk_attr_value (av
->value
);
3879 write_indent (indent
+ 2);
3880 printf ("extract_constrain_insn_cached (insn);\n");
3882 else if (must_extract
)
3884 write_indent (indent
+ 2);
3885 printf ("extract_insn_cached (insn);\n");
3888 if (av
->num_insns
== 1)
3889 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3890 known_true
, av
->first_insn
->def
->insn_code
,
3891 av
->first_insn
->def
->insn_index
);
3893 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3896 if (strncmp (prefix
, "return", 6))
3898 write_indent (indent
+ 2);
3899 printf ("break;\n");
3904 /* Search for uses of non-const attributes and write code to cache them. */
3907 write_expr_attr_cache (rtx p
, struct attr_desc
*attr
)
3912 if (GET_CODE (p
) == EQ_ATTR
)
3914 if (XSTR (p
, 0) != attr
->name
)
3917 if (!attr
->is_numeric
)
3918 printf (" enum attr_%s ", attr
->name
);
3922 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
3926 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
3927 ie
= GET_RTX_LENGTH (GET_CODE (p
));
3928 for (i
= 0; i
< ie
; i
++)
3933 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
3938 je
= XVECLEN (p
, i
);
3939 for (j
= 0; j
< je
; ++j
)
3940 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
3949 /* Utilities to write in various forms. */
3952 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
3954 if (attr
->is_numeric
)
3960 if (num
> 9 || num
< 0)
3961 printf (" /* 0x%x */", num
);
3965 write_upcase (attr
->name
);
3972 write_attr_value (struct attr_desc
*attr
, rtx value
)
3976 switch (GET_CODE (value
))
3979 write_attr_valueq (attr
, XSTR (value
, 0));
3983 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
3987 print_c_condition (XSTR (value
, 0));
3992 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
3993 printf ("get_attr_%s (%s)", attr2
->name
,
3994 (attr2
->is_const
? "" : "insn"));
4015 write_attr_value (attr
, XEXP (value
, 0));
4019 write_attr_value (attr
, XEXP (value
, 1));
4028 write_upcase (const char *str
)
4032 /* The argument of TOUPPER should not have side effects. */
4033 putchar (TOUPPER(*str
));
4039 write_indent (int indent
)
4041 for (; indent
> 8; indent
-= 8)
4044 for (; indent
; indent
--)
4048 /* Write a subroutine that is given an insn that requires a delay slot, a
4049 delay slot ordinal, and a candidate insn. It returns nonzero if the
4050 candidate can be placed in the specified delay slot of the insn.
4052 We can write as many as three subroutines. `eligible_for_delay'
4053 handles normal delay slots, `eligible_for_annul_true' indicates that
4054 the specified insn can be annulled if the branch is true, and likewise
4055 for `eligible_for_annul_false'.
4057 KIND is a string distinguishing these three cases ("delay", "annul_true",
4058 or "annul_false"). */
4061 write_eligible_delay (const char *kind
)
4063 struct delay_desc
*delay
;
4067 struct attr_desc
*attr
;
4068 struct attr_value
*av
, *common_av
;
4071 /* Compute the maximum number of delay slots required. We use the delay
4072 ordinal times this number plus one, plus the slot number as an index into
4073 the appropriate predicate to test. */
4075 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4076 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4077 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4079 /* Write function prelude. */
4082 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4085 printf (" rtx insn;\n");
4087 printf (" gcc_assert (slot < %d);\n", max_slots
);
4089 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4090 converts a compound instruction into a loop. */
4091 printf (" if (!INSN_P (candidate_insn))\n");
4092 printf (" return 0;\n");
4095 /* If more than one delay type, find out which type the delay insn is. */
4099 attr
= find_attr (&delay_type_str
, 0);
4101 common_av
= find_most_used (attr
);
4103 printf (" insn = delay_insn;\n");
4104 printf (" switch (recog_memoized (insn))\n");
4107 sprintf (str
, " * %d;\n break;", max_slots
);
4108 for (av
= attr
->first_value
; av
; av
= av
->next
)
4109 if (av
!= common_av
)
4110 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4112 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4115 /* Ensure matched. Otherwise, shouldn't have been called. */
4116 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4119 /* If just one type of delay slot, write simple switch. */
4120 if (num_delays
== 1 && max_slots
== 1)
4122 printf (" insn = candidate_insn;\n");
4123 printf (" switch (recog_memoized (insn))\n");
4126 attr
= find_attr (&delay_1_0_str
, 0);
4128 common_av
= find_most_used (attr
);
4130 for (av
= attr
->first_value
; av
; av
= av
->next
)
4131 if (av
!= common_av
)
4132 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4134 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4140 /* Write a nested CASE. The first indicates which condition we need to
4141 test, and the inner CASE tests the condition. */
4142 printf (" insn = candidate_insn;\n");
4143 printf (" switch (slot)\n");
4146 for (delay
= delays
; delay
; delay
= delay
->next
)
4147 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4149 printf (" case %d:\n",
4150 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4151 printf (" switch (recog_memoized (insn))\n");
4154 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4156 attr
= find_attr (&pstr
, 0);
4158 common_av
= find_most_used (attr
);
4160 for (av
= attr
->first_value
; av
; av
= av
->next
)
4161 if (av
!= common_av
)
4162 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4164 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4168 printf (" default:\n");
4169 printf (" gcc_unreachable ();\n");
4176 /* This page contains miscellaneous utility routines. */
4178 /* Given a pointer to a (char *), return a malloc'ed string containing the
4179 next comma-separated element. Advance the pointer to after the string
4180 scanned, or the end-of-string. Return NULL if at end of string. */
4183 next_comma_elt (const char **pstr
)
4187 start
= scan_comma_elt (pstr
);
4192 return attr_string (start
, *pstr
- start
);
4195 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4196 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4197 replaced by a pointer to a canonical copy of the string. */
4199 static struct attr_desc
*
4200 find_attr (const char **name_p
, int create
)
4202 struct attr_desc
*attr
;
4204 const char *name
= *name_p
;
4206 /* Before we resort to using `strcmp', see if the string address matches
4207 anywhere. In most cases, it should have been canonicalized to do so. */
4208 if (name
== alternative_name
)
4211 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4212 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4213 if (name
== attr
->name
)
4216 /* Otherwise, do it the slow way. */
4217 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4218 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4220 *name_p
= attr
->name
;
4227 attr
= oballoc (sizeof (struct attr_desc
));
4228 attr
->name
= DEF_ATTR_STRING (name
);
4229 attr
->first_value
= attr
->default_val
= NULL
;
4230 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4232 attr
->next
= attrs
[index
];
4233 attrs
[index
] = attr
;
4235 *name_p
= attr
->name
;
4240 /* Create internal attribute with the given default value. */
4243 make_internal_attr (const char *name
, rtx value
, int special
)
4245 struct attr_desc
*attr
;
4247 attr
= find_attr (&name
, 1);
4248 gcc_assert (!attr
->default_val
);
4250 attr
->is_numeric
= 1;
4252 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4253 attr
->static_p
= (special
& ATTR_STATIC
) != 0;
4254 attr
->default_val
= get_attr_value (value
, attr
, -2);
4257 /* Find the most used value of an attribute. */
4259 static struct attr_value
*
4260 find_most_used (struct attr_desc
*attr
)
4262 struct attr_value
*av
;
4263 struct attr_value
*most_used
;
4269 for (av
= attr
->first_value
; av
; av
= av
->next
)
4270 if (av
->num_insns
> nuses
)
4271 nuses
= av
->num_insns
, most_used
= av
;
4276 /* Return (attr_value "n") */
4279 make_numeric_value (int n
)
4281 static rtx int_values
[20];
4285 gcc_assert (n
>= 0);
4287 if (n
< 20 && int_values
[n
])
4288 return int_values
[n
];
4290 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4291 exp
= attr_rtx (CONST_STRING
, p
);
4294 int_values
[n
] = exp
;
4300 copy_rtx_unchanging (rtx orig
)
4302 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4305 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4309 /* Determine if an insn has a constant number of delay slots, i.e., the
4310 number of delay slots is not a function of the length of the insn. */
4313 write_const_num_delay_slots (void)
4315 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4316 struct attr_value
*av
;
4320 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4322 printf (" switch (recog_memoized (insn))\n");
4325 for (av
= attr
->first_value
; av
; av
= av
->next
)
4328 walk_attr_value (av
->value
);
4330 write_insn_cases (av
->first_insn
, 4);
4333 printf (" default:\n");
4334 printf (" return 1;\n");
4335 printf (" }\n}\n\n");
4340 main (int argc
, char **argv
)
4343 struct attr_desc
*attr
;
4344 struct insn_def
*id
;
4348 progname
= "genattrtab";
4350 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
4351 return (FATAL_EXIT_CODE
);
4353 obstack_init (hash_obstack
);
4354 obstack_init (temp_obstack
);
4356 /* Set up true and false rtx's */
4357 true_rtx
= rtx_alloc (CONST_INT
);
4358 XWINT (true_rtx
, 0) = 1;
4359 false_rtx
= rtx_alloc (CONST_INT
);
4360 XWINT (false_rtx
, 0) = 0;
4361 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4362 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4364 alternative_name
= DEF_ATTR_STRING ("alternative");
4365 length_str
= DEF_ATTR_STRING ("length");
4366 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4367 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4368 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4370 printf ("/* Generated automatically by the program `genattrtab'\n\
4371 from the machine description file `md'. */\n\n");
4373 /* Read the machine description. */
4375 initiate_automaton_gen (argc
, argv
);
4380 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4384 switch (GET_CODE (desc
))
4387 case DEFINE_PEEPHOLE
:
4388 case DEFINE_ASM_ATTRIBUTES
:
4389 gen_insn (desc
, lineno
);
4393 gen_attr (desc
, lineno
);
4397 gen_delay (desc
, lineno
);
4400 case DEFINE_CPU_UNIT
:
4401 gen_cpu_unit (desc
);
4404 case DEFINE_QUERY_CPU_UNIT
:
4405 gen_query_cpu_unit (desc
);
4413 gen_excl_set (desc
);
4417 gen_presence_set (desc
);
4420 case FINAL_PRESENCE_SET
:
4421 gen_final_presence_set (desc
);
4425 gen_absence_set (desc
);
4428 case FINAL_ABSENCE_SET
:
4429 gen_final_absence_set (desc
);
4432 case DEFINE_AUTOMATON
:
4433 gen_automaton (desc
);
4436 case AUTOMATA_OPTION
:
4437 gen_automata_option (desc
);
4440 case DEFINE_RESERVATION
:
4444 case DEFINE_INSN_RESERVATION
:
4445 gen_insn_reserv (desc
);
4451 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4452 insn_index_number
++;
4456 return FATAL_EXIT_CODE
;
4460 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4461 if (! got_define_asm_attributes
)
4463 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4464 XVEC (tem
, 0) = rtvec_alloc (0);
4468 /* Expand DEFINE_DELAY information into new attribute. */
4472 /* Build DFA, output some functions and expand DFA information
4473 to new attributes. */
4477 printf ("#include \"config.h\"\n");
4478 printf ("#include \"system.h\"\n");
4479 printf ("#include \"coretypes.h\"\n");
4480 printf ("#include \"tm.h\"\n");
4481 printf ("#include \"rtl.h\"\n");
4482 printf ("#include \"tm_p.h\"\n");
4483 printf ("#include \"insn-config.h\"\n");
4484 printf ("#include \"recog.h\"\n");
4485 printf ("#include \"regs.h\"\n");
4486 printf ("#include \"real.h\"\n");
4487 printf ("#include \"output.h\"\n");
4488 printf ("#include \"insn-attr.h\"\n");
4489 printf ("#include \"toplev.h\"\n");
4490 printf ("#include \"flags.h\"\n");
4491 printf ("#include \"function.h\"\n");
4493 printf ("#define operands recog_data.operand\n\n");
4495 /* Make `insn_alternatives'. */
4496 insn_alternatives
= oballoc (insn_code_number
* sizeof (int));
4497 for (id
= defs
; id
; id
= id
->next
)
4498 if (id
->insn_code
>= 0)
4499 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4501 /* Make `insn_n_alternatives'. */
4502 insn_n_alternatives
= oballoc (insn_code_number
* sizeof (int));
4503 for (id
= defs
; id
; id
= id
->next
)
4504 if (id
->insn_code
>= 0)
4505 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4507 /* Prepare to write out attribute subroutines by checking everything stored
4508 away and building the attribute cases. */
4512 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4513 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4514 attr
->default_val
->value
4515 = check_attr_value (attr
->default_val
->value
, attr
);
4518 return FATAL_EXIT_CODE
;
4520 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4521 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4524 /* Construct extra attributes for `length'. */
4525 make_length_attrs ();
4527 /* Perform any possible optimizations to speed up compilation. */
4530 /* Now write out all the `gen_attr_...' routines. Do these before the
4531 special routines so that they get defined before they are used. */
4533 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4534 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4536 if (! attr
->is_special
&& ! attr
->is_const
)
4541 = (attr
->name
[0] == '*'
4542 && strcmp (&attr
->name
[1], INSN_ALTS_FUNC_NAME
) == 0);
4544 printf ("\n#if AUTOMATON_ALTS\n");
4545 write_attr_get (attr
);
4547 printf ("#endif\n\n");
4551 /* Write out delay eligibility information, if DEFINE_DELAY present.
4552 (The function to compute the number of delay slots will be written
4556 write_eligible_delay ("delay");
4557 if (have_annul_true
)
4558 write_eligible_delay ("annul_true");
4559 if (have_annul_false
)
4560 write_eligible_delay ("annul_false");
4563 /* Output code for pipeline hazards recognition based on DFA
4564 (deterministic finite-state automata). */
4568 /* Write out constant delay slot info. */
4569 write_const_num_delay_slots ();
4571 write_length_unit_log ();
4574 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);
4577 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
4579 get_insn_name (int code ATTRIBUTE_UNUSED
)