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 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, 59 Temple Place - Suite 330, 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
94 `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
95 EQ_ATTR rtx is true if !volatil and false if volatil. */
97 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
98 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
99 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
100 #define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
103 #define strcmp_check(S1, S2) ((S1) == (S2) \
105 : (strcmp ((S1), (S2)) \
109 #define strcmp_check(S1, S2) ((S1) != (S2))
114 #include "coretypes.h"
118 #include "gensupport.h"
120 #ifdef HAVE_SYS_RESOURCE_H
121 # include <sys/resource.h>
124 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
125 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
129 #include "genattrtab.h"
131 static struct obstack obstack1
, obstack2
;
132 struct obstack
*hash_obstack
= &obstack1
;
133 struct obstack
*temp_obstack
= &obstack2
;
135 /* enough space to reserve for printing out ints */
136 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
138 /* Define structures used to record attributes and values. */
140 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
141 encountered, we store all the relevant information into a
142 `struct insn_def'. This is done to allow attribute definitions to occur
143 anywhere in the file. */
147 struct insn_def
*next
; /* Next insn in chain. */
148 rtx def
; /* The DEFINE_... */
149 int insn_code
; /* Instruction number. */
150 int insn_index
; /* Expression numer in file, for errors. */
151 int lineno
; /* Line number. */
152 int num_alternatives
; /* Number of alternatives. */
153 int vec_idx
; /* Index of attribute vector in `def'. */
156 /* Once everything has been read in, we store in each attribute value a list
157 of insn codes that have that value. Here is the structure used for the
162 struct insn_ent
*next
; /* Next in chain. */
163 int insn_code
; /* Instruction number. */
164 int insn_index
; /* Index of definition in file */
165 int lineno
; /* Line number. */
168 /* Each value of an attribute (either constant or computed) is assigned a
169 structure which is used as the listhead of the insns that have that
174 rtx value
; /* Value of attribute. */
175 struct attr_value
*next
; /* Next attribute value in chain. */
176 struct insn_ent
*first_insn
; /* First insn with this value. */
177 int num_insns
; /* Number of insns with this value. */
178 int has_asm_insn
; /* True if this value used for `asm' insns */
181 /* Structure for each attribute. */
185 char *name
; /* Name of attribute. */
186 struct attr_desc
*next
; /* Next attribute. */
187 struct attr_value
*first_value
; /* First value of this attribute. */
188 struct attr_value
*default_val
; /* Default value for this attribute. */
189 int lineno
: 24; /* Line number. */
190 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
191 unsigned negative_ok
: 1; /* Allow negative numeric values. */
192 unsigned unsigned_p
: 1; /* Make the output function unsigned int. */
193 unsigned is_const
: 1; /* Attribute value constant for each run. */
194 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
195 unsigned static_p
: 1; /* Make the output function static. */
198 #define NULL_ATTR (struct attr_desc *) NULL
200 /* Structure for each DEFINE_DELAY. */
204 rtx def
; /* DEFINE_DELAY expression. */
205 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
206 int num
; /* Number of DEFINE_DELAY, starting at 1. */
207 int lineno
; /* Line number. */
210 /* Listheads of above structures. */
212 /* This one is indexed by the first character of the attribute name. */
213 #define MAX_ATTRS_INDEX 256
214 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
215 static struct insn_def
*defs
;
216 static struct delay_desc
*delays
;
218 /* Other variables. */
220 static int insn_code_number
;
221 static int insn_index_number
;
222 static int got_define_asm_attributes
;
223 static int must_extract
;
224 static int must_constrain
;
225 static int address_used
;
226 static int length_used
;
227 static int num_delays
;
228 static int have_annul_true
, have_annul_false
;
229 static int num_insn_ents
;
233 /* Stores, for each insn code, the number of constraint alternatives. */
235 static int *insn_n_alternatives
;
237 /* Stores, for each insn code, a bitmap that has bits on for each possible
240 static int *insn_alternatives
;
242 /* If nonzero, assume that the `alternative' attr has this value.
243 This is the hashed, unique string for the numeral
244 whose value is chosen alternative. */
246 static const char *current_alternative_string
;
248 /* Used to simplify expressions. */
250 static rtx true_rtx
, false_rtx
;
252 /* Used to reduce calls to `strcmp' */
254 static char *alternative_name
;
255 static const char *length_str
;
256 static const char *delay_type_str
;
257 static const char *delay_1_0_str
;
258 static const char *num_delay_slots_str
;
260 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
263 int reload_completed
= 0;
265 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
266 to define it here. */
270 /* Simplify an expression. Only call the routine if there is something to
272 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
273 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
274 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
276 /* Simplify (eq_attr ("alternative") ...)
277 when we are working with a particular alternative. */
278 #define SIMPLIFY_ALTERNATIVE(EXP) \
279 if (current_alternative_string \
280 && GET_CODE ((EXP)) == EQ_ATTR \
281 && XSTR ((EXP), 0) == alternative_name) \
282 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
283 ? true_rtx : false_rtx);
285 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
287 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
288 They won't actually be used. */
290 rtx global_rtl
[GR_MAX
];
291 rtx pic_offset_table_rtx
;
293 static void attr_hash_add_rtx (int, rtx
);
294 static void attr_hash_add_string (int, char *);
295 static rtx
attr_rtx (enum rtx_code
, ...);
296 static rtx
attr_rtx_1 (enum rtx_code
, va_list);
297 static char *attr_string (const char *, int);
298 static rtx
check_attr_value (rtx
, struct attr_desc
*);
299 static rtx
convert_set_attr_alternative (rtx
, struct insn_def
*);
300 static rtx
convert_set_attr (rtx
, struct insn_def
*);
301 static void check_defs (void);
302 static rtx
make_canonical (struct attr_desc
*, rtx
);
303 static struct attr_value
*get_attr_value (rtx
, struct attr_desc
*, int);
304 static rtx
copy_rtx_unchanging (rtx
);
305 static rtx
copy_boolean (rtx
);
306 static void expand_delays (void);
307 static void fill_attr (struct attr_desc
*);
308 static rtx
substitute_address (rtx
, rtx (*) (rtx
), rtx (*) (rtx
));
309 static void make_length_attrs (void);
310 static rtx
identity_fn (rtx
);
311 static rtx
zero_fn (rtx
);
312 static rtx
one_fn (rtx
);
313 static rtx
max_fn (rtx
);
314 static void write_length_unit_log (void);
315 static rtx
simplify_cond (rtx
, int, int);
316 static void clear_struct_flag (rtx
);
317 static void remove_insn_ent (struct attr_value
*, struct insn_ent
*);
318 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
319 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
320 static rtx
make_alternative_compare (int);
321 static int compute_alternative_mask (rtx
, enum rtx_code
);
322 static rtx
evaluate_eq_attr (rtx
, rtx
, int, int);
323 static rtx
simplify_and_tree (rtx
, rtx
*, int, int);
324 static rtx
simplify_or_tree (rtx
, rtx
*, int, int);
325 static rtx
simplify_test_exp (rtx
, int, int);
326 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
327 static void optimize_attrs (void);
328 static void gen_attr (rtx
, int);
329 static int count_alternatives (rtx
);
330 static int compares_alternatives_p (rtx
);
331 static int contained_in_p (rtx
, rtx
);
332 static void gen_insn (rtx
, int);
333 static void gen_delay (rtx
, int);
334 static void write_test_expr (rtx
, int);
335 static int max_attr_value (rtx
, int*);
336 static int or_attr_value (rtx
, int*);
337 static void walk_attr_value (rtx
);
338 static void write_attr_get (struct attr_desc
*);
339 static rtx
eliminate_known_true (rtx
, rtx
, int, int);
340 static void write_attr_set (struct attr_desc
*, int, rtx
,
341 const char *, const char *, rtx
,
343 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
344 int, const char *, const char *, int, rtx
);
345 static void write_attr_valueq (struct attr_desc
*, const char *);
346 static void write_attr_value (struct attr_desc
*, rtx
);
347 static void write_upcase (const char *);
348 static void write_indent (int);
349 static void write_eligible_delay (const char *);
350 static int write_expr_attr_cache (rtx
, struct attr_desc
*);
351 static void write_const_num_delay_slots (void);
352 static char *next_comma_elt (const char **);
353 static struct attr_desc
*find_attr (const char **, int);
354 static struct attr_value
*find_most_used (struct attr_desc
*);
355 static rtx
attr_eq (const char *, const char *);
356 static const char *attr_numeral (int);
357 static int attr_equal_p (rtx
, rtx
);
358 static rtx
attr_copy_rtx (rtx
);
359 static int attr_rtx_cost (rtx
);
360 static bool attr_alt_subset_p (rtx
, rtx
);
361 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
362 static rtx
attr_alt_intersection (rtx
, rtx
);
363 static rtx
attr_alt_union (rtx
, rtx
);
364 static rtx
attr_alt_complement (rtx
);
365 static bool attr_alt_bit_p (rtx
, int);
366 static rtx
mk_attr_alt (int);
368 #define oballoc(size) obstack_alloc (hash_obstack, size)
370 /* Hash table for sharing RTL and strings. */
372 /* Each hash table slot is a bucket containing a chain of these structures.
373 Strings are given negative hash codes; RTL expressions are given positive
378 struct attr_hash
*next
; /* Next structure in the bucket. */
379 int hashcode
; /* Hash code of this rtx or string. */
382 char *str
; /* The string (negative hash codes) */
383 rtx rtl
; /* or the RTL recorded here. */
387 /* Now here is the hash table. When recording an RTL, it is added to
388 the slot whose index is the hash code mod the table size. Note
389 that the hash table is used for several kinds of RTL (see attr_rtx)
390 and for strings. While all these live in the same table, they are
391 completely independent, and the hash code is computed differently
394 #define RTL_HASH_SIZE 4093
395 struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
397 /* Here is how primitive or already-shared RTL's hash
399 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
401 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
404 attr_hash_add_rtx (int hashcode
, rtx rtl
)
408 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
409 h
->hashcode
= hashcode
;
411 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
412 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
415 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
418 attr_hash_add_string (int hashcode
, char *str
)
422 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
423 h
->hashcode
= -hashcode
;
425 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
426 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
429 /* Generate an RTL expression, but avoid duplicates.
430 Set the ATTR_PERMANENT_P flag for these permanent objects.
432 In some cases we cannot uniquify; then we return an ordinary
433 impermanent rtx with ATTR_PERMANENT_P clear.
437 rtx attr_rtx (code, [element1, ..., elementn]) */
440 attr_rtx_1 (enum rtx_code code
, va_list p
)
442 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
445 struct obstack
*old_obstack
= rtl_obstack
;
447 /* For each of several cases, search the hash table for an existing entry.
448 Use that entry if one is found; otherwise create a new RTL and add it
451 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
453 rtx arg0
= va_arg (p
, rtx
);
455 /* A permanent object cannot point to impermanent ones. */
456 if (! ATTR_PERMANENT_P (arg0
))
458 rt_val
= rtx_alloc (code
);
459 XEXP (rt_val
, 0) = arg0
;
463 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
464 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
465 if (h
->hashcode
== hashcode
466 && GET_CODE (h
->u
.rtl
) == code
467 && XEXP (h
->u
.rtl
, 0) == arg0
)
472 rtl_obstack
= hash_obstack
;
473 rt_val
= rtx_alloc (code
);
474 XEXP (rt_val
, 0) = arg0
;
477 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
478 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
479 || GET_RTX_CLASS (code
) == RTX_COMPARE
480 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
482 rtx arg0
= va_arg (p
, rtx
);
483 rtx arg1
= va_arg (p
, rtx
);
485 /* A permanent object cannot point to impermanent ones. */
486 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
488 rt_val
= rtx_alloc (code
);
489 XEXP (rt_val
, 0) = arg0
;
490 XEXP (rt_val
, 1) = arg1
;
494 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
495 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
496 if (h
->hashcode
== hashcode
497 && GET_CODE (h
->u
.rtl
) == code
498 && XEXP (h
->u
.rtl
, 0) == arg0
499 && XEXP (h
->u
.rtl
, 1) == arg1
)
504 rtl_obstack
= hash_obstack
;
505 rt_val
= rtx_alloc (code
);
506 XEXP (rt_val
, 0) = arg0
;
507 XEXP (rt_val
, 1) = arg1
;
510 else if (GET_RTX_LENGTH (code
) == 1
511 && GET_RTX_FORMAT (code
)[0] == 's')
513 char *arg0
= va_arg (p
, char *);
515 arg0
= DEF_ATTR_STRING (arg0
);
517 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
518 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
519 if (h
->hashcode
== hashcode
520 && GET_CODE (h
->u
.rtl
) == code
521 && XSTR (h
->u
.rtl
, 0) == arg0
)
526 rtl_obstack
= hash_obstack
;
527 rt_val
= rtx_alloc (code
);
528 XSTR (rt_val
, 0) = arg0
;
531 else if (GET_RTX_LENGTH (code
) == 2
532 && GET_RTX_FORMAT (code
)[0] == 's'
533 && GET_RTX_FORMAT (code
)[1] == 's')
535 char *arg0
= va_arg (p
, char *);
536 char *arg1
= va_arg (p
, char *);
538 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
539 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
540 if (h
->hashcode
== hashcode
541 && GET_CODE (h
->u
.rtl
) == code
542 && XSTR (h
->u
.rtl
, 0) == arg0
543 && XSTR (h
->u
.rtl
, 1) == arg1
)
548 rtl_obstack
= hash_obstack
;
549 rt_val
= rtx_alloc (code
);
550 XSTR (rt_val
, 0) = arg0
;
551 XSTR (rt_val
, 1) = arg1
;
554 else if (code
== CONST_INT
)
556 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
566 int i
; /* Array indices... */
567 const char *fmt
; /* Current rtx's format... */
569 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
571 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
572 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
576 case '0': /* Unused field. */
579 case 'i': /* An integer? */
580 XINT (rt_val
, i
) = va_arg (p
, int);
583 case 'w': /* A wide integer? */
584 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
587 case 's': /* A string? */
588 XSTR (rt_val
, i
) = va_arg (p
, char *);
591 case 'e': /* An expression? */
592 case 'u': /* An insn? Same except when printing. */
593 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
596 case 'E': /* An RTX vector? */
597 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
607 rtl_obstack
= old_obstack
;
608 attr_hash_add_rtx (hashcode
, rt_val
);
609 ATTR_PERMANENT_P (rt_val
) = 1;
614 attr_rtx (enum rtx_code code
, ...)
620 result
= attr_rtx_1 (code
, p
);
625 /* Create a new string printed with the printf line arguments into a space
626 of at most LEN bytes:
628 rtx attr_printf (len, format, [arg1, ..., argn]) */
631 attr_printf (unsigned int len
, const char *fmt
, ...)
638 if (len
> sizeof str
- 1) /* Leave room for \0. */
641 vsprintf (str
, fmt
, p
);
644 return DEF_ATTR_STRING (str
);
648 attr_eq (const char *name
, const char *value
)
650 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
656 return XSTR (make_numeric_value (n
), 0);
659 /* Return a permanent (possibly shared) copy of a string STR (not assumed
660 to be null terminated) with LEN bytes. */
663 attr_string (const char *str
, int len
)
670 /* Compute the hash code. */
671 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
672 for (i
= 1; i
<= len
; i
+= 2)
673 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
675 hashcode
= -hashcode
;
677 /* Search the table for the string. */
678 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
679 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
680 && !strncmp (h
->u
.str
, str
, len
))
681 return h
->u
.str
; /* <-- return if found. */
683 /* Not found; create a permanent copy and add it to the hash table. */
684 new_str
= obstack_alloc (hash_obstack
, len
+ 1);
685 memcpy (new_str
, str
, len
);
687 attr_hash_add_string (hashcode
, new_str
);
689 return new_str
; /* Return the new string. */
692 /* Check two rtx's for equality of contents,
693 taking advantage of the fact that if both are hashed
694 then they can't be equal unless they are the same object. */
697 attr_equal_p (rtx x
, rtx y
)
699 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
700 && rtx_equal_p (x
, y
)));
703 /* Copy an attribute value expression,
704 descending to all depths, but not copying any
705 permanent hashed subexpressions. */
708 attr_copy_rtx (rtx orig
)
713 const char *format_ptr
;
715 /* No need to copy a permanent object. */
716 if (ATTR_PERMANENT_P (orig
))
719 code
= GET_CODE (orig
);
737 copy
= rtx_alloc (code
);
738 PUT_MODE (copy
, GET_MODE (orig
));
739 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
740 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
741 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
742 ATTR_EQ_ATTR_P (copy
) = ATTR_EQ_ATTR_P (orig
);
744 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
746 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
748 switch (*format_ptr
++)
751 XEXP (copy
, i
) = XEXP (orig
, i
);
752 if (XEXP (orig
, i
) != NULL
)
753 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
758 XVEC (copy
, i
) = XVEC (orig
, i
);
759 if (XVEC (orig
, i
) != NULL
)
761 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
762 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
763 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
769 XINT (copy
, i
) = XINT (orig
, i
);
773 XWINT (copy
, i
) = XWINT (orig
, i
);
778 XSTR (copy
, i
) = XSTR (orig
, i
);
788 /* Given a test expression for an attribute, ensure it is validly formed.
789 IS_CONST indicates whether the expression is constant for each compiler
790 run (a constant expression may not test any particular insn).
792 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
793 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
794 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
796 Update the string address in EQ_ATTR expression to be the same used
797 in the attribute (or `alternative_name') to speed up subsequent
798 `find_attr' calls and eliminate most `strcmp' calls.
800 Return the new expression, if any. */
803 check_attr_test (rtx exp
, int is_const
, int lineno
)
805 struct attr_desc
*attr
;
806 struct attr_value
*av
;
807 const char *name_ptr
, *p
;
810 switch (GET_CODE (exp
))
813 /* Handle negation test. */
814 if (XSTR (exp
, 1)[0] == '!')
815 return check_attr_test (attr_rtx (NOT
,
816 attr_eq (XSTR (exp
, 0),
820 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
822 attr
= find_attr (&XSTR (exp
, 0), 0);
825 if (! strcmp (XSTR (exp
, 0), "alternative"))
826 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
828 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
831 if (is_const
&& ! attr
->is_const
)
832 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
835 /* Copy this just to make it permanent,
836 so expressions using it can be permanent too. */
837 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
839 /* It shouldn't be possible to simplify the value given to a
840 constant attribute, so don't expand this until it's time to
841 write the test expression. */
843 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
845 if (attr
->is_numeric
)
847 for (p
= XSTR (exp
, 1); *p
; p
++)
849 fatal ("attribute `%s' takes only numeric values",
854 for (av
= attr
->first_value
; av
; av
= av
->next
)
855 if (GET_CODE (av
->value
) == CONST_STRING
856 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
860 fatal ("unknown value `%s' for `%s' attribute",
861 XSTR (exp
, 1), XSTR (exp
, 0));
866 if (! strcmp (XSTR (exp
, 0), "alternative"))
870 name_ptr
= XSTR (exp
, 1);
871 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
872 set
|= 1 << atoi (p
);
874 return mk_attr_alt (set
);
878 /* Make an IOR tree of the possible values. */
880 name_ptr
= XSTR (exp
, 1);
881 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
883 newexp
= attr_eq (XSTR (exp
, 0), p
);
884 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
887 return check_attr_test (orexp
, is_const
, lineno
);
896 /* Either TRUE or FALSE. */
904 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
905 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
909 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
914 fatal ("RTL operator \"%s\" not valid in constant attribute test",
915 GET_RTX_NAME (GET_CODE (exp
)));
916 /* These cases can't be simplified. */
917 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
920 case LE
: case LT
: case GT
: case GE
:
921 case LEU
: case LTU
: case GTU
: case GEU
:
923 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
924 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
925 exp
= attr_rtx (GET_CODE (exp
),
926 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
927 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
928 /* These cases can't be simplified. */
929 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
935 /* These cases are valid for constant attributes, but can't be
937 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
938 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
942 fatal ("RTL operator \"%s\" not valid in attribute test",
943 GET_RTX_NAME (GET_CODE (exp
)));
949 /* Given an expression, ensure that it is validly formed and that all named
950 attribute values are valid for the given attribute. Issue a fatal error
951 if not. If no attribute is specified, assume a numeric attribute.
953 Return a perhaps modified replacement expression for the value. */
956 check_attr_value (rtx exp
, struct attr_desc
*attr
)
958 struct attr_value
*av
;
962 switch (GET_CODE (exp
))
965 if (attr
&& ! attr
->is_numeric
)
967 message_with_line (attr
->lineno
,
968 "CONST_INT not valid for non-numeric attribute %s",
974 if (INTVAL (exp
) < 0 && ! attr
->negative_ok
)
976 message_with_line (attr
->lineno
,
977 "negative numeric value specified for attribute %s",
985 if (! strcmp (XSTR (exp
, 0), "*"))
988 if (attr
== 0 || attr
->is_numeric
)
991 if (attr
&& attr
->negative_ok
&& *p
== '-')
996 message_with_line (attr
? attr
->lineno
: 0,
997 "non-numeric value for numeric attribute %s",
998 attr
? attr
->name
: "internal");
1005 for (av
= attr
->first_value
; av
; av
= av
->next
)
1006 if (GET_CODE (av
->value
) == CONST_STRING
1007 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
1012 message_with_line (attr
->lineno
,
1013 "unknown value `%s' for `%s' attribute",
1014 XSTR (exp
, 0), attr
? attr
->name
: "internal");
1020 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
1021 attr
? attr
->is_const
: 0,
1022 attr
? attr
->lineno
: 0);
1023 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1024 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
1032 if (attr
&& !attr
->is_numeric
)
1034 message_with_line (attr
->lineno
,
1035 "invalid operation `%s' for non-numeric attribute value",
1036 GET_RTX_NAME (GET_CODE (exp
)));
1044 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1045 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1053 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1057 if (XVECLEN (exp
, 0) % 2 != 0)
1059 message_with_line (attr
->lineno
,
1060 "first operand of COND must have even length");
1065 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1067 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1068 attr
? attr
->is_const
: 0,
1069 attr
? attr
->lineno
: 0);
1070 XVECEXP (exp
, 0, i
+ 1)
1071 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1074 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1079 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1082 message_with_line (attr
? attr
->lineno
: 0,
1083 "unknown attribute `%s' in ATTR",
1087 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1089 message_with_line (attr
->lineno
,
1090 "non-constant attribute `%s' referenced from `%s'",
1091 XSTR (exp
, 0), attr
->name
);
1095 && (attr
->is_numeric
!= attr2
->is_numeric
1096 || (! attr
->negative_ok
&& attr2
->negative_ok
)))
1098 message_with_line (attr
->lineno
,
1099 "numeric attribute mismatch calling `%s' from `%s'",
1100 XSTR (exp
, 0), attr
->name
);
1107 /* A constant SYMBOL_REF is valid as a constant attribute test and
1108 is expanded later by make_canonical into a COND. In a non-constant
1109 attribute test, it is left be. */
1110 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1113 message_with_line (attr
? attr
->lineno
: 0,
1114 "invalid operation `%s' for attribute value",
1115 GET_RTX_NAME (GET_CODE (exp
)));
1123 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1124 It becomes a COND with each test being (eq_attr "alternative "n") */
1127 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1129 int num_alt
= id
->num_alternatives
;
1133 if (XVECLEN (exp
, 1) != num_alt
)
1135 message_with_line (id
->lineno
,
1136 "bad number of entries in SET_ATTR_ALTERNATIVE");
1141 /* Make a COND with all tests but the last. Select the last value via the
1143 condexp
= rtx_alloc (COND
);
1144 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1146 for (i
= 0; i
< num_alt
- 1; i
++)
1149 p
= attr_numeral (i
);
1151 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1152 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1155 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1157 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1160 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1161 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1164 convert_set_attr (rtx exp
, struct insn_def
*id
)
1167 const char *name_ptr
;
1171 /* See how many alternative specified. */
1172 n
= n_comma_elts (XSTR (exp
, 1));
1174 return attr_rtx (SET
,
1175 attr_rtx (ATTR
, XSTR (exp
, 0)),
1176 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1178 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1179 XSTR (newexp
, 0) = XSTR (exp
, 0);
1180 XVEC (newexp
, 1) = rtvec_alloc (n
);
1182 /* Process each comma-separated name. */
1183 name_ptr
= XSTR (exp
, 1);
1185 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1186 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1188 return convert_set_attr_alternative (newexp
, id
);
1191 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1192 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1198 struct insn_def
*id
;
1199 struct attr_desc
*attr
;
1203 for (id
= defs
; id
; id
= id
->next
)
1205 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1208 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1210 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1211 switch (GET_CODE (value
))
1214 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1216 message_with_line (id
->lineno
, "bad attribute set");
1222 case SET_ATTR_ALTERNATIVE
:
1223 value
= convert_set_attr_alternative (value
, id
);
1227 value
= convert_set_attr (value
, id
);
1231 message_with_line (id
->lineno
, "invalid attribute code %s",
1232 GET_RTX_NAME (GET_CODE (value
)));
1236 if (value
== NULL_RTX
)
1239 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1241 message_with_line (id
->lineno
, "unknown attribute %s",
1242 XSTR (XEXP (value
, 0), 0));
1247 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1248 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1253 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1254 expressions by converting them into a COND. This removes cases from this
1255 program. Also, replace an attribute value of "*" with the default attribute
1259 make_canonical (struct attr_desc
*attr
, rtx exp
)
1264 switch (GET_CODE (exp
))
1267 exp
= make_numeric_value (INTVAL (exp
));
1271 if (! strcmp (XSTR (exp
, 0), "*"))
1273 if (attr
== 0 || attr
->default_val
== 0)
1274 fatal ("(attr_value \"*\") used in invalid context");
1275 exp
= attr
->default_val
->value
;
1278 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1283 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1285 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1286 This makes the COND something that won't be considered an arbitrary
1287 expression by walk_attr_value. */
1288 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1289 exp
= check_attr_value (exp
, attr
);
1293 newexp
= rtx_alloc (COND
);
1294 XVEC (newexp
, 0) = rtvec_alloc (2);
1295 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1296 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1298 XEXP (newexp
, 1) = XEXP (exp
, 2);
1301 /* Fall through to COND case since this is now a COND. */
1308 /* First, check for degenerate COND. */
1309 if (XVECLEN (exp
, 0) == 0)
1310 return make_canonical (attr
, XEXP (exp
, 1));
1311 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1313 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1315 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1316 XVECEXP (exp
, 0, i
+ 1)
1317 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1318 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1334 copy_boolean (rtx exp
)
1336 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1337 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1338 copy_boolean (XEXP (exp
, 1)));
1339 if (GET_CODE (exp
) == MATCH_OPERAND
)
1341 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1342 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1344 else if (GET_CODE (exp
) == EQ_ATTR
)
1346 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1347 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1353 /* Given a value and an attribute description, return a `struct attr_value *'
1354 that represents that value. This is either an existing structure, if the
1355 value has been previously encountered, or a newly-created structure.
1357 `insn_code' is the code of an insn whose attribute has the specified
1358 value (-2 if not processing an insn). We ensure that all insns for
1359 a given value have the same number of alternatives if the value checks
1362 static struct attr_value
*
1363 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1365 struct attr_value
*av
;
1368 value
= make_canonical (attr
, value
);
1369 if (compares_alternatives_p (value
))
1371 if (insn_code
< 0 || insn_alternatives
== NULL
)
1372 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1374 num_alt
= insn_alternatives
[insn_code
];
1377 for (av
= attr
->first_value
; av
; av
= av
->next
)
1378 if (rtx_equal_p (value
, av
->value
)
1379 && (num_alt
== 0 || av
->first_insn
== NULL
1380 || insn_alternatives
[av
->first_insn
->insn_code
]))
1383 av
= oballoc (sizeof (struct attr_value
));
1385 av
->next
= attr
->first_value
;
1386 attr
->first_value
= av
;
1387 av
->first_insn
= NULL
;
1389 av
->has_asm_insn
= 0;
1394 /* After all DEFINE_DELAYs have been read in, create internal attributes
1395 to generate the required routines.
1397 First, we compute the number of delay slots for each insn (as a COND of
1398 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1399 delay type is specified, we compute a similar function giving the
1400 DEFINE_DELAY ordinal for each insn.
1402 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1403 tells whether a given insn can be in that delay slot.
1405 Normal attribute filling and optimization expands these to contain the
1406 information needed to handle delay slots. */
1409 expand_delays (void)
1411 struct delay_desc
*delay
;
1417 /* First, generate data for `num_delay_slots' function. */
1419 condexp
= rtx_alloc (COND
);
1420 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1421 XEXP (condexp
, 1) = make_numeric_value (0);
1423 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1425 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1426 XVECEXP (condexp
, 0, i
+ 1)
1427 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1430 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1432 /* If more than one delay type, do the same for computing the delay type. */
1435 condexp
= rtx_alloc (COND
);
1436 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1437 XEXP (condexp
, 1) = make_numeric_value (0);
1439 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1441 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1442 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1445 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1448 /* For each delay possibility and delay slot, compute an eligibility
1449 attribute for non-annulled insns and for each type of annulled (annul
1450 if true and annul if false). */
1451 for (delay
= delays
; delay
; delay
= delay
->next
)
1453 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1455 condexp
= XVECEXP (delay
->def
, 1, i
);
1457 condexp
= false_rtx
;
1458 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1459 make_numeric_value (1), make_numeric_value (0));
1461 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1462 "*delay_%d_%d", delay
->num
, i
/ 3);
1463 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1465 if (have_annul_true
)
1467 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1468 if (condexp
== 0) condexp
= false_rtx
;
1469 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1470 make_numeric_value (1),
1471 make_numeric_value (0));
1472 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1473 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1474 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1477 if (have_annul_false
)
1479 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1480 if (condexp
== 0) condexp
= false_rtx
;
1481 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1482 make_numeric_value (1),
1483 make_numeric_value (0));
1484 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1485 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1486 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1492 /* Once all attributes and insns have been read and checked, we construct for
1493 each attribute value a list of all the insns that have that value for
1497 fill_attr (struct attr_desc
*attr
)
1499 struct attr_value
*av
;
1500 struct insn_ent
*ie
;
1501 struct insn_def
*id
;
1505 /* Don't fill constant attributes. The value is independent of
1506 any particular insn. */
1510 for (id
= defs
; id
; id
= id
->next
)
1512 /* If no value is specified for this insn for this attribute, use the
1515 if (XVEC (id
->def
, id
->vec_idx
))
1516 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1517 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1519 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1522 av
= attr
->default_val
;
1524 av
= get_attr_value (value
, attr
, id
->insn_code
);
1526 ie
= oballoc (sizeof (struct insn_ent
));
1527 ie
->insn_code
= id
->insn_code
;
1528 ie
->insn_index
= id
->insn_code
;
1529 insert_insn_ent (av
, ie
);
1533 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1534 test that checks relative positions of insns (uses MATCH_DUP or PC).
1535 If so, replace it with what is obtained by passing the expression to
1536 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1537 recursively on each value (including the default value). Otherwise,
1538 return the value returned by NO_ADDRESS_FN applied to EXP. */
1541 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1542 rtx (*address_fn
) (rtx
))
1547 if (GET_CODE (exp
) == COND
)
1549 /* See if any tests use addresses. */
1551 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1552 walk_attr_value (XVECEXP (exp
, 0, i
));
1555 return (*address_fn
) (exp
);
1557 /* Make a new copy of this COND, replacing each element. */
1558 newexp
= rtx_alloc (COND
);
1559 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1560 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1562 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1563 XVECEXP (newexp
, 0, i
+ 1)
1564 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1565 no_address_fn
, address_fn
);
1568 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1569 no_address_fn
, address_fn
);
1574 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1577 walk_attr_value (XEXP (exp
, 0));
1579 return (*address_fn
) (exp
);
1581 return attr_rtx (IF_THEN_ELSE
,
1582 substitute_address (XEXP (exp
, 0),
1583 no_address_fn
, address_fn
),
1584 substitute_address (XEXP (exp
, 1),
1585 no_address_fn
, address_fn
),
1586 substitute_address (XEXP (exp
, 2),
1587 no_address_fn
, address_fn
));
1590 return (*no_address_fn
) (exp
);
1593 /* Make new attributes from the `length' attribute. The following are made,
1594 each corresponding to a function called from `shorten_branches' or
1597 *insn_default_length This is the length of the insn to be returned
1598 by `get_attr_length' before `shorten_branches'
1599 has been called. In each case where the length
1600 depends on relative addresses, the largest
1601 possible is used. This routine is also used
1602 to compute the initial size of the insn.
1604 *insn_variable_length_p This returns 1 if the insn's length depends
1605 on relative addresses, zero otherwise.
1607 *insn_current_length This is only called when it is known that the
1608 insn has a variable length and returns the
1609 current length, based on relative addresses.
1613 make_length_attrs (void)
1615 static const char *new_names
[] =
1617 "*insn_default_length",
1618 "*insn_variable_length_p",
1619 "*insn_current_length"
1621 static rtx (*const no_address_fn
[]) (rtx
) = {identity_fn
, zero_fn
, zero_fn
};
1622 static rtx (*const address_fn
[]) (rtx
) = {max_fn
, one_fn
, identity_fn
};
1624 struct attr_desc
*length_attr
, *new_attr
;
1625 struct attr_value
*av
, *new_av
;
1626 struct insn_ent
*ie
, *new_ie
;
1628 /* See if length attribute is defined. If so, it must be numeric. Make
1629 it special so we don't output anything for it. */
1630 length_attr
= find_attr (&length_str
, 0);
1631 if (length_attr
== 0)
1634 if (! length_attr
->is_numeric
)
1635 fatal ("length attribute must be numeric");
1637 length_attr
->is_const
= 0;
1638 length_attr
->is_special
= 1;
1640 /* Make each new attribute, in turn. */
1641 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1643 make_internal_attr (new_names
[i
],
1644 substitute_address (length_attr
->default_val
->value
,
1645 no_address_fn
[i
], address_fn
[i
]),
1647 new_attr
= find_attr (&new_names
[i
], 0);
1648 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1649 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1651 new_av
= get_attr_value (substitute_address (av
->value
,
1654 new_attr
, ie
->insn_code
);
1655 new_ie
= oballoc (sizeof (struct insn_ent
));
1656 new_ie
->insn_code
= ie
->insn_code
;
1657 new_ie
->insn_index
= ie
->insn_index
;
1658 insert_insn_ent (new_av
, new_ie
);
1663 /* Utility functions called from above routine. */
1666 identity_fn (rtx exp
)
1672 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1674 return make_numeric_value (0);
1678 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1680 return make_numeric_value (1);
1687 return make_numeric_value (max_attr_value (exp
, &unknown
));
1691 write_length_unit_log (void)
1693 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1694 struct attr_value
*av
;
1695 struct insn_ent
*ie
;
1696 unsigned int length_unit_log
, length_or
;
1699 if (length_attr
== 0)
1701 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1702 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1703 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1704 length_or
|= or_attr_value (av
->value
, &unknown
);
1707 length_unit_log
= 0;
1710 length_or
= ~length_or
;
1711 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1714 printf ("int length_unit_log = %u;\n", length_unit_log
);
1717 /* Take a COND expression and see if any of the conditions in it can be
1718 simplified. If any are known true or known false for the particular insn
1719 code, the COND can be further simplified.
1721 Also call ourselves on any COND operations that are values of this COND.
1723 We do not modify EXP; rather, we make and return a new rtx. */
1726 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1729 /* We store the desired contents here,
1730 then build a new expression if they don't match EXP. */
1731 rtx defval
= XEXP (exp
, 1);
1732 rtx new_defval
= XEXP (exp
, 1);
1733 int len
= XVECLEN (exp
, 0);
1734 rtx
*tests
= xmalloc (len
* sizeof (rtx
));
1738 /* This lets us free all storage allocated below, if appropriate. */
1739 obstack_finish (rtl_obstack
);
1741 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1743 /* See if default value needs simplification. */
1744 if (GET_CODE (defval
) == COND
)
1745 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1747 /* Simplify the subexpressions, and see what tests we can get rid of. */
1749 for (i
= 0; i
< len
; i
+= 2)
1751 rtx newtest
, newval
;
1753 /* Simplify this test. */
1754 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1757 newval
= tests
[i
+ 1];
1758 /* See if this value may need simplification. */
1759 if (GET_CODE (newval
) == COND
)
1760 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1762 /* Look for ways to delete or combine this test. */
1763 if (newtest
== true_rtx
)
1765 /* If test is true, make this value the default
1766 and discard this + any following tests. */
1768 defval
= tests
[i
+ 1];
1769 new_defval
= newval
;
1772 else if (newtest
== false_rtx
)
1774 /* If test is false, discard it and its value. */
1775 for (j
= i
; j
< len
- 2; j
++)
1776 tests
[j
] = tests
[j
+ 2];
1781 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1783 /* If this value and the value for the prev test are the same,
1787 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1788 insn_code
, insn_index
);
1790 /* Delete this test/value. */
1791 for (j
= i
; j
< len
- 2; j
++)
1792 tests
[j
] = tests
[j
+ 2];
1798 tests
[i
+ 1] = newval
;
1801 /* If the last test in a COND has the same value
1802 as the default value, that test isn't needed. */
1804 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1807 /* See if we changed anything. */
1808 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1811 for (i
= 0; i
< len
; i
++)
1812 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1820 if (GET_CODE (defval
) == COND
)
1821 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1829 rtx newexp
= rtx_alloc (COND
);
1831 XVEC (newexp
, 0) = rtvec_alloc (len
);
1832 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1833 XEXP (newexp
, 1) = new_defval
;
1840 /* Remove an insn entry from an attribute value. */
1843 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1845 struct insn_ent
*previe
;
1847 if (av
->first_insn
== ie
)
1848 av
->first_insn
= ie
->next
;
1851 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1853 previe
->next
= ie
->next
;
1857 if (ie
->insn_code
== -1)
1858 av
->has_asm_insn
= 0;
1863 /* Insert an insn entry in an attribute value list. */
1866 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1868 ie
->next
= av
->first_insn
;
1869 av
->first_insn
= ie
;
1871 if (ie
->insn_code
== -1)
1872 av
->has_asm_insn
= 1;
1877 /* This is a utility routine to take an expression that is a tree of either
1878 AND or IOR expressions and insert a new term. The new term will be
1879 inserted at the right side of the first node whose code does not match
1880 the root. A new node will be created with the root's code. Its left
1881 side will be the old right side and its right side will be the new
1884 If the `term' is itself a tree, all its leaves will be inserted. */
1887 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1891 /* Avoid consing in some special cases. */
1892 if (code
== AND
&& term
== true_rtx
)
1894 if (code
== AND
&& term
== false_rtx
)
1896 if (code
== AND
&& exp
== true_rtx
)
1898 if (code
== AND
&& exp
== false_rtx
)
1900 if (code
== IOR
&& term
== true_rtx
)
1902 if (code
== IOR
&& term
== false_rtx
)
1904 if (code
== IOR
&& exp
== true_rtx
)
1906 if (code
== IOR
&& exp
== false_rtx
)
1908 if (attr_equal_p (exp
, term
))
1911 if (GET_CODE (term
) == code
)
1913 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1914 insn_code
, insn_index
);
1915 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1916 insn_code
, insn_index
);
1921 if (GET_CODE (exp
) == code
)
1923 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1924 term
, insn_code
, insn_index
);
1925 if (new != XEXP (exp
, 1))
1926 /* Make a copy of this expression and call recursively. */
1927 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1933 /* Insert the new term. */
1934 newexp
= attr_rtx (code
, exp
, term
);
1937 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1940 /* If we have an expression which AND's a bunch of
1941 (not (eq_attrq "alternative" "n"))
1942 terms, we may have covered all or all but one of the possible alternatives.
1943 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1945 This routine is passed an expression and either AND or IOR. It returns a
1946 bitmask indicating which alternatives are mentioned within EXP. */
1949 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1952 if (GET_CODE (exp
) == code
)
1953 return compute_alternative_mask (XEXP (exp
, 0), code
)
1954 | compute_alternative_mask (XEXP (exp
, 1), code
);
1956 else if (code
== AND
&& GET_CODE (exp
) == NOT
1957 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1958 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1959 string
= XSTR (XEXP (exp
, 0), 1);
1961 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1962 && XSTR (exp
, 0) == alternative_name
)
1963 string
= XSTR (exp
, 1);
1965 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1967 if (code
== AND
&& XINT (exp
, 1))
1968 return XINT (exp
, 0);
1970 if (code
== IOR
&& !XINT (exp
, 1))
1971 return XINT (exp
, 0);
1979 return 1 << (string
[0] - '0');
1980 return 1 << atoi (string
);
1983 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1984 attribute with the value represented by that bit. */
1987 make_alternative_compare (int mask
)
1989 return mk_attr_alt (mask
);
1992 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1993 of "attr" for this insn code. From that value, we can compute a test
1994 showing when the EQ_ATTR will be true. This routine performs that
1995 computation. If a test condition involves an address, we leave the EQ_ATTR
1996 intact because addresses are only valid for the `length' attribute.
1998 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1999 for the insn corresponding to INSN_CODE and INSN_INDEX. */
2002 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
2009 if (GET_CODE (value
) == CONST_STRING
)
2011 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2016 else if (GET_CODE (value
) == SYMBOL_REF
)
2021 if (GET_CODE (exp
) != EQ_ATTR
)
2024 if (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2 > 256)
2027 strcpy (string
, XSTR (exp
, 0));
2028 strcat (string
, "_");
2029 strcat (string
, XSTR (exp
, 1));
2030 for (p
= string
; *p
; p
++)
2033 newexp
= attr_rtx (EQ
, value
,
2034 attr_rtx (SYMBOL_REF
,
2035 DEF_ATTR_STRING (string
)));
2037 else if (GET_CODE (value
) == COND
)
2039 /* We construct an IOR of all the cases for which the requested attribute
2040 value is present. Since we start with FALSE, if it is not present,
2041 FALSE will be returned.
2043 Each case is the AND of the NOT's of the previous conditions with the
2044 current condition; in the default case the current condition is TRUE.
2046 For each possible COND value, call ourselves recursively.
2048 The extra TRUE and FALSE expressions will be eliminated by another
2049 call to the simplification routine. */
2054 if (current_alternative_string
)
2055 clear_struct_flag (value
);
2057 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2059 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2060 insn_code
, insn_index
);
2062 SIMPLIFY_ALTERNATIVE (this);
2064 right
= insert_right_side (AND
, andexp
, this,
2065 insn_code
, insn_index
);
2066 right
= insert_right_side (AND
, right
,
2067 evaluate_eq_attr (exp
,
2070 insn_code
, insn_index
),
2071 insn_code
, insn_index
);
2072 orexp
= insert_right_side (IOR
, orexp
, right
,
2073 insn_code
, insn_index
);
2075 /* Add this condition into the AND expression. */
2076 newexp
= attr_rtx (NOT
, this);
2077 andexp
= insert_right_side (AND
, andexp
, newexp
,
2078 insn_code
, insn_index
);
2081 /* Handle the default case. */
2082 right
= insert_right_side (AND
, andexp
,
2083 evaluate_eq_attr (exp
, XEXP (value
, 1),
2084 insn_code
, insn_index
),
2085 insn_code
, insn_index
);
2086 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2091 /* If uses an address, must return original expression. But set the
2092 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2095 walk_attr_value (newexp
);
2099 /* This had `&& current_alternative_string', which seems to be wrong. */
2100 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2101 return copy_rtx_unchanging (exp
);
2108 /* This routine is called when an AND of a term with a tree of AND's is
2109 encountered. If the term or its complement is present in the tree, it
2110 can be replaced with TRUE or FALSE, respectively.
2112 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2113 be true and hence are complementary.
2115 There is one special case: If we see
2116 (and (not (eq_attr "att" "v1"))
2117 (eq_attr "att" "v2"))
2118 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2119 replace the term, not anything in the AND tree. So we pass a pointer to
2123 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2128 int left_eliminates_term
, right_eliminates_term
;
2130 if (GET_CODE (exp
) == AND
)
2132 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2133 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2134 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2136 newexp
= attr_rtx (AND
, left
, right
);
2138 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2142 else if (GET_CODE (exp
) == IOR
)
2144 /* For the IOR case, we do the same as above, except that we can
2145 only eliminate `term' if both sides of the IOR would do so. */
2147 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2148 left_eliminates_term
= (temp
== true_rtx
);
2151 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2152 right_eliminates_term
= (temp
== true_rtx
);
2154 if (left_eliminates_term
&& right_eliminates_term
)
2157 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2159 newexp
= attr_rtx (IOR
, left
, right
);
2161 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2165 /* Check for simplifications. Do some extra checking here since this
2166 routine is called so many times. */
2171 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2174 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2177 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2179 if (attr_alt_subset_p (*pterm
, exp
))
2182 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2185 if (attr_alt_subset_p (exp
, *pterm
))
2191 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2193 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2196 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2202 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2203 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2205 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2208 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2214 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2215 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2217 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2220 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2226 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2228 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2232 else if (GET_CODE (exp
) == NOT
)
2234 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2238 else if (GET_CODE (*pterm
) == NOT
)
2240 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2244 else if (attr_equal_p (exp
, *pterm
))
2250 /* Similar to `simplify_and_tree', but for IOR trees. */
2253 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2258 int left_eliminates_term
, right_eliminates_term
;
2260 if (GET_CODE (exp
) == IOR
)
2262 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2263 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2264 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2266 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2268 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2272 else if (GET_CODE (exp
) == AND
)
2274 /* For the AND case, we do the same as above, except that we can
2275 only eliminate `term' if both sides of the AND would do so. */
2277 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2278 left_eliminates_term
= (temp
== false_rtx
);
2281 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2282 right_eliminates_term
= (temp
== false_rtx
);
2284 if (left_eliminates_term
&& right_eliminates_term
)
2287 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2289 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2291 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2295 if (attr_equal_p (exp
, *pterm
))
2298 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2301 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2304 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2305 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2306 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2309 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2310 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2311 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2317 /* Compute approximate cost of the expression. Used to decide whether
2318 expression is cheap enough for inline. */
2320 attr_rtx_cost (rtx x
)
2326 code
= GET_CODE (x
);
2339 /* Alternatives don't result into function call. */
2340 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2347 const char *fmt
= GET_RTX_FORMAT (code
);
2348 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2354 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2355 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2358 cost
+= attr_rtx_cost (XEXP (x
, i
));
2368 /* Simplify test expression and use temporary obstack in order to avoid
2369 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2370 and avoid unnecessary copying if possible. */
2373 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2376 struct obstack
*old
;
2377 if (ATTR_IND_SIMPLIFIED_P (exp
))
2380 rtl_obstack
= temp_obstack
;
2381 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2383 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2385 return attr_copy_rtx (x
);
2388 /* Returns true if S1 is a subset of S2. */
2391 attr_alt_subset_p (rtx s1
, rtx s2
)
2393 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2396 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2399 return !(XINT (s1
, 0) & XINT (s2
, 0));
2405 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2412 /* Returns true if S1 is a subset of complement of S2. */
2414 static bool attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2416 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2419 return !(XINT (s1
, 0) & XINT (s2
, 0));
2422 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2425 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2435 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2438 attr_alt_intersection (rtx s1
, rtx s2
)
2440 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2442 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2445 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2448 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2451 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2454 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2459 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2464 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2467 attr_alt_union (rtx s1
, rtx s2
)
2469 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2471 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2474 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2477 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2480 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2483 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2489 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2493 /* Return EQ_ATTR_ALT expression representing complement of S. */
2496 attr_alt_complement (rtx s
)
2498 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2500 XINT (result
, 0) = XINT (s
, 0);
2501 XINT (result
, 1) = 1 - XINT (s
, 1);
2506 /* Tests whether a bit B belongs to the set represented by S. */
2509 attr_alt_bit_p (rtx s
, int b
)
2511 return XINT (s
, 1) ^ ((XINT (s
, 0) >> b
) & 1);
2514 /* Return EQ_ATTR_ALT expression representing set containing elements set
2520 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2522 XINT (result
, 0) = e
;
2523 XINT (result
, 1) = 0;
2528 /* Given an expression, see if it can be simplified for a particular insn
2529 code based on the values of other attributes being tested. This can
2530 eliminate nested get_attr_... calls.
2532 Note that if an endless recursion is specified in the patterns, the
2533 optimization will loop. However, it will do so in precisely the cases where
2534 an infinite recursion loop could occur during compilation. It's better that
2538 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2541 struct attr_desc
*attr
;
2542 struct attr_value
*av
;
2543 struct insn_ent
*ie
;
2546 bool left_alt
, right_alt
;
2548 /* Don't re-simplify something we already simplified. */
2549 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2552 switch (GET_CODE (exp
))
2555 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2556 SIMPLIFY_ALTERNATIVE (left
);
2557 if (left
== false_rtx
)
2559 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2560 SIMPLIFY_ALTERNATIVE (right
);
2561 if (left
== false_rtx
)
2564 if (GET_CODE (left
) == EQ_ATTR_ALT
2565 && GET_CODE (right
) == EQ_ATTR_ALT
)
2567 exp
= attr_alt_intersection (left
, right
);
2568 return simplify_test_exp (exp
, insn_code
, insn_index
);
2571 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2572 present on both sides, apply the distributive law since this will
2573 yield simplifications. */
2574 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2575 && compute_alternative_mask (left
, IOR
)
2576 && compute_alternative_mask (right
, IOR
))
2578 if (GET_CODE (left
) == IOR
)
2585 newexp
= attr_rtx (IOR
,
2586 attr_rtx (AND
, left
, XEXP (right
, 0)),
2587 attr_rtx (AND
, left
, XEXP (right
, 1)));
2589 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2592 /* Try with the term on both sides. */
2593 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2594 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2595 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2597 if (left
== false_rtx
|| right
== false_rtx
)
2599 else if (left
== true_rtx
)
2603 else if (right
== true_rtx
)
2607 /* See if all or all but one of the insn's alternatives are specified
2608 in this tree. Optimize if so. */
2610 if (GET_CODE (left
) == NOT
)
2611 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2612 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2614 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2617 if (GET_CODE (right
) == NOT
)
2618 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2619 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2621 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2622 && XINT (right
, 1));
2625 && (GET_CODE (left
) == AND
2627 || GET_CODE (right
) == AND
2630 i
= compute_alternative_mask (exp
, AND
);
2631 if (i
& ~insn_alternatives
[insn_code
])
2632 fatal ("invalid alternative specified for pattern number %d",
2635 /* If all alternatives are excluded, this is false. */
2636 i
^= insn_alternatives
[insn_code
];
2639 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2641 /* If just one excluded, AND a comparison with that one to the
2642 front of the tree. The others will be eliminated by
2643 optimization. We do not want to do this if the insn has one
2644 alternative and we have tested none of them! */
2645 left
= make_alternative_compare (i
);
2646 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2647 newexp
= attr_rtx (AND
, left
, right
);
2649 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2653 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2655 newexp
= attr_rtx (AND
, left
, right
);
2656 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2661 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2662 SIMPLIFY_ALTERNATIVE (left
);
2663 if (left
== true_rtx
)
2665 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2666 SIMPLIFY_ALTERNATIVE (right
);
2667 if (right
== true_rtx
)
2670 if (GET_CODE (left
) == EQ_ATTR_ALT
2671 && GET_CODE (right
) == EQ_ATTR_ALT
)
2673 exp
= attr_alt_union (left
, right
);
2674 return simplify_test_exp (exp
, insn_code
, insn_index
);
2677 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2678 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2679 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2681 if (right
== true_rtx
|| left
== true_rtx
)
2683 else if (left
== false_rtx
)
2687 else if (right
== false_rtx
)
2692 /* Test for simple cases where the distributive law is useful. I.e.,
2693 convert (ior (and (x) (y))
2699 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2700 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2702 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2704 left
= XEXP (left
, 0);
2706 newexp
= attr_rtx (AND
, left
, right
);
2707 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2710 /* See if all or all but one of the insn's alternatives are specified
2711 in this tree. Optimize if so. */
2713 else if (insn_code
>= 0
2714 && (GET_CODE (left
) == IOR
2715 || (GET_CODE (left
) == EQ_ATTR_ALT
2717 || (GET_CODE (left
) == EQ_ATTR
2718 && XSTR (left
, 0) == alternative_name
)
2719 || GET_CODE (right
) == IOR
2720 || (GET_CODE (right
) == EQ_ATTR_ALT
2721 && !XINT (right
, 1))
2722 || (GET_CODE (right
) == EQ_ATTR
2723 && XSTR (right
, 0) == alternative_name
)))
2725 i
= compute_alternative_mask (exp
, IOR
);
2726 if (i
& ~insn_alternatives
[insn_code
])
2727 fatal ("invalid alternative specified for pattern number %d",
2730 /* If all alternatives are included, this is true. */
2731 i
^= insn_alternatives
[insn_code
];
2734 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2736 /* If just one excluded, IOR a comparison with that one to the
2737 front of the tree. The others will be eliminated by
2738 optimization. We do not want to do this if the insn has one
2739 alternative and we have tested none of them! */
2740 left
= make_alternative_compare (i
);
2741 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2742 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2744 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2748 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2750 newexp
= attr_rtx (IOR
, left
, right
);
2751 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2756 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2758 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2759 insn_code
, insn_index
);
2760 SIMPLIFY_ALTERNATIVE (left
);
2764 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2765 SIMPLIFY_ALTERNATIVE (left
);
2766 if (GET_CODE (left
) == NOT
)
2767 return XEXP (left
, 0);
2769 if (left
== false_rtx
)
2771 if (left
== true_rtx
)
2774 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2776 exp
= attr_alt_complement (left
);
2777 return simplify_test_exp (exp
, insn_code
, insn_index
);
2780 /* Try to apply De`Morgan's laws. */
2781 if (GET_CODE (left
) == IOR
)
2783 newexp
= attr_rtx (AND
,
2784 attr_rtx (NOT
, XEXP (left
, 0)),
2785 attr_rtx (NOT
, XEXP (left
, 1)));
2787 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2789 else if (GET_CODE (left
) == AND
)
2791 newexp
= attr_rtx (IOR
,
2792 attr_rtx (NOT
, XEXP (left
, 0)),
2793 attr_rtx (NOT
, XEXP (left
, 1)));
2795 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2797 else if (left
!= XEXP (exp
, 0))
2799 newexp
= attr_rtx (NOT
, left
);
2804 if (current_alternative_string
)
2805 return attr_alt_bit_p (exp
, atoi (current_alternative_string
)) ? true_rtx
: false_rtx
;
2808 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2812 if (current_alternative_string
&& XSTR (exp
, 0) == alternative_name
)
2813 return (XSTR (exp
, 1) == current_alternative_string
2814 ? true_rtx
: false_rtx
);
2816 if (XSTR (exp
, 0) == alternative_name
)
2818 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2822 /* Look at the value for this insn code in the specified attribute.
2823 We normally can replace this comparison with the condition that
2824 would give this insn the values being tested for. */
2825 if (XSTR (exp
, 0) != alternative_name
2826 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2827 for (av
= attr
->first_value
; av
; av
= av
->next
)
2828 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2829 if (ie
->insn_code
== insn_code
)
2832 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2833 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2834 if (attr_rtx_cost(x
) < 20)
2843 /* We have already simplified this expression. Simplifying it again
2844 won't buy anything unless we weren't given a valid insn code
2845 to process (i.e., we are canonicalizing something.). */
2846 if (insn_code
!= -2 /* Seems wrong: && current_alternative_string. */
2847 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2848 return copy_rtx_unchanging (newexp
);
2853 /* Optimize the attribute lists by seeing if we can determine conditional
2854 values from the known values of other attributes. This will save subroutine
2855 calls during the compilation. */
2858 optimize_attrs (void)
2860 struct attr_desc
*attr
;
2861 struct attr_value
*av
;
2862 struct insn_ent
*ie
;
2865 struct attr_value_list
2867 struct attr_value
*av
;
2868 struct insn_ent
*ie
;
2869 struct attr_desc
*attr
;
2870 struct attr_value_list
*next
;
2872 struct attr_value_list
**insn_code_values
;
2873 struct attr_value_list
*ivbuf
;
2874 struct attr_value_list
*iv
;
2876 /* For each insn code, make a list of all the insn_ent's for it,
2877 for all values for all attributes. */
2879 if (num_insn_ents
== 0)
2882 /* Make 2 extra elements, for "code" values -2 and -1. */
2883 insn_code_values
= xcalloc ((insn_code_number
+ 2),
2884 sizeof (struct attr_value_list
*));
2886 /* Offset the table address so we can index by -2 or -1. */
2887 insn_code_values
+= 2;
2889 iv
= ivbuf
= xmalloc (num_insn_ents
* sizeof (struct attr_value_list
));
2891 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2892 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2893 for (av
= attr
->first_value
; av
; av
= av
->next
)
2894 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2899 iv
->next
= insn_code_values
[ie
->insn_code
];
2900 insn_code_values
[ie
->insn_code
] = iv
;
2904 /* Sanity check on num_insn_ents. */
2905 if (iv
!= ivbuf
+ num_insn_ents
)
2908 /* Process one insn code at a time. */
2909 for (i
= -2; i
< insn_code_number
; i
++)
2911 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2912 We use it to mean "already simplified for this insn". */
2913 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2914 clear_struct_flag (iv
->av
->value
);
2916 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2918 struct obstack
*old
= rtl_obstack
;
2923 if (GET_CODE (av
->value
) != COND
)
2926 rtl_obstack
= temp_obstack
;
2928 while (GET_CODE (newexp
) == COND
)
2930 rtx newexp2
= simplify_cond (newexp
, ie
->insn_code
,
2932 if (newexp2
== newexp
)
2938 if (newexp
!= av
->value
)
2940 newexp
= attr_copy_rtx (newexp
);
2941 remove_insn_ent (av
, ie
);
2942 av
= get_attr_value (newexp
, attr
, ie
->insn_code
);
2944 insert_insn_ent (av
, ie
);
2950 free (insn_code_values
- 2);
2953 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2956 clear_struct_flag (rtx x
)
2963 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2964 if (ATTR_IND_SIMPLIFIED_P (x
))
2967 code
= GET_CODE (x
);
2987 /* Compare the elements. If any pair of corresponding elements
2988 fail to match, return 0 for the whole things. */
2990 fmt
= GET_RTX_FORMAT (code
);
2991 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2997 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2998 clear_struct_flag (XVECEXP (x
, i
, j
));
3002 clear_struct_flag (XEXP (x
, i
));
3008 /* Create table entries for DEFINE_ATTR. */
3011 gen_attr (rtx exp
, int lineno
)
3013 struct attr_desc
*attr
;
3014 struct attr_value
*av
;
3015 const char *name_ptr
;
3018 /* Make a new attribute structure. Check for duplicate by looking at
3019 attr->default_val, since it is initialized by this routine. */
3020 attr
= find_attr (&XSTR (exp
, 0), 1);
3021 if (attr
->default_val
)
3023 message_with_line (lineno
, "duplicate definition for attribute %s",
3025 message_with_line (attr
->lineno
, "previous definition");
3029 attr
->lineno
= lineno
;
3031 if (*XSTR (exp
, 1) == '\0')
3032 attr
->is_numeric
= 1;
3035 name_ptr
= XSTR (exp
, 1);
3036 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3038 av
= oballoc (sizeof (struct attr_value
));
3039 av
->value
= attr_rtx (CONST_STRING
, p
);
3040 av
->next
= attr
->first_value
;
3041 attr
->first_value
= av
;
3042 av
->first_insn
= NULL
;
3044 av
->has_asm_insn
= 0;
3048 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3051 if (attr
->is_numeric
)
3053 message_with_line (lineno
,
3054 "constant attributes may not take numeric values");
3058 /* Get rid of the CONST node. It is allowed only at top-level. */
3059 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3062 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3064 message_with_line (lineno
,
3065 "`length' attribute must take numeric values");
3069 /* Set up the default value. */
3070 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3071 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3074 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3075 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3076 number of alternatives as this should be checked elsewhere. */
3079 count_alternatives (rtx exp
)
3084 if (GET_CODE (exp
) == MATCH_OPERAND
)
3085 return n_comma_elts (XSTR (exp
, 2));
3087 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3088 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3093 n
= count_alternatives (XEXP (exp
, i
));
3100 if (XVEC (exp
, i
) != NULL
)
3101 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3103 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3112 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3113 `alternative' attribute. */
3116 compares_alternatives_p (rtx exp
)
3121 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3124 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3125 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3130 if (compares_alternatives_p (XEXP (exp
, i
)))
3135 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3136 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3144 /* Returns nonzero is INNER is contained in EXP. */
3147 contained_in_p (rtx inner
, rtx exp
)
3152 if (rtx_equal_p (inner
, exp
))
3155 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3156 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3161 if (contained_in_p (inner
, XEXP (exp
, i
)))
3166 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3167 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
3175 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3178 gen_insn (rtx exp
, int lineno
)
3180 struct insn_def
*id
;
3182 id
= oballoc (sizeof (struct insn_def
));
3186 id
->lineno
= lineno
;
3188 switch (GET_CODE (exp
))
3191 id
->insn_code
= insn_code_number
;
3192 id
->insn_index
= insn_index_number
;
3193 id
->num_alternatives
= count_alternatives (exp
);
3194 if (id
->num_alternatives
== 0)
3195 id
->num_alternatives
= 1;
3199 case DEFINE_PEEPHOLE
:
3200 id
->insn_code
= insn_code_number
;
3201 id
->insn_index
= insn_index_number
;
3202 id
->num_alternatives
= count_alternatives (exp
);
3203 if (id
->num_alternatives
== 0)
3204 id
->num_alternatives
= 1;
3208 case DEFINE_ASM_ATTRIBUTES
:
3210 id
->insn_index
= -1;
3211 id
->num_alternatives
= 1;
3213 got_define_asm_attributes
= 1;
3221 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3222 true or annul false is specified, and make a `struct delay_desc'. */
3225 gen_delay (rtx def
, int lineno
)
3227 struct delay_desc
*delay
;
3230 if (XVECLEN (def
, 1) % 3 != 0)
3232 message_with_line (lineno
,
3233 "number of elements in DEFINE_DELAY must be multiple of three");
3238 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3240 if (XVECEXP (def
, 1, i
+ 1))
3241 have_annul_true
= 1;
3242 if (XVECEXP (def
, 1, i
+ 2))
3243 have_annul_false
= 1;
3246 delay
= oballoc (sizeof (struct delay_desc
));
3248 delay
->num
= ++num_delays
;
3249 delay
->next
= delays
;
3250 delay
->lineno
= lineno
;
3254 /* Given a piece of RTX, print a C expression to test its truth value.
3255 We use AND and IOR both for logical and bit-wise operations, so
3256 interpret them as logical unless they are inside a comparison expression.
3257 The first bit of FLAGS will be nonzero in that case.
3259 Set the second bit of FLAGS to make references to attribute values use
3260 a cached local variable instead of calling a function. */
3263 write_test_expr (rtx exp
, int flags
)
3265 int comparison_operator
= 0;
3267 struct attr_desc
*attr
;
3269 /* In order not to worry about operator precedence, surround our part of
3270 the expression with parentheses. */
3273 code
= GET_CODE (exp
);
3276 /* Binary operators. */
3279 printf ("(unsigned) ");
3285 comparison_operator
= 1;
3287 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3288 case AND
: case IOR
: case XOR
:
3289 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3290 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3306 printf (" >= (unsigned) ");
3309 printf (" > (unsigned) ");
3318 printf (" <= (unsigned) ");
3321 printf (" < (unsigned) ");
3364 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3368 /* Special-case (not (eq_attrq "alternative" "x")) */
3369 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3370 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3372 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3376 /* Otherwise, fall through to normal unary operator. */
3378 /* Unary operators. */
3398 write_test_expr (XEXP (exp
, 0), flags
);
3403 int set
= XINT (exp
, 0), bit
= 0;
3406 fatal ("EQ_ATTR_ALT not valid inside comparison");
3409 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3411 if (!(set
& (set
- 1)))
3413 if (!(set
& 0xffff))
3436 printf ("which_alternative %s= %d",
3437 XINT (exp
, 1) ? "!" : "=", bit
);
3441 printf ("%s((1 << which_alternative) & 0x%x)",
3442 XINT (exp
, 1) ? "!" : "", set
);
3447 /* Comparison test of an attribute with a value. Most of these will
3448 have been removed by optimization. Handle "alternative"
3449 specially and give error if EQ_ATTR present inside a comparison. */
3452 fatal ("EQ_ATTR not valid inside comparison");
3454 if (XSTR (exp
, 0) == alternative_name
)
3456 printf ("which_alternative == %s", XSTR (exp
, 1));
3460 attr
= find_attr (&XSTR (exp
, 0), 0);
3464 /* Now is the time to expand the value of a constant attribute. */
3467 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3474 printf ("attr_%s", attr
->name
);
3476 printf ("get_attr_%s (insn)", attr
->name
);
3478 write_attr_valueq (attr
, XSTR (exp
, 1));
3482 /* Comparison test of flags for define_delays. */
3485 fatal ("ATTR_FLAG not valid inside comparison");
3486 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3489 /* See if an operand matches a predicate. */
3491 /* If only a mode is given, just ensure the mode matches the operand.
3492 If neither a mode nor predicate is given, error. */
3493 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3495 if (GET_MODE (exp
) == VOIDmode
)
3496 fatal ("null MATCH_OPERAND specified as test");
3498 printf ("GET_MODE (operands[%d]) == %smode",
3499 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3502 printf ("%s (operands[%d], %smode)",
3503 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3506 /* Constant integer. */
3508 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3511 /* A random C expression. */
3513 printf ("%s", XSTR (exp
, 0));
3516 /* The address of the branch target. */
3518 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3519 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3523 /* The address of the current insn. We implement this actually as the
3524 address of the current insn for backward branches, but the last
3525 address of the next insn for forward branches, and both with
3526 adjustments that account for the worst-case possible stretching of
3527 intervening alignments between this insn and its destination. */
3528 printf ("insn_current_reference_address (insn)");
3532 printf ("%s", XSTR (exp
, 0));
3536 write_test_expr (XEXP (exp
, 0), flags
& 2);
3538 write_test_expr (XEXP (exp
, 1), flags
| 1);
3540 write_test_expr (XEXP (exp
, 2), flags
| 1);
3544 fatal ("bad RTX code `%s' in attribute calculation\n",
3545 GET_RTX_NAME (code
));
3551 /* Given an attribute value, return the maximum CONST_STRING argument
3552 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3555 max_attr_value (rtx exp
, int *unknownp
)
3560 switch (GET_CODE (exp
))
3563 current_max
= atoi (XSTR (exp
, 0));
3567 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3568 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3570 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3571 if (n
> current_max
)
3577 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3578 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3579 if (n
> current_max
)
3585 current_max
= INT_MAX
;
3592 /* Given an attribute value, return the result of ORing together all
3593 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3594 if the numeric value is not known. */
3597 or_attr_value (rtx exp
, int *unknownp
)
3602 switch (GET_CODE (exp
))
3605 current_or
= atoi (XSTR (exp
, 0));
3609 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3610 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3611 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3615 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3616 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3628 /* Scan an attribute value, possibly a conditional, and record what actions
3629 will be required to do any conditional tests in it.
3632 `must_extract' if we need to extract the insn operands
3633 `must_constrain' if we must compute `which_alternative'
3634 `address_used' if an address expression was used
3635 `length_used' if an (eq_attr "length" ...) was used
3639 walk_attr_value (rtx exp
)
3648 code
= GET_CODE (exp
);
3652 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3653 /* Since this is an arbitrary expression, it can look at anything.
3654 However, constant expressions do not depend on any particular
3656 must_extract
= must_constrain
= 1;
3664 must_extract
= must_constrain
= 1;
3668 if (XSTR (exp
, 0) == alternative_name
)
3669 must_extract
= must_constrain
= 1;
3670 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3690 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3695 walk_attr_value (XEXP (exp
, i
));
3699 if (XVEC (exp
, i
) != NULL
)
3700 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3701 walk_attr_value (XVECEXP (exp
, i
, j
));
3706 /* Write out a function to obtain the attribute for a given INSN. */
3709 write_attr_get (struct attr_desc
*attr
)
3711 struct attr_value
*av
, *common_av
;
3713 /* Find the most used attribute value. Handle that as the `default' of the
3714 switch we will generate. */
3715 common_av
= find_most_used (attr
);
3717 /* Write out start of function, then all values with explicit `case' lines,
3718 then a `default', then the value with the most uses. */
3721 if (!attr
->is_numeric
)
3722 printf ("enum attr_%s\n", attr
->name
);
3723 else if (attr
->unsigned_p
)
3724 printf ("unsigned int\n");
3728 /* If the attribute name starts with a star, the remainder is the name of
3729 the subroutine to use, instead of `get_attr_...'. */
3730 if (attr
->name
[0] == '*')
3731 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3732 else if (attr
->is_const
== 0)
3733 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3736 printf ("get_attr_%s (void)\n", attr
->name
);
3739 for (av
= attr
->first_value
; av
; av
= av
->next
)
3740 if (av
->num_insns
!= 0)
3741 write_attr_set (attr
, 2, av
->value
, "return", ";",
3742 true_rtx
, av
->first_insn
->insn_code
,
3743 av
->first_insn
->insn_index
);
3750 printf (" switch (recog_memoized (insn))\n");
3753 for (av
= attr
->first_value
; av
; av
= av
->next
)
3754 if (av
!= common_av
)
3755 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3757 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3758 printf (" }\n}\n\n");
3761 /* Given an AND tree of known true terms (because we are inside an `if' with
3762 that as the condition or are in an `else' clause) and an expression,
3763 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3764 the bulk of the work. */
3767 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3771 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3773 if (GET_CODE (known_true
) == AND
)
3775 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3776 insn_code
, insn_index
);
3777 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3778 insn_code
, insn_index
);
3783 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3789 /* Write out a series of tests and assignment statements to perform tests and
3790 sets of an attribute value. We are passed an indentation amount and prefix
3791 and suffix strings to write around each attribute value (e.g., "return"
3795 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3796 const char *prefix
, const char *suffix
, rtx known_true
,
3797 int insn_code
, int insn_index
)
3799 if (GET_CODE (value
) == COND
)
3801 /* Assume the default value will be the default of the COND unless we
3802 find an always true expression. */
3803 rtx default_val
= XEXP (value
, 1);
3804 rtx our_known_true
= known_true
;
3809 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3814 testexp
= eliminate_known_true (our_known_true
,
3815 XVECEXP (value
, 0, i
),
3816 insn_code
, insn_index
);
3817 newexp
= attr_rtx (NOT
, testexp
);
3818 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3819 insn_code
, insn_index
);
3821 /* If the test expression is always true or if the next `known_true'
3822 expression is always false, this is the last case, so break
3823 out and let this value be the `else' case. */
3824 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3826 default_val
= XVECEXP (value
, 0, i
+ 1);
3830 /* Compute the expression to pass to our recursive call as being
3832 inner_true
= insert_right_side (AND
, our_known_true
,
3833 testexp
, insn_code
, insn_index
);
3835 /* If this is always false, skip it. */
3836 if (inner_true
== false_rtx
)
3839 write_indent (indent
);
3840 printf ("%sif ", first_if
? "" : "else ");
3842 write_test_expr (testexp
, 0);
3844 write_indent (indent
+ 2);
3847 write_attr_set (attr
, indent
+ 4,
3848 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3849 inner_true
, insn_code
, insn_index
);
3850 write_indent (indent
+ 2);
3852 our_known_true
= newexp
;
3857 write_indent (indent
);
3859 write_indent (indent
+ 2);
3863 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
3864 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
3868 write_indent (indent
+ 2);
3874 write_indent (indent
);
3875 printf ("%s ", prefix
);
3876 write_attr_value (attr
, value
);
3877 printf ("%s\n", suffix
);
3881 /* Write out the computation for one attribute value. */
3884 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
3885 int write_case_lines
, const char *prefix
, const char *suffix
,
3886 int indent
, rtx known_true
)
3888 struct insn_ent
*ie
;
3890 if (av
->num_insns
== 0)
3893 if (av
->has_asm_insn
)
3895 write_indent (indent
);
3896 printf ("case -1:\n");
3897 write_indent (indent
+ 2);
3898 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3899 write_indent (indent
+ 2);
3900 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3901 write_indent (indent
+ 2);
3902 printf (" fatal_insn_not_found (insn);\n");
3905 if (write_case_lines
)
3907 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
3908 if (ie
->insn_code
!= -1)
3910 write_indent (indent
);
3911 printf ("case %d:\n", ie
->insn_code
);
3916 write_indent (indent
);
3917 printf ("default:\n");
3920 /* See what we have to do to output this value. */
3921 must_extract
= must_constrain
= address_used
= 0;
3922 walk_attr_value (av
->value
);
3926 write_indent (indent
+ 2);
3927 printf ("extract_constrain_insn_cached (insn);\n");
3929 else if (must_extract
)
3931 write_indent (indent
+ 2);
3932 printf ("extract_insn_cached (insn);\n");
3935 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3936 known_true
, av
->first_insn
->insn_code
,
3937 av
->first_insn
->insn_index
);
3939 if (strncmp (prefix
, "return", 6))
3941 write_indent (indent
+ 2);
3942 printf ("break;\n");
3947 /* Search for uses of non-const attributes and write code to cache them. */
3950 write_expr_attr_cache (rtx p
, struct attr_desc
*attr
)
3955 if (GET_CODE (p
) == EQ_ATTR
)
3957 if (XSTR (p
, 0) != attr
->name
)
3960 if (!attr
->is_numeric
)
3961 printf (" enum attr_%s ", attr
->name
);
3962 else if (attr
->unsigned_p
)
3963 printf (" unsigned int ");
3967 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
3971 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
3972 ie
= GET_RTX_LENGTH (GET_CODE (p
));
3973 for (i
= 0; i
< ie
; i
++)
3978 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
3983 je
= XVECLEN (p
, i
);
3984 for (j
= 0; j
< je
; ++j
)
3985 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
3994 /* Utilities to write in various forms. */
3997 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
3999 if (attr
->is_numeric
)
4005 if (num
> 9 || num
< 0)
4006 printf (" /* 0x%x */", num
);
4010 write_upcase (attr
->name
);
4017 write_attr_value (struct attr_desc
*attr
, rtx value
)
4021 switch (GET_CODE (value
))
4024 write_attr_valueq (attr
, XSTR (value
, 0));
4028 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4032 fputs (XSTR (value
, 0), stdout
);
4037 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4038 printf ("get_attr_%s (%s)", attr2
->name
,
4039 (attr2
->is_const
? "" : "insn"));
4060 write_attr_value (attr
, XEXP (value
, 0));
4064 write_attr_value (attr
, XEXP (value
, 1));
4073 write_upcase (const char *str
)
4077 /* The argument of TOUPPER should not have side effects. */
4078 putchar (TOUPPER(*str
));
4084 write_indent (int indent
)
4086 for (; indent
> 8; indent
-= 8)
4089 for (; indent
; indent
--)
4093 /* Write a subroutine that is given an insn that requires a delay slot, a
4094 delay slot ordinal, and a candidate insn. It returns nonzero if the
4095 candidate can be placed in the specified delay slot of the insn.
4097 We can write as many as three subroutines. `eligible_for_delay'
4098 handles normal delay slots, `eligible_for_annul_true' indicates that
4099 the specified insn can be annulled if the branch is true, and likewise
4100 for `eligible_for_annul_false'.
4102 KIND is a string distinguishing these three cases ("delay", "annul_true",
4103 or "annul_false"). */
4106 write_eligible_delay (const char *kind
)
4108 struct delay_desc
*delay
;
4112 struct attr_desc
*attr
;
4113 struct attr_value
*av
, *common_av
;
4116 /* Compute the maximum number of delay slots required. We use the delay
4117 ordinal times this number plus one, plus the slot number as an index into
4118 the appropriate predicate to test. */
4120 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4121 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4122 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4124 /* Write function prelude. */
4127 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4130 printf (" rtx insn;\n");
4132 printf (" if (slot >= %d)\n", max_slots
);
4133 printf (" abort ();\n");
4135 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4136 converts a compound instruction into a loop. */
4137 printf (" if (!INSN_P (candidate_insn))\n");
4138 printf (" return 0;\n");
4141 /* If more than one delay type, find out which type the delay insn is. */
4145 attr
= find_attr (&delay_type_str
, 0);
4148 common_av
= find_most_used (attr
);
4150 printf (" insn = delay_insn;\n");
4151 printf (" switch (recog_memoized (insn))\n");
4154 sprintf (str
, " * %d;\n break;", max_slots
);
4155 for (av
= attr
->first_value
; av
; av
= av
->next
)
4156 if (av
!= common_av
)
4157 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4159 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4162 /* Ensure matched. Otherwise, shouldn't have been called. */
4163 printf (" if (slot < %d)\n", max_slots
);
4164 printf (" abort ();\n\n");
4167 /* If just one type of delay slot, write simple switch. */
4168 if (num_delays
== 1 && max_slots
== 1)
4170 printf (" insn = candidate_insn;\n");
4171 printf (" switch (recog_memoized (insn))\n");
4174 attr
= find_attr (&delay_1_0_str
, 0);
4177 common_av
= find_most_used (attr
);
4179 for (av
= attr
->first_value
; av
; av
= av
->next
)
4180 if (av
!= common_av
)
4181 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4183 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4189 /* Write a nested CASE. The first indicates which condition we need to
4190 test, and the inner CASE tests the condition. */
4191 printf (" insn = candidate_insn;\n");
4192 printf (" switch (slot)\n");
4195 for (delay
= delays
; delay
; delay
= delay
->next
)
4196 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4198 printf (" case %d:\n",
4199 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4200 printf (" switch (recog_memoized (insn))\n");
4203 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4205 attr
= find_attr (&pstr
, 0);
4208 common_av
= find_most_used (attr
);
4210 for (av
= attr
->first_value
; av
; av
= av
->next
)
4211 if (av
!= common_av
)
4212 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4214 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4218 printf (" default:\n");
4219 printf (" abort ();\n");
4226 /* This page contains miscellaneous utility routines. */
4228 /* Given a pointer to a (char *), return a malloc'ed string containing the
4229 next comma-separated element. Advance the pointer to after the string
4230 scanned, or the end-of-string. Return NULL if at end of string. */
4233 next_comma_elt (const char **pstr
)
4237 start
= scan_comma_elt (pstr
);
4242 return attr_string (start
, *pstr
- start
);
4245 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4246 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4247 replaced by a pointer to a canonical copy of the string. */
4249 static struct attr_desc
*
4250 find_attr (const char **name_p
, int create
)
4252 struct attr_desc
*attr
;
4254 const char *name
= *name_p
;
4256 /* Before we resort to using `strcmp', see if the string address matches
4257 anywhere. In most cases, it should have been canonicalized to do so. */
4258 if (name
== alternative_name
)
4261 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4262 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4263 if (name
== attr
->name
)
4266 /* Otherwise, do it the slow way. */
4267 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4268 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4270 *name_p
= attr
->name
;
4277 attr
= oballoc (sizeof (struct attr_desc
));
4278 attr
->name
= DEF_ATTR_STRING (name
);
4279 attr
->first_value
= attr
->default_val
= NULL
;
4280 attr
->is_numeric
= attr
->negative_ok
= attr
->is_const
= attr
->is_special
= 0;
4281 attr
->unsigned_p
= attr
->static_p
= 0;
4282 attr
->next
= attrs
[index
];
4283 attrs
[index
] = attr
;
4285 *name_p
= attr
->name
;
4290 /* Create internal attribute with the given default value. */
4293 make_internal_attr (const char *name
, rtx value
, int special
)
4295 struct attr_desc
*attr
;
4297 attr
= find_attr (&name
, 1);
4298 if (attr
->default_val
)
4301 attr
->is_numeric
= 1;
4303 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4304 attr
->negative_ok
= (special
& ATTR_NEGATIVE_OK
) != 0;
4305 attr
->unsigned_p
= (special
& ATTR_UNSIGNED
) != 0;
4306 attr
->static_p
= (special
& ATTR_STATIC
) != 0;
4307 attr
->default_val
= get_attr_value (value
, attr
, -2);
4310 /* Find the most used value of an attribute. */
4312 static struct attr_value
*
4313 find_most_used (struct attr_desc
*attr
)
4315 struct attr_value
*av
;
4316 struct attr_value
*most_used
;
4322 for (av
= attr
->first_value
; av
; av
= av
->next
)
4323 if (av
->num_insns
> nuses
)
4324 nuses
= av
->num_insns
, most_used
= av
;
4329 /* Return (attr_value "n") */
4332 make_numeric_value (int n
)
4334 static rtx int_values
[20];
4341 if (n
< 20 && int_values
[n
])
4342 return int_values
[n
];
4344 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4345 exp
= attr_rtx (CONST_STRING
, p
);
4348 int_values
[n
] = exp
;
4354 copy_rtx_unchanging (rtx orig
)
4356 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4359 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4363 /* Determine if an insn has a constant number of delay slots, i.e., the
4364 number of delay slots is not a function of the length of the insn. */
4367 write_const_num_delay_slots (void)
4369 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4370 struct attr_value
*av
;
4371 struct insn_ent
*ie
;
4375 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4377 printf (" switch (recog_memoized (insn))\n");
4380 for (av
= attr
->first_value
; av
; av
= av
->next
)
4383 walk_attr_value (av
->value
);
4386 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
4387 if (ie
->insn_code
!= -1)
4388 printf (" case %d:\n", ie
->insn_code
);
4389 printf (" return 0;\n");
4393 printf (" default:\n");
4394 printf (" return 1;\n");
4395 printf (" }\n}\n\n");
4400 main (int argc
, char **argv
)
4403 struct attr_desc
*attr
;
4404 struct insn_def
*id
;
4408 progname
= "genattrtab";
4410 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
4411 return (FATAL_EXIT_CODE
);
4413 obstack_init (hash_obstack
);
4414 obstack_init (temp_obstack
);
4416 /* Set up true and false rtx's */
4417 true_rtx
= rtx_alloc (CONST_INT
);
4418 XWINT (true_rtx
, 0) = 1;
4419 false_rtx
= rtx_alloc (CONST_INT
);
4420 XWINT (false_rtx
, 0) = 0;
4421 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4422 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4424 alternative_name
= DEF_ATTR_STRING ("alternative");
4425 length_str
= DEF_ATTR_STRING ("length");
4426 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4427 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4428 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4430 printf ("/* Generated automatically by the program `genattrtab'\n\
4431 from the machine description file `md'. */\n\n");
4433 /* Read the machine description. */
4435 initiate_automaton_gen (argc
, argv
);
4440 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4444 switch (GET_CODE (desc
))
4447 case DEFINE_PEEPHOLE
:
4448 case DEFINE_ASM_ATTRIBUTES
:
4449 gen_insn (desc
, lineno
);
4453 gen_attr (desc
, lineno
);
4457 gen_delay (desc
, lineno
);
4460 case DEFINE_CPU_UNIT
:
4461 gen_cpu_unit (desc
);
4464 case DEFINE_QUERY_CPU_UNIT
:
4465 gen_query_cpu_unit (desc
);
4473 gen_excl_set (desc
);
4477 gen_presence_set (desc
);
4480 case FINAL_PRESENCE_SET
:
4481 gen_final_presence_set (desc
);
4485 gen_absence_set (desc
);
4488 case FINAL_ABSENCE_SET
:
4489 gen_final_absence_set (desc
);
4492 case DEFINE_AUTOMATON
:
4493 gen_automaton (desc
);
4496 case AUTOMATA_OPTION
:
4497 gen_automata_option (desc
);
4500 case DEFINE_RESERVATION
:
4504 case DEFINE_INSN_RESERVATION
:
4505 gen_insn_reserv (desc
);
4511 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4512 insn_index_number
++;
4516 return FATAL_EXIT_CODE
;
4520 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4521 if (! got_define_asm_attributes
)
4523 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4524 XVEC (tem
, 0) = rtvec_alloc (0);
4528 /* Expand DEFINE_DELAY information into new attribute. */
4532 /* Build DFA, output some functions and expand DFA information
4533 to new attributes. */
4537 printf ("#include \"config.h\"\n");
4538 printf ("#include \"system.h\"\n");
4539 printf ("#include \"coretypes.h\"\n");
4540 printf ("#include \"tm.h\"\n");
4541 printf ("#include \"rtl.h\"\n");
4542 printf ("#include \"tm_p.h\"\n");
4543 printf ("#include \"insn-config.h\"\n");
4544 printf ("#include \"recog.h\"\n");
4545 printf ("#include \"regs.h\"\n");
4546 printf ("#include \"real.h\"\n");
4547 printf ("#include \"output.h\"\n");
4548 printf ("#include \"insn-attr.h\"\n");
4549 printf ("#include \"toplev.h\"\n");
4550 printf ("#include \"flags.h\"\n");
4551 printf ("#include \"function.h\"\n");
4553 printf ("#define operands recog_data.operand\n\n");
4555 /* Make `insn_alternatives'. */
4556 insn_alternatives
= oballoc (insn_code_number
* sizeof (int));
4557 for (id
= defs
; id
; id
= id
->next
)
4558 if (id
->insn_code
>= 0)
4559 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4561 /* Make `insn_n_alternatives'. */
4562 insn_n_alternatives
= oballoc (insn_code_number
* sizeof (int));
4563 for (id
= defs
; id
; id
= id
->next
)
4564 if (id
->insn_code
>= 0)
4565 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4567 /* Prepare to write out attribute subroutines by checking everything stored
4568 away and building the attribute cases. */
4572 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4573 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4574 attr
->default_val
->value
4575 = check_attr_value (attr
->default_val
->value
, attr
);
4578 return FATAL_EXIT_CODE
;
4580 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4581 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4584 /* Construct extra attributes for `length'. */
4585 make_length_attrs ();
4587 /* Perform any possible optimizations to speed up compilation. */
4590 /* Now write out all the `gen_attr_...' routines. Do these before the
4591 special routines so that they get defined before they are used. */
4593 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4594 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4596 if (! attr
->is_special
&& ! attr
->is_const
)
4601 = (attr
->name
[0] == '*'
4602 && strcmp (&attr
->name
[1], INSN_ALTS_FUNC_NAME
) == 0);
4604 printf ("\n#if AUTOMATON_ALTS\n");
4605 write_attr_get (attr
);
4607 printf ("#endif\n\n");
4611 /* Write out delay eligibility information, if DEFINE_DELAY present.
4612 (The function to compute the number of delay slots will be written
4616 write_eligible_delay ("delay");
4617 if (have_annul_true
)
4618 write_eligible_delay ("annul_true");
4619 if (have_annul_false
)
4620 write_eligible_delay ("annul_false");
4623 /* Output code for pipeline hazards recognition based on DFA
4624 (deterministic finite-state automata). */
4628 /* Write out constant delay slot info. */
4629 write_const_num_delay_slots ();
4631 write_length_unit_log ();
4634 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);
4637 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
4639 get_insn_name (int code ATTRIBUTE_UNUSED
)