1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 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 : (gcc_assert (strcmp ((S1), (S2))), 1))
107 #define strcmp_check(S1, S2) ((S1) != (S2))
112 #include "coretypes.h"
116 #include "gensupport.h"
118 #ifdef HAVE_SYS_RESOURCE_H
119 # include <sys/resource.h>
122 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
123 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
127 #include "genattrtab.h"
129 static struct obstack obstack1
, obstack2
;
130 struct obstack
*hash_obstack
= &obstack1
;
131 struct obstack
*temp_obstack
= &obstack2
;
133 /* enough space to reserve for printing out ints */
134 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
136 /* Define structures used to record attributes and values. */
138 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
139 encountered, we store all the relevant information into a
140 `struct insn_def'. This is done to allow attribute definitions to occur
141 anywhere in the file. */
145 struct insn_def
*next
; /* Next insn in chain. */
146 rtx def
; /* The DEFINE_... */
147 int insn_code
; /* Instruction number. */
148 int insn_index
; /* Expression numer in file, for errors. */
149 int lineno
; /* Line number. */
150 int num_alternatives
; /* Number of alternatives. */
151 int vec_idx
; /* Index of attribute vector in `def'. */
154 /* Once everything has been read in, we store in each attribute value a list
155 of insn codes that have that value. Here is the structure used for the
160 struct insn_ent
*next
; /* Next in chain. */
161 struct insn_def
*def
; /* Instruction definition. */
164 /* Each value of an attribute (either constant or computed) is assigned a
165 structure which is used as the listhead of the insns that have that
170 rtx value
; /* Value of attribute. */
171 struct attr_value
*next
; /* Next attribute value in chain. */
172 struct insn_ent
*first_insn
; /* First insn with this value. */
173 int num_insns
; /* Number of insns with this value. */
174 int has_asm_insn
; /* True if this value used for `asm' insns */
177 /* Structure for each attribute. */
181 char *name
; /* Name of attribute. */
182 struct attr_desc
*next
; /* Next attribute. */
183 struct attr_value
*first_value
; /* First value of this attribute. */
184 struct attr_value
*default_val
; /* Default value for this attribute. */
185 int lineno
: 24; /* Line number. */
186 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
187 unsigned is_const
: 1; /* Attribute value constant for each run. */
188 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
189 unsigned static_p
: 1; /* Make the output function static. */
192 #define NULL_ATTR (struct attr_desc *) NULL
194 /* Structure for each DEFINE_DELAY. */
198 rtx def
; /* DEFINE_DELAY expression. */
199 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
200 int num
; /* Number of DEFINE_DELAY, starting at 1. */
201 int lineno
; /* Line number. */
204 /* Listheads of above structures. */
206 /* This one is indexed by the first character of the attribute name. */
207 #define MAX_ATTRS_INDEX 256
208 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
209 static struct insn_def
*defs
;
210 static struct delay_desc
*delays
;
212 /* Other variables. */
214 static int insn_code_number
;
215 static int insn_index_number
;
216 static int got_define_asm_attributes
;
217 static int must_extract
;
218 static int must_constrain
;
219 static int address_used
;
220 static int length_used
;
221 static int num_delays
;
222 static int have_annul_true
, have_annul_false
;
223 static int num_insn_ents
;
227 /* Stores, for each insn code, the number of constraint alternatives. */
229 static int *insn_n_alternatives
;
231 /* Stores, for each insn code, a bitmap that has bits on for each possible
234 static int *insn_alternatives
;
236 /* If nonzero, assume that the `alternative' attr has this value.
237 This is the hashed, unique string for the numeral
238 whose value is chosen alternative. */
240 static const char *current_alternative_string
;
242 /* Used to simplify expressions. */
244 static rtx true_rtx
, false_rtx
;
246 /* Used to reduce calls to `strcmp' */
248 static char *alternative_name
;
249 static const char *length_str
;
250 static const char *delay_type_str
;
251 static const char *delay_1_0_str
;
252 static const char *num_delay_slots_str
;
254 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
257 int reload_completed
= 0;
259 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
260 to define it here. */
264 /* Simplify an expression. Only call the routine if there is something to
266 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
267 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
268 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
270 /* Simplify (eq_attr ("alternative") ...)
271 when we are working with a particular alternative. */
272 #define SIMPLIFY_ALTERNATIVE(EXP) \
273 if (current_alternative_string \
274 && GET_CODE ((EXP)) == EQ_ATTR \
275 && XSTR ((EXP), 0) == alternative_name) \
276 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
277 ? true_rtx : false_rtx);
279 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
281 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
282 They won't actually be used. */
284 rtx global_rtl
[GR_MAX
];
285 rtx pic_offset_table_rtx
;
287 static void attr_hash_add_rtx (int, rtx
);
288 static void attr_hash_add_string (int, char *);
289 static rtx
attr_rtx (enum rtx_code
, ...);
290 static rtx
attr_rtx_1 (enum rtx_code
, va_list);
291 static char *attr_string (const char *, int);
292 static rtx
check_attr_value (rtx
, struct attr_desc
*);
293 static rtx
convert_set_attr_alternative (rtx
, struct insn_def
*);
294 static rtx
convert_set_attr (rtx
, struct insn_def
*);
295 static void check_defs (void);
296 static rtx
make_canonical (struct attr_desc
*, rtx
);
297 static struct attr_value
*get_attr_value (rtx
, struct attr_desc
*, int);
298 static rtx
copy_rtx_unchanging (rtx
);
299 static rtx
copy_boolean (rtx
);
300 static void expand_delays (void);
301 static void fill_attr (struct attr_desc
*);
302 static rtx
substitute_address (rtx
, rtx (*) (rtx
), rtx (*) (rtx
));
303 static void make_length_attrs (void);
304 static rtx
identity_fn (rtx
);
305 static rtx
zero_fn (rtx
);
306 static rtx
one_fn (rtx
);
307 static rtx
max_fn (rtx
);
308 static void write_length_unit_log (void);
309 static rtx
simplify_cond (rtx
, int, int);
310 static void clear_struct_flag (rtx
);
311 static void remove_insn_ent (struct attr_value
*, struct insn_ent
*);
312 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
313 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
314 static rtx
make_alternative_compare (int);
315 static int compute_alternative_mask (rtx
, enum rtx_code
);
316 static rtx
evaluate_eq_attr (rtx
, rtx
, int, int);
317 static rtx
simplify_and_tree (rtx
, rtx
*, int, int);
318 static rtx
simplify_or_tree (rtx
, rtx
*, int, int);
319 static rtx
simplify_test_exp (rtx
, int, int);
320 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
321 static void optimize_attrs (void);
322 static void gen_attr (rtx
, int);
323 static int count_alternatives (rtx
);
324 static int compares_alternatives_p (rtx
);
325 static int contained_in_p (rtx
, rtx
);
326 static void gen_insn (rtx
, int);
327 static void gen_delay (rtx
, int);
328 static void write_test_expr (rtx
, int);
329 static int max_attr_value (rtx
, int*);
330 static int or_attr_value (rtx
, int*);
331 static void walk_attr_value (rtx
);
332 static void write_attr_get (struct attr_desc
*);
333 static rtx
eliminate_known_true (rtx
, rtx
, int, int);
334 static void write_attr_set (struct attr_desc
*, int, rtx
,
335 const char *, const char *, rtx
,
337 static void write_insn_cases (struct insn_ent
*, int);
338 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
339 int, const char *, const char *, int, rtx
);
340 static void write_attr_valueq (struct attr_desc
*, const char *);
341 static void write_attr_value (struct attr_desc
*, rtx
);
342 static void write_upcase (const char *);
343 static void write_indent (int);
344 static void write_eligible_delay (const char *);
345 static int write_expr_attr_cache (rtx
, struct attr_desc
*);
346 static void write_const_num_delay_slots (void);
347 static char *next_comma_elt (const char **);
348 static struct attr_desc
*find_attr (const char **, int);
349 static struct attr_value
*find_most_used (struct attr_desc
*);
350 static rtx
attr_eq (const char *, const char *);
351 static const char *attr_numeral (int);
352 static int attr_equal_p (rtx
, rtx
);
353 static rtx
attr_copy_rtx (rtx
);
354 static int attr_rtx_cost (rtx
);
355 static bool attr_alt_subset_p (rtx
, rtx
);
356 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
357 static rtx
attr_alt_intersection (rtx
, rtx
);
358 static rtx
attr_alt_union (rtx
, rtx
);
359 static rtx
attr_alt_complement (rtx
);
360 static bool attr_alt_bit_p (rtx
, int);
361 static rtx
mk_attr_alt (int);
363 #define oballoc(size) obstack_alloc (hash_obstack, size)
365 /* Hash table for sharing RTL and strings. */
367 /* Each hash table slot is a bucket containing a chain of these structures.
368 Strings are given negative hash codes; RTL expressions are given positive
373 struct attr_hash
*next
; /* Next structure in the bucket. */
374 int hashcode
; /* Hash code of this rtx or string. */
377 char *str
; /* The string (negative hash codes) */
378 rtx rtl
; /* or the RTL recorded here. */
382 /* Now here is the hash table. When recording an RTL, it is added to
383 the slot whose index is the hash code mod the table size. Note
384 that the hash table is used for several kinds of RTL (see attr_rtx)
385 and for strings. While all these live in the same table, they are
386 completely independent, and the hash code is computed differently
389 #define RTL_HASH_SIZE 4093
390 struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
392 /* Here is how primitive or already-shared RTL's hash
394 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
396 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
399 attr_hash_add_rtx (int hashcode
, rtx rtl
)
403 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
404 h
->hashcode
= hashcode
;
406 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
407 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
410 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
413 attr_hash_add_string (int hashcode
, char *str
)
417 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
418 h
->hashcode
= -hashcode
;
420 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
421 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
424 /* Generate an RTL expression, but avoid duplicates.
425 Set the ATTR_PERMANENT_P flag for these permanent objects.
427 In some cases we cannot uniquify; then we return an ordinary
428 impermanent rtx with ATTR_PERMANENT_P clear.
432 rtx attr_rtx (code, [element1, ..., elementn]) */
435 attr_rtx_1 (enum rtx_code code
, va_list p
)
437 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
440 struct obstack
*old_obstack
= rtl_obstack
;
442 /* For each of several cases, search the hash table for an existing entry.
443 Use that entry if one is found; otherwise create a new RTL and add it
446 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
448 rtx arg0
= va_arg (p
, rtx
);
450 /* A permanent object cannot point to impermanent ones. */
451 if (! ATTR_PERMANENT_P (arg0
))
453 rt_val
= rtx_alloc (code
);
454 XEXP (rt_val
, 0) = arg0
;
458 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
459 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
460 if (h
->hashcode
== hashcode
461 && GET_CODE (h
->u
.rtl
) == code
462 && XEXP (h
->u
.rtl
, 0) == arg0
)
467 rtl_obstack
= hash_obstack
;
468 rt_val
= rtx_alloc (code
);
469 XEXP (rt_val
, 0) = arg0
;
472 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
473 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
474 || GET_RTX_CLASS (code
) == RTX_COMPARE
475 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
477 rtx arg0
= va_arg (p
, rtx
);
478 rtx arg1
= va_arg (p
, rtx
);
480 /* A permanent object cannot point to impermanent ones. */
481 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
483 rt_val
= rtx_alloc (code
);
484 XEXP (rt_val
, 0) = arg0
;
485 XEXP (rt_val
, 1) = arg1
;
489 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
490 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
491 if (h
->hashcode
== hashcode
492 && GET_CODE (h
->u
.rtl
) == code
493 && XEXP (h
->u
.rtl
, 0) == arg0
494 && XEXP (h
->u
.rtl
, 1) == arg1
)
499 rtl_obstack
= hash_obstack
;
500 rt_val
= rtx_alloc (code
);
501 XEXP (rt_val
, 0) = arg0
;
502 XEXP (rt_val
, 1) = arg1
;
505 else if (GET_RTX_LENGTH (code
) == 1
506 && GET_RTX_FORMAT (code
)[0] == 's')
508 char *arg0
= va_arg (p
, char *);
510 arg0
= DEF_ATTR_STRING (arg0
);
512 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
513 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
514 if (h
->hashcode
== hashcode
515 && GET_CODE (h
->u
.rtl
) == code
516 && XSTR (h
->u
.rtl
, 0) == arg0
)
521 rtl_obstack
= hash_obstack
;
522 rt_val
= rtx_alloc (code
);
523 XSTR (rt_val
, 0) = arg0
;
526 else if (GET_RTX_LENGTH (code
) == 2
527 && GET_RTX_FORMAT (code
)[0] == 's'
528 && GET_RTX_FORMAT (code
)[1] == 's')
530 char *arg0
= va_arg (p
, char *);
531 char *arg1
= va_arg (p
, char *);
533 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
534 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
535 if (h
->hashcode
== hashcode
536 && GET_CODE (h
->u
.rtl
) == code
537 && XSTR (h
->u
.rtl
, 0) == arg0
538 && XSTR (h
->u
.rtl
, 1) == arg1
)
543 rtl_obstack
= hash_obstack
;
544 rt_val
= rtx_alloc (code
);
545 XSTR (rt_val
, 0) = arg0
;
546 XSTR (rt_val
, 1) = arg1
;
549 else if (code
== CONST_INT
)
551 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
561 int i
; /* Array indices... */
562 const char *fmt
; /* Current rtx's format... */
564 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
566 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
567 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
571 case '0': /* Unused field. */
574 case 'i': /* An integer? */
575 XINT (rt_val
, i
) = va_arg (p
, int);
578 case 'w': /* A wide integer? */
579 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
582 case 's': /* A string? */
583 XSTR (rt_val
, i
) = va_arg (p
, char *);
586 case 'e': /* An expression? */
587 case 'u': /* An insn? Same except when printing. */
588 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
591 case 'E': /* An RTX vector? */
592 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
602 rtl_obstack
= old_obstack
;
603 attr_hash_add_rtx (hashcode
, rt_val
);
604 ATTR_PERMANENT_P (rt_val
) = 1;
609 attr_rtx (enum rtx_code code
, ...)
615 result
= attr_rtx_1 (code
, p
);
620 /* Create a new string printed with the printf line arguments into a space
621 of at most LEN bytes:
623 rtx attr_printf (len, format, [arg1, ..., argn]) */
626 attr_printf (unsigned int len
, const char *fmt
, ...)
633 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
635 vsprintf (str
, fmt
, p
);
638 return DEF_ATTR_STRING (str
);
642 attr_eq (const char *name
, const char *value
)
644 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
650 return XSTR (make_numeric_value (n
), 0);
653 /* Return a permanent (possibly shared) copy of a string STR (not assumed
654 to be null terminated) with LEN bytes. */
657 attr_string (const char *str
, int len
)
664 /* Compute the hash code. */
665 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
666 for (i
= 1; i
<= len
; i
+= 2)
667 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
669 hashcode
= -hashcode
;
671 /* Search the table for the string. */
672 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
673 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
674 && !strncmp (h
->u
.str
, str
, len
))
675 return h
->u
.str
; /* <-- return if found. */
677 /* Not found; create a permanent copy and add it to the hash table. */
678 new_str
= obstack_alloc (hash_obstack
, len
+ 1);
679 memcpy (new_str
, str
, len
);
681 attr_hash_add_string (hashcode
, new_str
);
683 return new_str
; /* Return the new string. */
686 /* Check two rtx's for equality of contents,
687 taking advantage of the fact that if both are hashed
688 then they can't be equal unless they are the same object. */
691 attr_equal_p (rtx x
, rtx y
)
693 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
694 && rtx_equal_p (x
, y
)));
697 /* Copy an attribute value expression,
698 descending to all depths, but not copying any
699 permanent hashed subexpressions. */
702 attr_copy_rtx (rtx orig
)
707 const char *format_ptr
;
709 /* No need to copy a permanent object. */
710 if (ATTR_PERMANENT_P (orig
))
713 code
= GET_CODE (orig
);
731 copy
= rtx_alloc (code
);
732 PUT_MODE (copy
, GET_MODE (orig
));
733 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
734 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
735 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
736 ATTR_EQ_ATTR_P (copy
) = ATTR_EQ_ATTR_P (orig
);
738 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
740 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
742 switch (*format_ptr
++)
745 XEXP (copy
, i
) = XEXP (orig
, i
);
746 if (XEXP (orig
, i
) != NULL
)
747 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
752 XVEC (copy
, i
) = XVEC (orig
, i
);
753 if (XVEC (orig
, i
) != NULL
)
755 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
756 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
757 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
763 XINT (copy
, i
) = XINT (orig
, i
);
767 XWINT (copy
, i
) = XWINT (orig
, i
);
772 XSTR (copy
, i
) = XSTR (orig
, i
);
782 /* Given a test expression for an attribute, ensure it is validly formed.
783 IS_CONST indicates whether the expression is constant for each compiler
784 run (a constant expression may not test any particular insn).
786 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
787 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
788 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
790 Update the string address in EQ_ATTR expression to be the same used
791 in the attribute (or `alternative_name') to speed up subsequent
792 `find_attr' calls and eliminate most `strcmp' calls.
794 Return the new expression, if any. */
797 check_attr_test (rtx exp
, int is_const
, int lineno
)
799 struct attr_desc
*attr
;
800 struct attr_value
*av
;
801 const char *name_ptr
, *p
;
804 switch (GET_CODE (exp
))
807 /* Handle negation test. */
808 if (XSTR (exp
, 1)[0] == '!')
809 return check_attr_test (attr_rtx (NOT
,
810 attr_eq (XSTR (exp
, 0),
814 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
816 attr
= find_attr (&XSTR (exp
, 0), 0);
819 if (! strcmp (XSTR (exp
, 0), "alternative"))
820 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
822 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
825 if (is_const
&& ! attr
->is_const
)
826 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
829 /* Copy this just to make it permanent,
830 so expressions using it can be permanent too. */
831 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
833 /* It shouldn't be possible to simplify the value given to a
834 constant attribute, so don't expand this until it's time to
835 write the test expression. */
837 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
839 if (attr
->is_numeric
)
841 for (p
= XSTR (exp
, 1); *p
; p
++)
843 fatal ("attribute `%s' takes only numeric values",
848 for (av
= attr
->first_value
; av
; av
= av
->next
)
849 if (GET_CODE (av
->value
) == CONST_STRING
850 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
854 fatal ("unknown value `%s' for `%s' attribute",
855 XSTR (exp
, 1), XSTR (exp
, 0));
860 if (! strcmp (XSTR (exp
, 0), "alternative"))
864 name_ptr
= XSTR (exp
, 1);
865 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
866 set
|= 1 << atoi (p
);
868 return mk_attr_alt (set
);
872 /* Make an IOR tree of the possible values. */
874 name_ptr
= XSTR (exp
, 1);
875 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
877 newexp
= attr_eq (XSTR (exp
, 0), p
);
878 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
881 return check_attr_test (orexp
, is_const
, lineno
);
890 /* Either TRUE or FALSE. */
898 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
899 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
903 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
908 fatal ("RTL operator \"%s\" not valid in constant attribute test",
909 GET_RTX_NAME (GET_CODE (exp
)));
910 /* These cases can't be simplified. */
911 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
914 case LE
: case LT
: case GT
: case GE
:
915 case LEU
: case LTU
: case GTU
: case GEU
:
917 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
918 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
919 exp
= attr_rtx (GET_CODE (exp
),
920 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
921 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
922 /* These cases can't be simplified. */
923 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
929 /* These cases are valid for constant attributes, but can't be
931 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
932 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
936 fatal ("RTL operator \"%s\" not valid in attribute test",
937 GET_RTX_NAME (GET_CODE (exp
)));
943 /* Given an expression, ensure that it is validly formed and that all named
944 attribute values are valid for the given attribute. Issue a fatal error
945 if not. If no attribute is specified, assume a numeric attribute.
947 Return a perhaps modified replacement expression for the value. */
950 check_attr_value (rtx exp
, struct attr_desc
*attr
)
952 struct attr_value
*av
;
956 switch (GET_CODE (exp
))
959 if (attr
&& ! attr
->is_numeric
)
961 message_with_line (attr
->lineno
,
962 "CONST_INT not valid for non-numeric attribute %s",
968 if (INTVAL (exp
) < 0)
970 message_with_line (attr
->lineno
,
971 "negative numeric value specified for attribute %s",
979 if (! strcmp (XSTR (exp
, 0), "*"))
982 if (attr
== 0 || attr
->is_numeric
)
988 message_with_line (attr
? attr
->lineno
: 0,
989 "non-numeric value for numeric attribute %s",
990 attr
? attr
->name
: "internal");
997 for (av
= attr
->first_value
; av
; av
= av
->next
)
998 if (GET_CODE (av
->value
) == CONST_STRING
999 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
1004 message_with_line (attr
->lineno
,
1005 "unknown value `%s' for `%s' attribute",
1006 XSTR (exp
, 0), attr
? attr
->name
: "internal");
1012 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
1013 attr
? attr
->is_const
: 0,
1014 attr
? attr
->lineno
: 0);
1015 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1016 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
1024 if (attr
&& !attr
->is_numeric
)
1026 message_with_line (attr
->lineno
,
1027 "invalid operation `%s' for non-numeric attribute value",
1028 GET_RTX_NAME (GET_CODE (exp
)));
1036 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1037 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1045 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1049 if (XVECLEN (exp
, 0) % 2 != 0)
1051 message_with_line (attr
->lineno
,
1052 "first operand of COND must have even length");
1057 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1059 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1060 attr
? attr
->is_const
: 0,
1061 attr
? attr
->lineno
: 0);
1062 XVECEXP (exp
, 0, i
+ 1)
1063 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1066 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1071 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1074 message_with_line (attr
? attr
->lineno
: 0,
1075 "unknown attribute `%s' in ATTR",
1079 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1081 message_with_line (attr
->lineno
,
1082 "non-constant attribute `%s' referenced from `%s'",
1083 XSTR (exp
, 0), attr
->name
);
1087 && attr
->is_numeric
!= attr2
->is_numeric
)
1089 message_with_line (attr
->lineno
,
1090 "numeric attribute mismatch calling `%s' from `%s'",
1091 XSTR (exp
, 0), attr
->name
);
1098 /* A constant SYMBOL_REF is valid as a constant attribute test and
1099 is expanded later by make_canonical into a COND. In a non-constant
1100 attribute test, it is left be. */
1101 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1104 message_with_line (attr
? attr
->lineno
: 0,
1105 "invalid operation `%s' for attribute value",
1106 GET_RTX_NAME (GET_CODE (exp
)));
1114 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1115 It becomes a COND with each test being (eq_attr "alternative "n") */
1118 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1120 int num_alt
= id
->num_alternatives
;
1124 if (XVECLEN (exp
, 1) != num_alt
)
1126 message_with_line (id
->lineno
,
1127 "bad number of entries in SET_ATTR_ALTERNATIVE");
1132 /* Make a COND with all tests but the last. Select the last value via the
1134 condexp
= rtx_alloc (COND
);
1135 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1137 for (i
= 0; i
< num_alt
- 1; i
++)
1140 p
= attr_numeral (i
);
1142 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1143 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1146 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1148 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1151 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1152 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1155 convert_set_attr (rtx exp
, struct insn_def
*id
)
1158 const char *name_ptr
;
1162 /* See how many alternative specified. */
1163 n
= n_comma_elts (XSTR (exp
, 1));
1165 return attr_rtx (SET
,
1166 attr_rtx (ATTR
, XSTR (exp
, 0)),
1167 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1169 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1170 XSTR (newexp
, 0) = XSTR (exp
, 0);
1171 XVEC (newexp
, 1) = rtvec_alloc (n
);
1173 /* Process each comma-separated name. */
1174 name_ptr
= XSTR (exp
, 1);
1176 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1177 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1179 return convert_set_attr_alternative (newexp
, id
);
1182 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1183 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1189 struct insn_def
*id
;
1190 struct attr_desc
*attr
;
1194 for (id
= defs
; id
; id
= id
->next
)
1196 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1199 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1201 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1202 switch (GET_CODE (value
))
1205 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1207 message_with_line (id
->lineno
, "bad attribute set");
1213 case SET_ATTR_ALTERNATIVE
:
1214 value
= convert_set_attr_alternative (value
, id
);
1218 value
= convert_set_attr (value
, id
);
1222 message_with_line (id
->lineno
, "invalid attribute code %s",
1223 GET_RTX_NAME (GET_CODE (value
)));
1227 if (value
== NULL_RTX
)
1230 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1232 message_with_line (id
->lineno
, "unknown attribute %s",
1233 XSTR (XEXP (value
, 0), 0));
1238 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1239 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1244 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1245 expressions by converting them into a COND. This removes cases from this
1246 program. Also, replace an attribute value of "*" with the default attribute
1250 make_canonical (struct attr_desc
*attr
, rtx exp
)
1255 switch (GET_CODE (exp
))
1258 exp
= make_numeric_value (INTVAL (exp
));
1262 if (! strcmp (XSTR (exp
, 0), "*"))
1264 if (attr
== 0 || attr
->default_val
== 0)
1265 fatal ("(attr_value \"*\") used in invalid context");
1266 exp
= attr
->default_val
->value
;
1269 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1274 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1276 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1277 This makes the COND something that won't be considered an arbitrary
1278 expression by walk_attr_value. */
1279 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1280 exp
= check_attr_value (exp
, attr
);
1284 newexp
= rtx_alloc (COND
);
1285 XVEC (newexp
, 0) = rtvec_alloc (2);
1286 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1287 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1289 XEXP (newexp
, 1) = XEXP (exp
, 2);
1292 /* Fall through to COND case since this is now a COND. */
1299 /* First, check for degenerate COND. */
1300 if (XVECLEN (exp
, 0) == 0)
1301 return make_canonical (attr
, XEXP (exp
, 1));
1302 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1304 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1306 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1307 XVECEXP (exp
, 0, i
+ 1)
1308 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1309 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1325 copy_boolean (rtx exp
)
1327 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1328 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1329 copy_boolean (XEXP (exp
, 1)));
1330 if (GET_CODE (exp
) == MATCH_OPERAND
)
1332 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1333 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1335 else if (GET_CODE (exp
) == EQ_ATTR
)
1337 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1338 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1344 /* Given a value and an attribute description, return a `struct attr_value *'
1345 that represents that value. This is either an existing structure, if the
1346 value has been previously encountered, or a newly-created structure.
1348 `insn_code' is the code of an insn whose attribute has the specified
1349 value (-2 if not processing an insn). We ensure that all insns for
1350 a given value have the same number of alternatives if the value checks
1353 static struct attr_value
*
1354 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1356 struct attr_value
*av
;
1359 value
= make_canonical (attr
, value
);
1360 if (compares_alternatives_p (value
))
1362 if (insn_code
< 0 || insn_alternatives
== NULL
)
1363 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1365 num_alt
= insn_alternatives
[insn_code
];
1368 for (av
= attr
->first_value
; av
; av
= av
->next
)
1369 if (rtx_equal_p (value
, av
->value
)
1370 && (num_alt
== 0 || av
->first_insn
== NULL
1371 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1374 av
= oballoc (sizeof (struct attr_value
));
1376 av
->next
= attr
->first_value
;
1377 attr
->first_value
= av
;
1378 av
->first_insn
= NULL
;
1380 av
->has_asm_insn
= 0;
1385 /* After all DEFINE_DELAYs have been read in, create internal attributes
1386 to generate the required routines.
1388 First, we compute the number of delay slots for each insn (as a COND of
1389 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1390 delay type is specified, we compute a similar function giving the
1391 DEFINE_DELAY ordinal for each insn.
1393 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1394 tells whether a given insn can be in that delay slot.
1396 Normal attribute filling and optimization expands these to contain the
1397 information needed to handle delay slots. */
1400 expand_delays (void)
1402 struct delay_desc
*delay
;
1408 /* First, generate data for `num_delay_slots' function. */
1410 condexp
= rtx_alloc (COND
);
1411 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1412 XEXP (condexp
, 1) = make_numeric_value (0);
1414 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1416 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1417 XVECEXP (condexp
, 0, i
+ 1)
1418 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1421 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1423 /* If more than one delay type, do the same for computing the delay type. */
1426 condexp
= rtx_alloc (COND
);
1427 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1428 XEXP (condexp
, 1) = make_numeric_value (0);
1430 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1432 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1433 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1436 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1439 /* For each delay possibility and delay slot, compute an eligibility
1440 attribute for non-annulled insns and for each type of annulled (annul
1441 if true and annul if false). */
1442 for (delay
= delays
; delay
; delay
= delay
->next
)
1444 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1446 condexp
= XVECEXP (delay
->def
, 1, i
);
1448 condexp
= false_rtx
;
1449 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1450 make_numeric_value (1), make_numeric_value (0));
1452 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1453 "*delay_%d_%d", delay
->num
, i
/ 3);
1454 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1456 if (have_annul_true
)
1458 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1459 if (condexp
== 0) condexp
= false_rtx
;
1460 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1461 make_numeric_value (1),
1462 make_numeric_value (0));
1463 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1464 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1465 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1468 if (have_annul_false
)
1470 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1471 if (condexp
== 0) condexp
= false_rtx
;
1472 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1473 make_numeric_value (1),
1474 make_numeric_value (0));
1475 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1476 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1477 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1483 /* Once all attributes and insns have been read and checked, we construct for
1484 each attribute value a list of all the insns that have that value for
1488 fill_attr (struct attr_desc
*attr
)
1490 struct attr_value
*av
;
1491 struct insn_ent
*ie
;
1492 struct insn_def
*id
;
1496 /* Don't fill constant attributes. The value is independent of
1497 any particular insn. */
1501 for (id
= defs
; id
; id
= id
->next
)
1503 /* If no value is specified for this insn for this attribute, use the
1506 if (XVEC (id
->def
, id
->vec_idx
))
1507 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1508 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1510 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1513 av
= attr
->default_val
;
1515 av
= get_attr_value (value
, attr
, id
->insn_code
);
1517 ie
= oballoc (sizeof (struct insn_ent
));
1519 insert_insn_ent (av
, ie
);
1523 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1524 test that checks relative positions of insns (uses MATCH_DUP or PC).
1525 If so, replace it with what is obtained by passing the expression to
1526 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1527 recursively on each value (including the default value). Otherwise,
1528 return the value returned by NO_ADDRESS_FN applied to EXP. */
1531 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1532 rtx (*address_fn
) (rtx
))
1537 if (GET_CODE (exp
) == COND
)
1539 /* See if any tests use addresses. */
1541 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1542 walk_attr_value (XVECEXP (exp
, 0, i
));
1545 return (*address_fn
) (exp
);
1547 /* Make a new copy of this COND, replacing each element. */
1548 newexp
= rtx_alloc (COND
);
1549 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1550 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1552 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1553 XVECEXP (newexp
, 0, i
+ 1)
1554 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1555 no_address_fn
, address_fn
);
1558 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1559 no_address_fn
, address_fn
);
1564 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1567 walk_attr_value (XEXP (exp
, 0));
1569 return (*address_fn
) (exp
);
1571 return attr_rtx (IF_THEN_ELSE
,
1572 substitute_address (XEXP (exp
, 0),
1573 no_address_fn
, address_fn
),
1574 substitute_address (XEXP (exp
, 1),
1575 no_address_fn
, address_fn
),
1576 substitute_address (XEXP (exp
, 2),
1577 no_address_fn
, address_fn
));
1580 return (*no_address_fn
) (exp
);
1583 /* Make new attributes from the `length' attribute. The following are made,
1584 each corresponding to a function called from `shorten_branches' or
1587 *insn_default_length This is the length of the insn to be returned
1588 by `get_attr_length' before `shorten_branches'
1589 has been called. In each case where the length
1590 depends on relative addresses, the largest
1591 possible is used. This routine is also used
1592 to compute the initial size of the insn.
1594 *insn_variable_length_p This returns 1 if the insn's length depends
1595 on relative addresses, zero otherwise.
1597 *insn_current_length This is only called when it is known that the
1598 insn has a variable length and returns the
1599 current length, based on relative addresses.
1603 make_length_attrs (void)
1605 static const char *new_names
[] =
1607 "*insn_default_length",
1608 "*insn_variable_length_p",
1609 "*insn_current_length"
1611 static rtx (*const no_address_fn
[]) (rtx
) = {identity_fn
, zero_fn
, zero_fn
};
1612 static rtx (*const address_fn
[]) (rtx
) = {max_fn
, one_fn
, identity_fn
};
1614 struct attr_desc
*length_attr
, *new_attr
;
1615 struct attr_value
*av
, *new_av
;
1616 struct insn_ent
*ie
, *new_ie
;
1618 /* See if length attribute is defined. If so, it must be numeric. Make
1619 it special so we don't output anything for it. */
1620 length_attr
= find_attr (&length_str
, 0);
1621 if (length_attr
== 0)
1624 if (! length_attr
->is_numeric
)
1625 fatal ("length attribute must be numeric");
1627 length_attr
->is_const
= 0;
1628 length_attr
->is_special
= 1;
1630 /* Make each new attribute, in turn. */
1631 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1633 make_internal_attr (new_names
[i
],
1634 substitute_address (length_attr
->default_val
->value
,
1635 no_address_fn
[i
], address_fn
[i
]),
1637 new_attr
= find_attr (&new_names
[i
], 0);
1638 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1639 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1641 new_av
= get_attr_value (substitute_address (av
->value
,
1644 new_attr
, ie
->def
->insn_code
);
1645 new_ie
= oballoc (sizeof (struct insn_ent
));
1646 new_ie
->def
= ie
->def
;
1647 insert_insn_ent (new_av
, new_ie
);
1652 /* Utility functions called from above routine. */
1655 identity_fn (rtx exp
)
1661 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1663 return make_numeric_value (0);
1667 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1669 return make_numeric_value (1);
1676 return make_numeric_value (max_attr_value (exp
, &unknown
));
1680 write_length_unit_log (void)
1682 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1683 struct attr_value
*av
;
1684 struct insn_ent
*ie
;
1685 unsigned int length_unit_log
, length_or
;
1688 if (length_attr
== 0)
1690 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1691 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1692 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1693 length_or
|= or_attr_value (av
->value
, &unknown
);
1696 length_unit_log
= 0;
1699 length_or
= ~length_or
;
1700 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1703 printf ("int length_unit_log = %u;\n", length_unit_log
);
1706 /* Take a COND expression and see if any of the conditions in it can be
1707 simplified. If any are known true or known false for the particular insn
1708 code, the COND can be further simplified.
1710 Also call ourselves on any COND operations that are values of this COND.
1712 We do not modify EXP; rather, we make and return a new rtx. */
1715 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1718 /* We store the desired contents here,
1719 then build a new expression if they don't match EXP. */
1720 rtx defval
= XEXP (exp
, 1);
1721 rtx new_defval
= XEXP (exp
, 1);
1722 int len
= XVECLEN (exp
, 0);
1723 rtx
*tests
= xmalloc (len
* sizeof (rtx
));
1727 /* This lets us free all storage allocated below, if appropriate. */
1728 obstack_finish (rtl_obstack
);
1730 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1732 /* See if default value needs simplification. */
1733 if (GET_CODE (defval
) == COND
)
1734 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1736 /* Simplify the subexpressions, and see what tests we can get rid of. */
1738 for (i
= 0; i
< len
; i
+= 2)
1740 rtx newtest
, newval
;
1742 /* Simplify this test. */
1743 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1746 newval
= tests
[i
+ 1];
1747 /* See if this value may need simplification. */
1748 if (GET_CODE (newval
) == COND
)
1749 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1751 /* Look for ways to delete or combine this test. */
1752 if (newtest
== true_rtx
)
1754 /* If test is true, make this value the default
1755 and discard this + any following tests. */
1757 defval
= tests
[i
+ 1];
1758 new_defval
= newval
;
1761 else if (newtest
== false_rtx
)
1763 /* If test is false, discard it and its value. */
1764 for (j
= i
; j
< len
- 2; j
++)
1765 tests
[j
] = tests
[j
+ 2];
1770 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1772 /* If this value and the value for the prev test are the same,
1776 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1777 insn_code
, insn_index
);
1779 /* Delete this test/value. */
1780 for (j
= i
; j
< len
- 2; j
++)
1781 tests
[j
] = tests
[j
+ 2];
1787 tests
[i
+ 1] = newval
;
1790 /* If the last test in a COND has the same value
1791 as the default value, that test isn't needed. */
1793 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1796 /* See if we changed anything. */
1797 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1800 for (i
= 0; i
< len
; i
++)
1801 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1809 if (GET_CODE (defval
) == COND
)
1810 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1818 rtx newexp
= rtx_alloc (COND
);
1820 XVEC (newexp
, 0) = rtvec_alloc (len
);
1821 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1822 XEXP (newexp
, 1) = new_defval
;
1829 /* Remove an insn entry from an attribute value. */
1832 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1834 struct insn_ent
*previe
;
1836 if (av
->first_insn
== ie
)
1837 av
->first_insn
= ie
->next
;
1840 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1842 previe
->next
= ie
->next
;
1846 if (ie
->def
->insn_code
== -1)
1847 av
->has_asm_insn
= 0;
1852 /* Insert an insn entry in an attribute value list. */
1855 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1857 ie
->next
= av
->first_insn
;
1858 av
->first_insn
= ie
;
1860 if (ie
->def
->insn_code
== -1)
1861 av
->has_asm_insn
= 1;
1866 /* This is a utility routine to take an expression that is a tree of either
1867 AND or IOR expressions and insert a new term. The new term will be
1868 inserted at the right side of the first node whose code does not match
1869 the root. A new node will be created with the root's code. Its left
1870 side will be the old right side and its right side will be the new
1873 If the `term' is itself a tree, all its leaves will be inserted. */
1876 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1880 /* Avoid consing in some special cases. */
1881 if (code
== AND
&& term
== true_rtx
)
1883 if (code
== AND
&& term
== false_rtx
)
1885 if (code
== AND
&& exp
== true_rtx
)
1887 if (code
== AND
&& exp
== false_rtx
)
1889 if (code
== IOR
&& term
== true_rtx
)
1891 if (code
== IOR
&& term
== false_rtx
)
1893 if (code
== IOR
&& exp
== true_rtx
)
1895 if (code
== IOR
&& exp
== false_rtx
)
1897 if (attr_equal_p (exp
, term
))
1900 if (GET_CODE (term
) == code
)
1902 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1903 insn_code
, insn_index
);
1904 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1905 insn_code
, insn_index
);
1910 if (GET_CODE (exp
) == code
)
1912 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1913 term
, insn_code
, insn_index
);
1914 if (new != XEXP (exp
, 1))
1915 /* Make a copy of this expression and call recursively. */
1916 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1922 /* Insert the new term. */
1923 newexp
= attr_rtx (code
, exp
, term
);
1926 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1929 /* If we have an expression which AND's a bunch of
1930 (not (eq_attrq "alternative" "n"))
1931 terms, we may have covered all or all but one of the possible alternatives.
1932 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1934 This routine is passed an expression and either AND or IOR. It returns a
1935 bitmask indicating which alternatives are mentioned within EXP. */
1938 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1941 if (GET_CODE (exp
) == code
)
1942 return compute_alternative_mask (XEXP (exp
, 0), code
)
1943 | compute_alternative_mask (XEXP (exp
, 1), code
);
1945 else if (code
== AND
&& GET_CODE (exp
) == NOT
1946 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1947 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1948 string
= XSTR (XEXP (exp
, 0), 1);
1950 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1951 && XSTR (exp
, 0) == alternative_name
)
1952 string
= XSTR (exp
, 1);
1954 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1956 if (code
== AND
&& XINT (exp
, 1))
1957 return XINT (exp
, 0);
1959 if (code
== IOR
&& !XINT (exp
, 1))
1960 return XINT (exp
, 0);
1968 return 1 << (string
[0] - '0');
1969 return 1 << atoi (string
);
1972 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1973 attribute with the value represented by that bit. */
1976 make_alternative_compare (int mask
)
1978 return mk_attr_alt (mask
);
1981 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1982 of "attr" for this insn code. From that value, we can compute a test
1983 showing when the EQ_ATTR will be true. This routine performs that
1984 computation. If a test condition involves an address, we leave the EQ_ATTR
1985 intact because addresses are only valid for the `length' attribute.
1987 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1988 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1991 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
1998 switch (GET_CODE (value
))
2001 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2012 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2013 gcc_assert (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2
2016 strcpy (string
, XSTR (exp
, 0));
2017 strcat (string
, "_");
2018 strcat (string
, XSTR (exp
, 1));
2019 for (p
= string
; *p
; p
++)
2022 newexp
= attr_rtx (EQ
, value
,
2023 attr_rtx (SYMBOL_REF
,
2024 DEF_ATTR_STRING (string
)));
2029 /* We construct an IOR of all the cases for which the
2030 requested attribute value is present. Since we start with
2031 FALSE, if it is not present, FALSE will be returned.
2033 Each case is the AND of the NOT's of the previous conditions with the
2034 current condition; in the default case the current condition is TRUE.
2036 For each possible COND value, call ourselves recursively.
2038 The extra TRUE and FALSE expressions will be eliminated by another
2039 call to the simplification routine. */
2044 if (current_alternative_string
)
2045 clear_struct_flag (value
);
2047 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2049 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2050 insn_code
, insn_index
);
2052 SIMPLIFY_ALTERNATIVE (this);
2054 right
= insert_right_side (AND
, andexp
, this,
2055 insn_code
, insn_index
);
2056 right
= insert_right_side (AND
, right
,
2057 evaluate_eq_attr (exp
,
2060 insn_code
, insn_index
),
2061 insn_code
, insn_index
);
2062 orexp
= insert_right_side (IOR
, orexp
, right
,
2063 insn_code
, insn_index
);
2065 /* Add this condition into the AND expression. */
2066 newexp
= attr_rtx (NOT
, this);
2067 andexp
= insert_right_side (AND
, andexp
, newexp
,
2068 insn_code
, insn_index
);
2071 /* Handle the default case. */
2072 right
= insert_right_side (AND
, andexp
,
2073 evaluate_eq_attr (exp
, XEXP (value
, 1),
2074 insn_code
, insn_index
),
2075 insn_code
, insn_index
);
2076 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2083 /* If uses an address, must return original expression. But set the
2084 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2087 walk_attr_value (newexp
);
2091 /* This had `&& current_alternative_string', which seems to be wrong. */
2092 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2093 return copy_rtx_unchanging (exp
);
2100 /* This routine is called when an AND of a term with a tree of AND's is
2101 encountered. If the term or its complement is present in the tree, it
2102 can be replaced with TRUE or FALSE, respectively.
2104 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2105 be true and hence are complementary.
2107 There is one special case: If we see
2108 (and (not (eq_attr "att" "v1"))
2109 (eq_attr "att" "v2"))
2110 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2111 replace the term, not anything in the AND tree. So we pass a pointer to
2115 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2120 int left_eliminates_term
, right_eliminates_term
;
2122 if (GET_CODE (exp
) == AND
)
2124 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2125 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2126 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2128 newexp
= attr_rtx (AND
, left
, right
);
2130 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2134 else if (GET_CODE (exp
) == IOR
)
2136 /* For the IOR case, we do the same as above, except that we can
2137 only eliminate `term' if both sides of the IOR would do so. */
2139 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2140 left_eliminates_term
= (temp
== true_rtx
);
2143 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2144 right_eliminates_term
= (temp
== true_rtx
);
2146 if (left_eliminates_term
&& right_eliminates_term
)
2149 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2151 newexp
= attr_rtx (IOR
, left
, right
);
2153 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2157 /* Check for simplifications. Do some extra checking here since this
2158 routine is called so many times. */
2163 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2166 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2169 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2171 if (attr_alt_subset_p (*pterm
, exp
))
2174 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2177 if (attr_alt_subset_p (exp
, *pterm
))
2183 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2185 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2188 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2194 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2195 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2197 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2200 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2206 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2207 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2209 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2212 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2218 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2220 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2224 else if (GET_CODE (exp
) == NOT
)
2226 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2230 else if (GET_CODE (*pterm
) == NOT
)
2232 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2236 else if (attr_equal_p (exp
, *pterm
))
2242 /* Similar to `simplify_and_tree', but for IOR trees. */
2245 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2250 int left_eliminates_term
, right_eliminates_term
;
2252 if (GET_CODE (exp
) == IOR
)
2254 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2255 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2256 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2258 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2260 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2264 else if (GET_CODE (exp
) == AND
)
2266 /* For the AND case, we do the same as above, except that we can
2267 only eliminate `term' if both sides of the AND would do so. */
2269 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2270 left_eliminates_term
= (temp
== false_rtx
);
2273 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2274 right_eliminates_term
= (temp
== false_rtx
);
2276 if (left_eliminates_term
&& right_eliminates_term
)
2279 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2281 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2283 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2287 if (attr_equal_p (exp
, *pterm
))
2290 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2293 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2296 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2297 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2298 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2301 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2302 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2303 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2309 /* Compute approximate cost of the expression. Used to decide whether
2310 expression is cheap enough for inline. */
2312 attr_rtx_cost (rtx x
)
2318 code
= GET_CODE (x
);
2331 /* Alternatives don't result into function call. */
2332 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2339 const char *fmt
= GET_RTX_FORMAT (code
);
2340 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2346 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2347 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2350 cost
+= attr_rtx_cost (XEXP (x
, i
));
2360 /* Simplify test expression and use temporary obstack in order to avoid
2361 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2362 and avoid unnecessary copying if possible. */
2365 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2368 struct obstack
*old
;
2369 if (ATTR_IND_SIMPLIFIED_P (exp
))
2372 rtl_obstack
= temp_obstack
;
2373 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2375 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2377 return attr_copy_rtx (x
);
2380 /* Returns true if S1 is a subset of S2. */
2383 attr_alt_subset_p (rtx s1
, rtx s2
)
2385 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2388 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2391 return !(XINT (s1
, 0) & XINT (s2
, 0));
2397 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2404 /* Returns true if S1 is a subset of complement of S2. */
2407 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2409 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2412 return !(XINT (s1
, 0) & XINT (s2
, 0));
2415 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2418 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2428 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2431 attr_alt_intersection (rtx s1
, rtx s2
)
2433 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2435 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2438 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2441 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2444 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2447 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2452 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2457 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2460 attr_alt_union (rtx s1
, rtx s2
)
2462 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2464 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2467 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2470 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2473 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2476 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2482 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2486 /* Return EQ_ATTR_ALT expression representing complement of S. */
2489 attr_alt_complement (rtx s
)
2491 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2493 XINT (result
, 0) = XINT (s
, 0);
2494 XINT (result
, 1) = 1 - XINT (s
, 1);
2499 /* Tests whether a bit B belongs to the set represented by S. */
2502 attr_alt_bit_p (rtx s
, int b
)
2504 return XINT (s
, 1) ^ ((XINT (s
, 0) >> b
) & 1);
2507 /* Return EQ_ATTR_ALT expression representing set containing elements set
2513 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2515 XINT (result
, 0) = e
;
2516 XINT (result
, 1) = 0;
2521 /* Given an expression, see if it can be simplified for a particular insn
2522 code based on the values of other attributes being tested. This can
2523 eliminate nested get_attr_... calls.
2525 Note that if an endless recursion is specified in the patterns, the
2526 optimization will loop. However, it will do so in precisely the cases where
2527 an infinite recursion loop could occur during compilation. It's better that
2531 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2534 struct attr_desc
*attr
;
2535 struct attr_value
*av
;
2536 struct insn_ent
*ie
;
2539 bool left_alt
, right_alt
;
2541 /* Don't re-simplify something we already simplified. */
2542 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2545 switch (GET_CODE (exp
))
2548 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2549 SIMPLIFY_ALTERNATIVE (left
);
2550 if (left
== false_rtx
)
2552 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2553 SIMPLIFY_ALTERNATIVE (right
);
2554 if (left
== false_rtx
)
2557 if (GET_CODE (left
) == EQ_ATTR_ALT
2558 && GET_CODE (right
) == EQ_ATTR_ALT
)
2560 exp
= attr_alt_intersection (left
, right
);
2561 return simplify_test_exp (exp
, insn_code
, insn_index
);
2564 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2565 present on both sides, apply the distributive law since this will
2566 yield simplifications. */
2567 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2568 && compute_alternative_mask (left
, IOR
)
2569 && compute_alternative_mask (right
, IOR
))
2571 if (GET_CODE (left
) == IOR
)
2578 newexp
= attr_rtx (IOR
,
2579 attr_rtx (AND
, left
, XEXP (right
, 0)),
2580 attr_rtx (AND
, left
, XEXP (right
, 1)));
2582 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2585 /* Try with the term on both sides. */
2586 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2587 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2588 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2590 if (left
== false_rtx
|| right
== false_rtx
)
2592 else if (left
== true_rtx
)
2596 else if (right
== true_rtx
)
2600 /* See if all or all but one of the insn's alternatives are specified
2601 in this tree. Optimize if so. */
2603 if (GET_CODE (left
) == NOT
)
2604 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2605 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2607 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2610 if (GET_CODE (right
) == NOT
)
2611 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2612 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2614 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2615 && XINT (right
, 1));
2618 && (GET_CODE (left
) == AND
2620 || GET_CODE (right
) == AND
2623 i
= compute_alternative_mask (exp
, AND
);
2624 if (i
& ~insn_alternatives
[insn_code
])
2625 fatal ("invalid alternative specified for pattern number %d",
2628 /* If all alternatives are excluded, this is false. */
2629 i
^= insn_alternatives
[insn_code
];
2632 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2634 /* If just one excluded, AND a comparison with that one to the
2635 front of the tree. The others will be eliminated by
2636 optimization. We do not want to do this if the insn has one
2637 alternative and we have tested none of them! */
2638 left
= make_alternative_compare (i
);
2639 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2640 newexp
= attr_rtx (AND
, left
, right
);
2642 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2646 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2648 newexp
= attr_rtx (AND
, left
, right
);
2649 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2654 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2655 SIMPLIFY_ALTERNATIVE (left
);
2656 if (left
== true_rtx
)
2658 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2659 SIMPLIFY_ALTERNATIVE (right
);
2660 if (right
== true_rtx
)
2663 if (GET_CODE (left
) == EQ_ATTR_ALT
2664 && GET_CODE (right
) == EQ_ATTR_ALT
)
2666 exp
= attr_alt_union (left
, right
);
2667 return simplify_test_exp (exp
, insn_code
, insn_index
);
2670 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2671 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2672 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2674 if (right
== true_rtx
|| left
== true_rtx
)
2676 else if (left
== false_rtx
)
2680 else if (right
== false_rtx
)
2685 /* Test for simple cases where the distributive law is useful. I.e.,
2686 convert (ior (and (x) (y))
2692 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2693 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2695 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2697 left
= XEXP (left
, 0);
2699 newexp
= attr_rtx (AND
, left
, right
);
2700 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2703 /* See if all or all but one of the insn's alternatives are specified
2704 in this tree. Optimize if so. */
2706 else if (insn_code
>= 0
2707 && (GET_CODE (left
) == IOR
2708 || (GET_CODE (left
) == EQ_ATTR_ALT
2710 || (GET_CODE (left
) == EQ_ATTR
2711 && XSTR (left
, 0) == alternative_name
)
2712 || GET_CODE (right
) == IOR
2713 || (GET_CODE (right
) == EQ_ATTR_ALT
2714 && !XINT (right
, 1))
2715 || (GET_CODE (right
) == EQ_ATTR
2716 && XSTR (right
, 0) == alternative_name
)))
2718 i
= compute_alternative_mask (exp
, IOR
);
2719 if (i
& ~insn_alternatives
[insn_code
])
2720 fatal ("invalid alternative specified for pattern number %d",
2723 /* If all alternatives are included, this is true. */
2724 i
^= insn_alternatives
[insn_code
];
2727 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2729 /* If just one excluded, IOR a comparison with that one to the
2730 front of the tree. The others will be eliminated by
2731 optimization. We do not want to do this if the insn has one
2732 alternative and we have tested none of them! */
2733 left
= make_alternative_compare (i
);
2734 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2735 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2737 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2741 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2743 newexp
= attr_rtx (IOR
, left
, right
);
2744 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2749 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2751 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2752 insn_code
, insn_index
);
2753 SIMPLIFY_ALTERNATIVE (left
);
2757 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2758 SIMPLIFY_ALTERNATIVE (left
);
2759 if (GET_CODE (left
) == NOT
)
2760 return XEXP (left
, 0);
2762 if (left
== false_rtx
)
2764 if (left
== true_rtx
)
2767 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2769 exp
= attr_alt_complement (left
);
2770 return simplify_test_exp (exp
, insn_code
, insn_index
);
2773 /* Try to apply De`Morgan's laws. */
2774 if (GET_CODE (left
) == IOR
)
2776 newexp
= attr_rtx (AND
,
2777 attr_rtx (NOT
, XEXP (left
, 0)),
2778 attr_rtx (NOT
, XEXP (left
, 1)));
2780 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2782 else if (GET_CODE (left
) == AND
)
2784 newexp
= attr_rtx (IOR
,
2785 attr_rtx (NOT
, XEXP (left
, 0)),
2786 attr_rtx (NOT
, XEXP (left
, 1)));
2788 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2790 else if (left
!= XEXP (exp
, 0))
2792 newexp
= attr_rtx (NOT
, left
);
2797 if (current_alternative_string
)
2798 return attr_alt_bit_p (exp
, atoi (current_alternative_string
)) ? true_rtx
: false_rtx
;
2801 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2805 if (current_alternative_string
&& XSTR (exp
, 0) == alternative_name
)
2806 return (XSTR (exp
, 1) == current_alternative_string
2807 ? true_rtx
: false_rtx
);
2809 if (XSTR (exp
, 0) == alternative_name
)
2811 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2815 /* Look at the value for this insn code in the specified attribute.
2816 We normally can replace this comparison with the condition that
2817 would give this insn the values being tested for. */
2818 if (XSTR (exp
, 0) != alternative_name
2819 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2820 for (av
= attr
->first_value
; av
; av
= av
->next
)
2821 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2822 if (ie
->def
->insn_code
== insn_code
)
2825 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2826 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2827 if (attr_rtx_cost(x
) < 20)
2836 /* We have already simplified this expression. Simplifying it again
2837 won't buy anything unless we weren't given a valid insn code
2838 to process (i.e., we are canonicalizing something.). */
2839 if (insn_code
!= -2 /* Seems wrong: && current_alternative_string. */
2840 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2841 return copy_rtx_unchanging (newexp
);
2846 /* Optimize the attribute lists by seeing if we can determine conditional
2847 values from the known values of other attributes. This will save subroutine
2848 calls during the compilation. */
2851 optimize_attrs (void)
2853 struct attr_desc
*attr
;
2854 struct attr_value
*av
;
2855 struct insn_ent
*ie
;
2858 struct attr_value_list
2860 struct attr_value
*av
;
2861 struct insn_ent
*ie
;
2862 struct attr_desc
*attr
;
2863 struct attr_value_list
*next
;
2865 struct attr_value_list
**insn_code_values
;
2866 struct attr_value_list
*ivbuf
;
2867 struct attr_value_list
*iv
;
2869 /* For each insn code, make a list of all the insn_ent's for it,
2870 for all values for all attributes. */
2872 if (num_insn_ents
== 0)
2875 /* Make 2 extra elements, for "code" values -2 and -1. */
2876 insn_code_values
= xcalloc ((insn_code_number
+ 2),
2877 sizeof (struct attr_value_list
*));
2879 /* Offset the table address so we can index by -2 or -1. */
2880 insn_code_values
+= 2;
2882 iv
= ivbuf
= xmalloc (num_insn_ents
* sizeof (struct attr_value_list
));
2884 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2885 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2886 for (av
= attr
->first_value
; av
; av
= av
->next
)
2887 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2892 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2893 insn_code_values
[ie
->def
->insn_code
] = iv
;
2897 /* Sanity check on num_insn_ents. */
2898 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2900 /* Process one insn code at a time. */
2901 for (i
= -2; i
< insn_code_number
; i
++)
2903 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2904 We use it to mean "already simplified for this insn". */
2905 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2906 clear_struct_flag (iv
->av
->value
);
2908 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2910 struct obstack
*old
= rtl_obstack
;
2915 if (GET_CODE (av
->value
) != COND
)
2918 rtl_obstack
= temp_obstack
;
2920 while (GET_CODE (newexp
) == COND
)
2922 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2923 ie
->def
->insn_index
);
2924 if (newexp2
== newexp
)
2930 if (newexp
!= av
->value
)
2932 newexp
= attr_copy_rtx (newexp
);
2933 remove_insn_ent (av
, ie
);
2934 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2936 insert_insn_ent (av
, ie
);
2942 free (insn_code_values
- 2);
2945 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2948 clear_struct_flag (rtx x
)
2955 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2956 if (ATTR_IND_SIMPLIFIED_P (x
))
2959 code
= GET_CODE (x
);
2979 /* Compare the elements. If any pair of corresponding elements
2980 fail to match, return 0 for the whole things. */
2982 fmt
= GET_RTX_FORMAT (code
);
2983 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2989 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2990 clear_struct_flag (XVECEXP (x
, i
, j
));
2994 clear_struct_flag (XEXP (x
, i
));
3000 /* Create table entries for DEFINE_ATTR. */
3003 gen_attr (rtx exp
, int lineno
)
3005 struct attr_desc
*attr
;
3006 struct attr_value
*av
;
3007 const char *name_ptr
;
3010 /* Make a new attribute structure. Check for duplicate by looking at
3011 attr->default_val, since it is initialized by this routine. */
3012 attr
= find_attr (&XSTR (exp
, 0), 1);
3013 if (attr
->default_val
)
3015 message_with_line (lineno
, "duplicate definition for attribute %s",
3017 message_with_line (attr
->lineno
, "previous definition");
3021 attr
->lineno
= lineno
;
3023 if (*XSTR (exp
, 1) == '\0')
3024 attr
->is_numeric
= 1;
3027 name_ptr
= XSTR (exp
, 1);
3028 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3030 av
= oballoc (sizeof (struct attr_value
));
3031 av
->value
= attr_rtx (CONST_STRING
, p
);
3032 av
->next
= attr
->first_value
;
3033 attr
->first_value
= av
;
3034 av
->first_insn
= NULL
;
3036 av
->has_asm_insn
= 0;
3040 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3043 if (attr
->is_numeric
)
3045 message_with_line (lineno
,
3046 "constant attributes may not take numeric values");
3050 /* Get rid of the CONST node. It is allowed only at top-level. */
3051 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3054 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3056 message_with_line (lineno
,
3057 "`length' attribute must take numeric values");
3061 /* Set up the default value. */
3062 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3063 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3066 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3067 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3068 number of alternatives as this should be checked elsewhere. */
3071 count_alternatives (rtx exp
)
3076 if (GET_CODE (exp
) == MATCH_OPERAND
)
3077 return n_comma_elts (XSTR (exp
, 2));
3079 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3080 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3085 n
= count_alternatives (XEXP (exp
, i
));
3092 if (XVEC (exp
, i
) != NULL
)
3093 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3095 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3104 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3105 `alternative' attribute. */
3108 compares_alternatives_p (rtx exp
)
3113 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3116 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3117 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3122 if (compares_alternatives_p (XEXP (exp
, i
)))
3127 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3128 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3136 /* Returns nonzero is INNER is contained in EXP. */
3139 contained_in_p (rtx inner
, rtx exp
)
3144 if (rtx_equal_p (inner
, exp
))
3147 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3148 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3153 if (contained_in_p (inner
, XEXP (exp
, i
)))
3158 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3159 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
3167 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3170 gen_insn (rtx exp
, int lineno
)
3172 struct insn_def
*id
;
3174 id
= oballoc (sizeof (struct insn_def
));
3178 id
->lineno
= lineno
;
3180 switch (GET_CODE (exp
))
3183 id
->insn_code
= insn_code_number
;
3184 id
->insn_index
= insn_index_number
;
3185 id
->num_alternatives
= count_alternatives (exp
);
3186 if (id
->num_alternatives
== 0)
3187 id
->num_alternatives
= 1;
3191 case DEFINE_PEEPHOLE
:
3192 id
->insn_code
= insn_code_number
;
3193 id
->insn_index
= insn_index_number
;
3194 id
->num_alternatives
= count_alternatives (exp
);
3195 if (id
->num_alternatives
== 0)
3196 id
->num_alternatives
= 1;
3200 case DEFINE_ASM_ATTRIBUTES
:
3202 id
->insn_index
= -1;
3203 id
->num_alternatives
= 1;
3205 got_define_asm_attributes
= 1;
3213 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3214 true or annul false is specified, and make a `struct delay_desc'. */
3217 gen_delay (rtx def
, int lineno
)
3219 struct delay_desc
*delay
;
3222 if (XVECLEN (def
, 1) % 3 != 0)
3224 message_with_line (lineno
,
3225 "number of elements in DEFINE_DELAY must be multiple of three");
3230 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3232 if (XVECEXP (def
, 1, i
+ 1))
3233 have_annul_true
= 1;
3234 if (XVECEXP (def
, 1, i
+ 2))
3235 have_annul_false
= 1;
3238 delay
= oballoc (sizeof (struct delay_desc
));
3240 delay
->num
= ++num_delays
;
3241 delay
->next
= delays
;
3242 delay
->lineno
= lineno
;
3246 /* Given a piece of RTX, print a C expression to test its truth value.
3247 We use AND and IOR both for logical and bit-wise operations, so
3248 interpret them as logical unless they are inside a comparison expression.
3249 The first bit of FLAGS will be nonzero in that case.
3251 Set the second bit of FLAGS to make references to attribute values use
3252 a cached local variable instead of calling a function. */
3255 write_test_expr (rtx exp
, int flags
)
3257 int comparison_operator
= 0;
3259 struct attr_desc
*attr
;
3261 /* In order not to worry about operator precedence, surround our part of
3262 the expression with parentheses. */
3265 code
= GET_CODE (exp
);
3268 /* Binary operators. */
3271 printf ("(unsigned) ");
3277 comparison_operator
= 1;
3279 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3280 case AND
: case IOR
: case XOR
:
3281 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3282 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3298 printf (" >= (unsigned) ");
3301 printf (" > (unsigned) ");
3310 printf (" <= (unsigned) ");
3313 printf (" < (unsigned) ");
3356 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3360 /* Special-case (not (eq_attrq "alternative" "x")) */
3361 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3362 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3364 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3368 /* Otherwise, fall through to normal unary operator. */
3370 /* Unary operators. */
3390 write_test_expr (XEXP (exp
, 0), flags
);
3395 int set
= XINT (exp
, 0), bit
= 0;
3398 fatal ("EQ_ATTR_ALT not valid inside comparison");
3401 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3403 if (!(set
& (set
- 1)))
3405 if (!(set
& 0xffff))
3428 printf ("which_alternative %s= %d",
3429 XINT (exp
, 1) ? "!" : "=", bit
);
3433 printf ("%s((1 << which_alternative) & 0x%x)",
3434 XINT (exp
, 1) ? "!" : "", set
);
3439 /* Comparison test of an attribute with a value. Most of these will
3440 have been removed by optimization. Handle "alternative"
3441 specially and give error if EQ_ATTR present inside a comparison. */
3444 fatal ("EQ_ATTR not valid inside comparison");
3446 if (XSTR (exp
, 0) == alternative_name
)
3448 printf ("which_alternative == %s", XSTR (exp
, 1));
3452 attr
= find_attr (&XSTR (exp
, 0), 0);
3455 /* Now is the time to expand the value of a constant attribute. */
3458 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3465 printf ("attr_%s", attr
->name
);
3467 printf ("get_attr_%s (insn)", attr
->name
);
3469 write_attr_valueq (attr
, XSTR (exp
, 1));
3473 /* Comparison test of flags for define_delays. */
3476 fatal ("ATTR_FLAG not valid inside comparison");
3477 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3480 /* See if an operand matches a predicate. */
3482 /* If only a mode is given, just ensure the mode matches the operand.
3483 If neither a mode nor predicate is given, error. */
3484 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3486 if (GET_MODE (exp
) == VOIDmode
)
3487 fatal ("null MATCH_OPERAND specified as test");
3489 printf ("GET_MODE (operands[%d]) == %smode",
3490 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3493 printf ("%s (operands[%d], %smode)",
3494 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3497 /* Constant integer. */
3499 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3502 /* A random C expression. */
3504 print_c_condition (XSTR (exp
, 0));
3507 /* The address of the branch target. */
3509 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3510 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3514 /* The address of the current insn. We implement this actually as the
3515 address of the current insn for backward branches, but the last
3516 address of the next insn for forward branches, and both with
3517 adjustments that account for the worst-case possible stretching of
3518 intervening alignments between this insn and its destination. */
3519 printf ("insn_current_reference_address (insn)");
3523 printf ("%s", XSTR (exp
, 0));
3527 write_test_expr (XEXP (exp
, 0), flags
& 2);
3529 write_test_expr (XEXP (exp
, 1), flags
| 1);
3531 write_test_expr (XEXP (exp
, 2), flags
| 1);
3535 fatal ("bad RTX code `%s' in attribute calculation\n",
3536 GET_RTX_NAME (code
));
3542 /* Given an attribute value, return the maximum CONST_STRING argument
3543 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3546 max_attr_value (rtx exp
, int *unknownp
)
3551 switch (GET_CODE (exp
))
3554 current_max
= atoi (XSTR (exp
, 0));
3558 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3559 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3561 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3562 if (n
> current_max
)
3568 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3569 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3570 if (n
> current_max
)
3576 current_max
= INT_MAX
;
3583 /* Given an attribute value, return the result of ORing together all
3584 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3585 if the numeric value is not known. */
3588 or_attr_value (rtx exp
, int *unknownp
)
3593 switch (GET_CODE (exp
))
3596 current_or
= atoi (XSTR (exp
, 0));
3600 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3601 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3602 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3606 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3607 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3619 /* Scan an attribute value, possibly a conditional, and record what actions
3620 will be required to do any conditional tests in it.
3623 `must_extract' if we need to extract the insn operands
3624 `must_constrain' if we must compute `which_alternative'
3625 `address_used' if an address expression was used
3626 `length_used' if an (eq_attr "length" ...) was used
3630 walk_attr_value (rtx exp
)
3639 code
= GET_CODE (exp
);
3643 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3644 /* Since this is an arbitrary expression, it can look at anything.
3645 However, constant expressions do not depend on any particular
3647 must_extract
= must_constrain
= 1;
3655 must_extract
= must_constrain
= 1;
3659 if (XSTR (exp
, 0) == alternative_name
)
3660 must_extract
= must_constrain
= 1;
3661 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3681 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3686 walk_attr_value (XEXP (exp
, i
));
3690 if (XVEC (exp
, i
) != NULL
)
3691 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3692 walk_attr_value (XVECEXP (exp
, i
, j
));
3697 /* Write out a function to obtain the attribute for a given INSN. */
3700 write_attr_get (struct attr_desc
*attr
)
3702 struct attr_value
*av
, *common_av
;
3704 /* Find the most used attribute value. Handle that as the `default' of the
3705 switch we will generate. */
3706 common_av
= find_most_used (attr
);
3708 /* Write out start of function, then all values with explicit `case' lines,
3709 then a `default', then the value with the most uses. */
3712 if (!attr
->is_numeric
)
3713 printf ("enum attr_%s\n", attr
->name
);
3717 /* If the attribute name starts with a star, the remainder is the name of
3718 the subroutine to use, instead of `get_attr_...'. */
3719 if (attr
->name
[0] == '*')
3720 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3721 else if (attr
->is_const
== 0)
3722 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3725 printf ("get_attr_%s (void)\n", attr
->name
);
3728 for (av
= attr
->first_value
; av
; av
= av
->next
)
3729 if (av
->num_insns
!= 0)
3730 write_attr_set (attr
, 2, av
->value
, "return", ";",
3731 true_rtx
, av
->first_insn
->def
->insn_code
,
3732 av
->first_insn
->def
->insn_index
);
3739 printf (" switch (recog_memoized (insn))\n");
3742 for (av
= attr
->first_value
; av
; av
= av
->next
)
3743 if (av
!= common_av
)
3744 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3746 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3747 printf (" }\n}\n\n");
3750 /* Given an AND tree of known true terms (because we are inside an `if' with
3751 that as the condition or are in an `else' clause) and an expression,
3752 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3753 the bulk of the work. */
3756 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3760 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3762 if (GET_CODE (known_true
) == AND
)
3764 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3765 insn_code
, insn_index
);
3766 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3767 insn_code
, insn_index
);
3772 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3778 /* Write out a series of tests and assignment statements to perform tests and
3779 sets of an attribute value. We are passed an indentation amount and prefix
3780 and suffix strings to write around each attribute value (e.g., "return"
3784 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3785 const char *prefix
, const char *suffix
, rtx known_true
,
3786 int insn_code
, int insn_index
)
3788 if (GET_CODE (value
) == COND
)
3790 /* Assume the default value will be the default of the COND unless we
3791 find an always true expression. */
3792 rtx default_val
= XEXP (value
, 1);
3793 rtx our_known_true
= known_true
;
3798 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3803 testexp
= eliminate_known_true (our_known_true
,
3804 XVECEXP (value
, 0, i
),
3805 insn_code
, insn_index
);
3806 newexp
= attr_rtx (NOT
, testexp
);
3807 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3808 insn_code
, insn_index
);
3810 /* If the test expression is always true or if the next `known_true'
3811 expression is always false, this is the last case, so break
3812 out and let this value be the `else' case. */
3813 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3815 default_val
= XVECEXP (value
, 0, i
+ 1);
3819 /* Compute the expression to pass to our recursive call as being
3821 inner_true
= insert_right_side (AND
, our_known_true
,
3822 testexp
, insn_code
, insn_index
);
3824 /* If this is always false, skip it. */
3825 if (inner_true
== false_rtx
)
3828 write_indent (indent
);
3829 printf ("%sif ", first_if
? "" : "else ");
3831 write_test_expr (testexp
, 0);
3833 write_indent (indent
+ 2);
3836 write_attr_set (attr
, indent
+ 4,
3837 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3838 inner_true
, insn_code
, insn_index
);
3839 write_indent (indent
+ 2);
3841 our_known_true
= newexp
;
3846 write_indent (indent
);
3848 write_indent (indent
+ 2);
3852 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
3853 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
3857 write_indent (indent
+ 2);
3863 write_indent (indent
);
3864 printf ("%s ", prefix
);
3865 write_attr_value (attr
, value
);
3866 printf ("%s\n", suffix
);
3870 /* Write a series of case statements for every instruction in list IE.
3871 INDENT is the amount of indentation to write before each case. */
3874 write_insn_cases (struct insn_ent
*ie
, int indent
)
3876 for (; ie
!= 0; ie
= ie
->next
)
3877 if (ie
->def
->insn_code
!= -1)
3879 write_indent (indent
);
3880 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
3881 printf ("case %d: /* define_peephole, line %d */\n",
3882 ie
->def
->insn_code
, ie
->def
->lineno
);
3884 printf ("case %d: /* %s */\n",
3885 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
3889 /* Write out the computation for one attribute value. */
3892 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
3893 int write_case_lines
, const char *prefix
, const char *suffix
,
3894 int indent
, rtx known_true
)
3896 if (av
->num_insns
== 0)
3899 if (av
->has_asm_insn
)
3901 write_indent (indent
);
3902 printf ("case -1:\n");
3903 write_indent (indent
+ 2);
3904 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3905 write_indent (indent
+ 2);
3906 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3907 write_indent (indent
+ 2);
3908 printf (" fatal_insn_not_found (insn);\n");
3911 if (write_case_lines
)
3912 write_insn_cases (av
->first_insn
, indent
);
3915 write_indent (indent
);
3916 printf ("default:\n");
3919 /* See what we have to do to output this value. */
3920 must_extract
= must_constrain
= address_used
= 0;
3921 walk_attr_value (av
->value
);
3925 write_indent (indent
+ 2);
3926 printf ("extract_constrain_insn_cached (insn);\n");
3928 else if (must_extract
)
3930 write_indent (indent
+ 2);
3931 printf ("extract_insn_cached (insn);\n");
3934 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3935 known_true
, av
->first_insn
->def
->insn_code
,
3936 av
->first_insn
->def
->insn_index
);
3938 if (strncmp (prefix
, "return", 6))
3940 write_indent (indent
+ 2);
3941 printf ("break;\n");
3946 /* Search for uses of non-const attributes and write code to cache them. */
3949 write_expr_attr_cache (rtx p
, struct attr_desc
*attr
)
3954 if (GET_CODE (p
) == EQ_ATTR
)
3956 if (XSTR (p
, 0) != attr
->name
)
3959 if (!attr
->is_numeric
)
3960 printf (" enum attr_%s ", attr
->name
);
3964 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
3968 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
3969 ie
= GET_RTX_LENGTH (GET_CODE (p
));
3970 for (i
= 0; i
< ie
; i
++)
3975 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
3980 je
= XVECLEN (p
, i
);
3981 for (j
= 0; j
< je
; ++j
)
3982 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
3991 /* Utilities to write in various forms. */
3994 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
3996 if (attr
->is_numeric
)
4002 if (num
> 9 || num
< 0)
4003 printf (" /* 0x%x */", num
);
4007 write_upcase (attr
->name
);
4014 write_attr_value (struct attr_desc
*attr
, rtx value
)
4018 switch (GET_CODE (value
))
4021 write_attr_valueq (attr
, XSTR (value
, 0));
4025 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4029 print_c_condition (XSTR (value
, 0));
4034 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4035 printf ("get_attr_%s (%s)", attr2
->name
,
4036 (attr2
->is_const
? "" : "insn"));
4057 write_attr_value (attr
, XEXP (value
, 0));
4061 write_attr_value (attr
, XEXP (value
, 1));
4070 write_upcase (const char *str
)
4074 /* The argument of TOUPPER should not have side effects. */
4075 putchar (TOUPPER(*str
));
4081 write_indent (int indent
)
4083 for (; indent
> 8; indent
-= 8)
4086 for (; indent
; indent
--)
4090 /* Write a subroutine that is given an insn that requires a delay slot, a
4091 delay slot ordinal, and a candidate insn. It returns nonzero if the
4092 candidate can be placed in the specified delay slot of the insn.
4094 We can write as many as three subroutines. `eligible_for_delay'
4095 handles normal delay slots, `eligible_for_annul_true' indicates that
4096 the specified insn can be annulled if the branch is true, and likewise
4097 for `eligible_for_annul_false'.
4099 KIND is a string distinguishing these three cases ("delay", "annul_true",
4100 or "annul_false"). */
4103 write_eligible_delay (const char *kind
)
4105 struct delay_desc
*delay
;
4109 struct attr_desc
*attr
;
4110 struct attr_value
*av
, *common_av
;
4113 /* Compute the maximum number of delay slots required. We use the delay
4114 ordinal times this number plus one, plus the slot number as an index into
4115 the appropriate predicate to test. */
4117 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4118 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4119 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4121 /* Write function prelude. */
4124 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4127 printf (" rtx insn;\n");
4129 printf (" gcc_assert (slot < %d);\n", max_slots
);
4131 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4132 converts a compound instruction into a loop. */
4133 printf (" if (!INSN_P (candidate_insn))\n");
4134 printf (" return 0;\n");
4137 /* If more than one delay type, find out which type the delay insn is. */
4141 attr
= find_attr (&delay_type_str
, 0);
4143 common_av
= find_most_used (attr
);
4145 printf (" insn = delay_insn;\n");
4146 printf (" switch (recog_memoized (insn))\n");
4149 sprintf (str
, " * %d;\n break;", max_slots
);
4150 for (av
= attr
->first_value
; av
; av
= av
->next
)
4151 if (av
!= common_av
)
4152 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4154 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4157 /* Ensure matched. Otherwise, shouldn't have been called. */
4158 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4161 /* If just one type of delay slot, write simple switch. */
4162 if (num_delays
== 1 && max_slots
== 1)
4164 printf (" insn = candidate_insn;\n");
4165 printf (" switch (recog_memoized (insn))\n");
4168 attr
= find_attr (&delay_1_0_str
, 0);
4170 common_av
= find_most_used (attr
);
4172 for (av
= attr
->first_value
; av
; av
= av
->next
)
4173 if (av
!= common_av
)
4174 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4176 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4182 /* Write a nested CASE. The first indicates which condition we need to
4183 test, and the inner CASE tests the condition. */
4184 printf (" insn = candidate_insn;\n");
4185 printf (" switch (slot)\n");
4188 for (delay
= delays
; delay
; delay
= delay
->next
)
4189 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4191 printf (" case %d:\n",
4192 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4193 printf (" switch (recog_memoized (insn))\n");
4196 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4198 attr
= find_attr (&pstr
, 0);
4200 common_av
= find_most_used (attr
);
4202 for (av
= attr
->first_value
; av
; av
= av
->next
)
4203 if (av
!= common_av
)
4204 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4206 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4210 printf (" default:\n");
4211 printf (" gcc_unreachable ();\n");
4218 /* This page contains miscellaneous utility routines. */
4220 /* Given a pointer to a (char *), return a malloc'ed string containing the
4221 next comma-separated element. Advance the pointer to after the string
4222 scanned, or the end-of-string. Return NULL if at end of string. */
4225 next_comma_elt (const char **pstr
)
4229 start
= scan_comma_elt (pstr
);
4234 return attr_string (start
, *pstr
- start
);
4237 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4238 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4239 replaced by a pointer to a canonical copy of the string. */
4241 static struct attr_desc
*
4242 find_attr (const char **name_p
, int create
)
4244 struct attr_desc
*attr
;
4246 const char *name
= *name_p
;
4248 /* Before we resort to using `strcmp', see if the string address matches
4249 anywhere. In most cases, it should have been canonicalized to do so. */
4250 if (name
== alternative_name
)
4253 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4254 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4255 if (name
== attr
->name
)
4258 /* Otherwise, do it the slow way. */
4259 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4260 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4262 *name_p
= attr
->name
;
4269 attr
= oballoc (sizeof (struct attr_desc
));
4270 attr
->name
= DEF_ATTR_STRING (name
);
4271 attr
->first_value
= attr
->default_val
= NULL
;
4272 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4274 attr
->next
= attrs
[index
];
4275 attrs
[index
] = attr
;
4277 *name_p
= attr
->name
;
4282 /* Create internal attribute with the given default value. */
4285 make_internal_attr (const char *name
, rtx value
, int special
)
4287 struct attr_desc
*attr
;
4289 attr
= find_attr (&name
, 1);
4290 gcc_assert (!attr
->default_val
);
4292 attr
->is_numeric
= 1;
4294 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4295 attr
->static_p
= (special
& ATTR_STATIC
) != 0;
4296 attr
->default_val
= get_attr_value (value
, attr
, -2);
4299 /* Find the most used value of an attribute. */
4301 static struct attr_value
*
4302 find_most_used (struct attr_desc
*attr
)
4304 struct attr_value
*av
;
4305 struct attr_value
*most_used
;
4311 for (av
= attr
->first_value
; av
; av
= av
->next
)
4312 if (av
->num_insns
> nuses
)
4313 nuses
= av
->num_insns
, most_used
= av
;
4318 /* Return (attr_value "n") */
4321 make_numeric_value (int n
)
4323 static rtx int_values
[20];
4327 gcc_assert (n
>= 0);
4329 if (n
< 20 && int_values
[n
])
4330 return int_values
[n
];
4332 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4333 exp
= attr_rtx (CONST_STRING
, p
);
4336 int_values
[n
] = exp
;
4342 copy_rtx_unchanging (rtx orig
)
4344 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4347 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4351 /* Determine if an insn has a constant number of delay slots, i.e., the
4352 number of delay slots is not a function of the length of the insn. */
4355 write_const_num_delay_slots (void)
4357 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4358 struct attr_value
*av
;
4362 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4364 printf (" switch (recog_memoized (insn))\n");
4367 for (av
= attr
->first_value
; av
; av
= av
->next
)
4370 walk_attr_value (av
->value
);
4372 write_insn_cases (av
->first_insn
, 4);
4375 printf (" default:\n");
4376 printf (" return 1;\n");
4377 printf (" }\n}\n\n");
4382 main (int argc
, char **argv
)
4385 struct attr_desc
*attr
;
4386 struct insn_def
*id
;
4390 progname
= "genattrtab";
4392 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
4393 return (FATAL_EXIT_CODE
);
4395 obstack_init (hash_obstack
);
4396 obstack_init (temp_obstack
);
4398 /* Set up true and false rtx's */
4399 true_rtx
= rtx_alloc (CONST_INT
);
4400 XWINT (true_rtx
, 0) = 1;
4401 false_rtx
= rtx_alloc (CONST_INT
);
4402 XWINT (false_rtx
, 0) = 0;
4403 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4404 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4406 alternative_name
= DEF_ATTR_STRING ("alternative");
4407 length_str
= DEF_ATTR_STRING ("length");
4408 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4409 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4410 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4412 printf ("/* Generated automatically by the program `genattrtab'\n\
4413 from the machine description file `md'. */\n\n");
4415 /* Read the machine description. */
4417 initiate_automaton_gen (argc
, argv
);
4422 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4426 switch (GET_CODE (desc
))
4429 case DEFINE_PEEPHOLE
:
4430 case DEFINE_ASM_ATTRIBUTES
:
4431 gen_insn (desc
, lineno
);
4435 gen_attr (desc
, lineno
);
4439 gen_delay (desc
, lineno
);
4442 case DEFINE_CPU_UNIT
:
4443 gen_cpu_unit (desc
);
4446 case DEFINE_QUERY_CPU_UNIT
:
4447 gen_query_cpu_unit (desc
);
4455 gen_excl_set (desc
);
4459 gen_presence_set (desc
);
4462 case FINAL_PRESENCE_SET
:
4463 gen_final_presence_set (desc
);
4467 gen_absence_set (desc
);
4470 case FINAL_ABSENCE_SET
:
4471 gen_final_absence_set (desc
);
4474 case DEFINE_AUTOMATON
:
4475 gen_automaton (desc
);
4478 case AUTOMATA_OPTION
:
4479 gen_automata_option (desc
);
4482 case DEFINE_RESERVATION
:
4486 case DEFINE_INSN_RESERVATION
:
4487 gen_insn_reserv (desc
);
4493 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4494 insn_index_number
++;
4498 return FATAL_EXIT_CODE
;
4502 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4503 if (! got_define_asm_attributes
)
4505 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4506 XVEC (tem
, 0) = rtvec_alloc (0);
4510 /* Expand DEFINE_DELAY information into new attribute. */
4514 /* Build DFA, output some functions and expand DFA information
4515 to new attributes. */
4519 printf ("#include \"config.h\"\n");
4520 printf ("#include \"system.h\"\n");
4521 printf ("#include \"coretypes.h\"\n");
4522 printf ("#include \"tm.h\"\n");
4523 printf ("#include \"rtl.h\"\n");
4524 printf ("#include \"tm_p.h\"\n");
4525 printf ("#include \"insn-config.h\"\n");
4526 printf ("#include \"recog.h\"\n");
4527 printf ("#include \"regs.h\"\n");
4528 printf ("#include \"real.h\"\n");
4529 printf ("#include \"output.h\"\n");
4530 printf ("#include \"insn-attr.h\"\n");
4531 printf ("#include \"toplev.h\"\n");
4532 printf ("#include \"flags.h\"\n");
4533 printf ("#include \"function.h\"\n");
4535 printf ("#define operands recog_data.operand\n\n");
4537 /* Make `insn_alternatives'. */
4538 insn_alternatives
= oballoc (insn_code_number
* sizeof (int));
4539 for (id
= defs
; id
; id
= id
->next
)
4540 if (id
->insn_code
>= 0)
4541 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4543 /* Make `insn_n_alternatives'. */
4544 insn_n_alternatives
= oballoc (insn_code_number
* sizeof (int));
4545 for (id
= defs
; id
; id
= id
->next
)
4546 if (id
->insn_code
>= 0)
4547 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4549 /* Prepare to write out attribute subroutines by checking everything stored
4550 away and building the attribute cases. */
4554 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4555 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4556 attr
->default_val
->value
4557 = check_attr_value (attr
->default_val
->value
, attr
);
4560 return FATAL_EXIT_CODE
;
4562 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4563 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4566 /* Construct extra attributes for `length'. */
4567 make_length_attrs ();
4569 /* Perform any possible optimizations to speed up compilation. */
4572 /* Now write out all the `gen_attr_...' routines. Do these before the
4573 special routines so that they get defined before they are used. */
4575 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4576 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4578 if (! attr
->is_special
&& ! attr
->is_const
)
4583 = (attr
->name
[0] == '*'
4584 && strcmp (&attr
->name
[1], INSN_ALTS_FUNC_NAME
) == 0);
4586 printf ("\n#if AUTOMATON_ALTS\n");
4587 write_attr_get (attr
);
4589 printf ("#endif\n\n");
4593 /* Write out delay eligibility information, if DEFINE_DELAY present.
4594 (The function to compute the number of delay slots will be written
4598 write_eligible_delay ("delay");
4599 if (have_annul_true
)
4600 write_eligible_delay ("annul_true");
4601 if (have_annul_false
)
4602 write_eligible_delay ("annul_false");
4605 /* Output code for pipeline hazards recognition based on DFA
4606 (deterministic finite-state automata). */
4610 /* Write out constant delay slot info. */
4611 write_const_num_delay_slots ();
4613 write_length_unit_log ();
4616 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);
4619 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
4621 get_insn_name (int code ATTRIBUTE_UNUSED
)