1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
100 #define strcmp_check(S1, S2) ((S1) == (S2) \
102 : (gcc_assert (strcmp ((S1), (S2))), 1))
104 #define strcmp_check(S1, S2) ((S1) != (S2))
109 #include "coretypes.h"
113 #include "gensupport.h"
115 #ifdef HAVE_SYS_RESOURCE_H
116 # include <sys/resource.h>
119 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
120 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
124 #include "genattrtab.h"
126 static struct obstack obstack1
, obstack2
;
127 struct obstack
*hash_obstack
= &obstack1
;
128 struct obstack
*temp_obstack
= &obstack2
;
130 /* enough space to reserve for printing out ints */
131 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
133 /* Define structures used to record attributes and values. */
135 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
136 encountered, we store all the relevant information into a
137 `struct insn_def'. This is done to allow attribute definitions to occur
138 anywhere in the file. */
142 struct insn_def
*next
; /* Next insn in chain. */
143 rtx def
; /* The DEFINE_... */
144 int insn_code
; /* Instruction number. */
145 int insn_index
; /* Expression numer in file, for errors. */
146 int lineno
; /* Line number. */
147 int num_alternatives
; /* Number of alternatives. */
148 int vec_idx
; /* Index of attribute vector in `def'. */
151 /* Once everything has been read in, we store in each attribute value a list
152 of insn codes that have that value. Here is the structure used for the
157 struct insn_ent
*next
; /* Next in chain. */
158 struct insn_def
*def
; /* Instruction definition. */
161 /* Each value of an attribute (either constant or computed) is assigned a
162 structure which is used as the listhead of the insns that have that
167 rtx value
; /* Value of attribute. */
168 struct attr_value
*next
; /* Next attribute value in chain. */
169 struct insn_ent
*first_insn
; /* First insn with this value. */
170 int num_insns
; /* Number of insns with this value. */
171 int has_asm_insn
; /* True if this value used for `asm' insns */
174 /* Structure for each attribute. */
178 char *name
; /* Name of attribute. */
179 struct attr_desc
*next
; /* Next attribute. */
180 struct attr_value
*first_value
; /* First value of this attribute. */
181 struct attr_value
*default_val
; /* Default value for this attribute. */
182 int lineno
: 24; /* Line number. */
183 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
184 unsigned is_const
: 1; /* Attribute value constant for each run. */
185 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
186 unsigned static_p
: 1; /* Make the output function static. */
189 /* Structure for each DEFINE_DELAY. */
193 rtx def
; /* DEFINE_DELAY expression. */
194 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
195 int num
; /* Number of DEFINE_DELAY, starting at 1. */
196 int lineno
; /* Line number. */
199 /* Listheads of above structures. */
201 /* This one is indexed by the first character of the attribute name. */
202 #define MAX_ATTRS_INDEX 256
203 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
204 static struct insn_def
*defs
;
205 static struct delay_desc
*delays
;
207 /* Other variables. */
209 static int insn_code_number
;
210 static int insn_index_number
;
211 static int got_define_asm_attributes
;
212 static int must_extract
;
213 static int must_constrain
;
214 static int address_used
;
215 static int length_used
;
216 static int num_delays
;
217 static int have_annul_true
, have_annul_false
;
218 static int num_insn_ents
;
222 /* Stores, for each insn code, the number of constraint alternatives. */
224 static int *insn_n_alternatives
;
226 /* Stores, for each insn code, a bitmap that has bits on for each possible
229 static int *insn_alternatives
;
231 /* Used to simplify expressions. */
233 static rtx true_rtx
, false_rtx
;
235 /* Used to reduce calls to `strcmp' */
237 static const char *alternative_name
;
238 static const char *length_str
;
239 static const char *delay_type_str
;
240 static const char *delay_1_0_str
;
241 static const char *num_delay_slots_str
;
243 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
246 int reload_completed
= 0;
248 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
249 to define it here. */
253 /* Simplify an expression. Only call the routine if there is something to
255 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
256 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
257 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
259 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
261 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
262 They won't actually be used. */
264 rtx global_rtl
[GR_MAX
];
265 rtx pic_offset_table_rtx
;
267 static void attr_hash_add_rtx (int, rtx
);
268 static void attr_hash_add_string (int, char *);
269 static rtx
attr_rtx (enum rtx_code
, ...);
270 static rtx
attr_rtx_1 (enum rtx_code
, va_list);
271 static char *attr_string (const char *, int);
272 static rtx
check_attr_value (rtx
, struct attr_desc
*);
273 static rtx
convert_set_attr_alternative (rtx
, struct insn_def
*);
274 static rtx
convert_set_attr (rtx
, struct insn_def
*);
275 static void check_defs (void);
276 static rtx
make_canonical (struct attr_desc
*, rtx
);
277 static struct attr_value
*get_attr_value (rtx
, struct attr_desc
*, int);
278 static rtx
copy_rtx_unchanging (rtx
);
279 static rtx
copy_boolean (rtx
);
280 static void expand_delays (void);
281 static void fill_attr (struct attr_desc
*);
282 static rtx
substitute_address (rtx
, rtx (*) (rtx
), rtx (*) (rtx
));
283 static void make_length_attrs (void);
284 static rtx
identity_fn (rtx
);
285 static rtx
zero_fn (rtx
);
286 static rtx
one_fn (rtx
);
287 static rtx
max_fn (rtx
);
288 static rtx
min_fn (rtx
);
289 static void write_length_unit_log (void);
290 static rtx
simplify_cond (rtx
, int, int);
291 static void clear_struct_flag (rtx
);
292 static void remove_insn_ent (struct attr_value
*, struct insn_ent
*);
293 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
294 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
295 static rtx
make_alternative_compare (int);
296 static int compute_alternative_mask (rtx
, enum rtx_code
);
297 static rtx
evaluate_eq_attr (rtx
, rtx
, int, int);
298 static rtx
simplify_and_tree (rtx
, rtx
*, int, int);
299 static rtx
simplify_or_tree (rtx
, rtx
*, int, int);
300 static rtx
simplify_test_exp (rtx
, int, int);
301 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
302 static void optimize_attrs (void);
303 static void gen_attr (rtx
, int);
304 static int count_alternatives (rtx
);
305 static int compares_alternatives_p (rtx
);
306 static int contained_in_p (rtx
, rtx
);
307 static void gen_insn (rtx
, int);
308 static void gen_delay (rtx
, int);
309 static void write_test_expr (rtx
, int);
310 static int max_attr_value (rtx
, int*);
311 static int min_attr_value (rtx
, int*);
312 static int or_attr_value (rtx
, int*);
313 static void walk_attr_value (rtx
);
314 static void write_attr_get (struct attr_desc
*);
315 static rtx
eliminate_known_true (rtx
, rtx
, int, int);
316 static void write_attr_set (struct attr_desc
*, int, rtx
,
317 const char *, const char *, rtx
,
319 static void write_insn_cases (struct insn_ent
*, int);
320 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
321 int, const char *, const char *, int, rtx
);
322 static void write_attr_valueq (struct attr_desc
*, const char *);
323 static void write_attr_value (struct attr_desc
*, rtx
);
324 static void write_upcase (const char *);
325 static void write_indent (int);
326 static void write_eligible_delay (const char *);
327 static int write_expr_attr_cache (rtx
, struct attr_desc
*);
328 static void write_const_num_delay_slots (void);
329 static char *next_comma_elt (const char **);
330 static struct attr_desc
*find_attr (const char **, int);
331 static struct attr_value
*find_most_used (struct attr_desc
*);
332 static rtx
attr_eq (const char *, const char *);
333 static const char *attr_numeral (int);
334 static int attr_equal_p (rtx
, rtx
);
335 static rtx
attr_copy_rtx (rtx
);
336 static int attr_rtx_cost (rtx
);
337 static bool attr_alt_subset_p (rtx
, rtx
);
338 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
339 static rtx
attr_alt_intersection (rtx
, rtx
);
340 static rtx
attr_alt_union (rtx
, rtx
);
341 static rtx
attr_alt_complement (rtx
);
342 static rtx
mk_attr_alt (int);
344 #define oballoc(size) obstack_alloc (hash_obstack, size)
346 /* Hash table for sharing RTL and strings. */
348 /* Each hash table slot is a bucket containing a chain of these structures.
349 Strings are given negative hash codes; RTL expressions are given positive
354 struct attr_hash
*next
; /* Next structure in the bucket. */
355 int hashcode
; /* Hash code of this rtx or string. */
358 char *str
; /* The string (negative hash codes) */
359 rtx rtl
; /* or the RTL recorded here. */
363 /* Now here is the hash table. When recording an RTL, it is added to
364 the slot whose index is the hash code mod the table size. Note
365 that the hash table is used for several kinds of RTL (see attr_rtx)
366 and for strings. While all these live in the same table, they are
367 completely independent, and the hash code is computed differently
370 #define RTL_HASH_SIZE 4093
371 struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
373 /* Here is how primitive or already-shared RTL's hash
375 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
377 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
380 attr_hash_add_rtx (int hashcode
, rtx rtl
)
384 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
385 h
->hashcode
= hashcode
;
387 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
388 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
391 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
394 attr_hash_add_string (int hashcode
, char *str
)
398 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
399 h
->hashcode
= -hashcode
;
401 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
402 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
405 /* Generate an RTL expression, but avoid duplicates.
406 Set the ATTR_PERMANENT_P flag for these permanent objects.
408 In some cases we cannot uniquify; then we return an ordinary
409 impermanent rtx with ATTR_PERMANENT_P clear.
413 rtx attr_rtx (code, [element1, ..., elementn]) */
416 attr_rtx_1 (enum rtx_code code
, va_list p
)
418 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
421 struct obstack
*old_obstack
= rtl_obstack
;
423 /* For each of several cases, search the hash table for an existing entry.
424 Use that entry if one is found; otherwise create a new RTL and add it
427 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
429 rtx arg0
= va_arg (p
, rtx
);
431 /* A permanent object cannot point to impermanent ones. */
432 if (! ATTR_PERMANENT_P (arg0
))
434 rt_val
= rtx_alloc (code
);
435 XEXP (rt_val
, 0) = arg0
;
439 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
440 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
441 if (h
->hashcode
== hashcode
442 && GET_CODE (h
->u
.rtl
) == code
443 && XEXP (h
->u
.rtl
, 0) == arg0
)
448 rtl_obstack
= hash_obstack
;
449 rt_val
= rtx_alloc (code
);
450 XEXP (rt_val
, 0) = arg0
;
453 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
454 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
455 || GET_RTX_CLASS (code
) == RTX_COMPARE
456 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
458 rtx arg0
= va_arg (p
, rtx
);
459 rtx arg1
= va_arg (p
, rtx
);
461 /* A permanent object cannot point to impermanent ones. */
462 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
464 rt_val
= rtx_alloc (code
);
465 XEXP (rt_val
, 0) = arg0
;
466 XEXP (rt_val
, 1) = arg1
;
470 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
471 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
472 if (h
->hashcode
== hashcode
473 && GET_CODE (h
->u
.rtl
) == code
474 && XEXP (h
->u
.rtl
, 0) == arg0
475 && XEXP (h
->u
.rtl
, 1) == arg1
)
480 rtl_obstack
= hash_obstack
;
481 rt_val
= rtx_alloc (code
);
482 XEXP (rt_val
, 0) = arg0
;
483 XEXP (rt_val
, 1) = arg1
;
486 else if (GET_RTX_LENGTH (code
) == 1
487 && GET_RTX_FORMAT (code
)[0] == 's')
489 char *arg0
= va_arg (p
, char *);
491 arg0
= DEF_ATTR_STRING (arg0
);
493 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
494 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
495 if (h
->hashcode
== hashcode
496 && GET_CODE (h
->u
.rtl
) == code
497 && XSTR (h
->u
.rtl
, 0) == arg0
)
502 rtl_obstack
= hash_obstack
;
503 rt_val
= rtx_alloc (code
);
504 XSTR (rt_val
, 0) = arg0
;
507 else if (GET_RTX_LENGTH (code
) == 2
508 && GET_RTX_FORMAT (code
)[0] == 's'
509 && GET_RTX_FORMAT (code
)[1] == 's')
511 char *arg0
= va_arg (p
, char *);
512 char *arg1
= va_arg (p
, char *);
514 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
515 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
516 if (h
->hashcode
== hashcode
517 && GET_CODE (h
->u
.rtl
) == code
518 && XSTR (h
->u
.rtl
, 0) == arg0
519 && XSTR (h
->u
.rtl
, 1) == arg1
)
524 rtl_obstack
= hash_obstack
;
525 rt_val
= rtx_alloc (code
);
526 XSTR (rt_val
, 0) = arg0
;
527 XSTR (rt_val
, 1) = arg1
;
530 else if (code
== CONST_INT
)
532 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
542 int i
; /* Array indices... */
543 const char *fmt
; /* Current rtx's format... */
545 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
547 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
548 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
552 case '0': /* Unused field. */
555 case 'i': /* An integer? */
556 XINT (rt_val
, i
) = va_arg (p
, int);
559 case 'w': /* A wide integer? */
560 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
563 case 's': /* A string? */
564 XSTR (rt_val
, i
) = va_arg (p
, char *);
567 case 'e': /* An expression? */
568 case 'u': /* An insn? Same except when printing. */
569 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
572 case 'E': /* An RTX vector? */
573 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
583 rtl_obstack
= old_obstack
;
584 attr_hash_add_rtx (hashcode
, rt_val
);
585 ATTR_PERMANENT_P (rt_val
) = 1;
590 attr_rtx (enum rtx_code code
, ...)
596 result
= attr_rtx_1 (code
, p
);
601 /* Create a new string printed with the printf line arguments into a space
602 of at most LEN bytes:
604 rtx attr_printf (len, format, [arg1, ..., argn]) */
607 attr_printf (unsigned int len
, const char *fmt
, ...)
614 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
616 vsprintf (str
, fmt
, p
);
619 return DEF_ATTR_STRING (str
);
623 attr_eq (const char *name
, const char *value
)
625 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
631 return XSTR (make_numeric_value (n
), 0);
634 /* Return a permanent (possibly shared) copy of a string STR (not assumed
635 to be null terminated) with LEN bytes. */
638 attr_string (const char *str
, int len
)
645 /* Compute the hash code. */
646 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
647 for (i
= 1; i
<= len
; i
+= 2)
648 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
650 hashcode
= -hashcode
;
652 /* Search the table for the string. */
653 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
654 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
655 && !strncmp (h
->u
.str
, str
, len
))
656 return h
->u
.str
; /* <-- return if found. */
658 /* Not found; create a permanent copy and add it to the hash table. */
659 new_str
= obstack_alloc (hash_obstack
, len
+ 1);
660 memcpy (new_str
, str
, len
);
662 attr_hash_add_string (hashcode
, new_str
);
664 return new_str
; /* Return the new string. */
667 /* Check two rtx's for equality of contents,
668 taking advantage of the fact that if both are hashed
669 then they can't be equal unless they are the same object. */
672 attr_equal_p (rtx x
, rtx y
)
674 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
675 && rtx_equal_p (x
, y
)));
678 /* Copy an attribute value expression,
679 descending to all depths, but not copying any
680 permanent hashed subexpressions. */
683 attr_copy_rtx (rtx orig
)
688 const char *format_ptr
;
690 /* No need to copy a permanent object. */
691 if (ATTR_PERMANENT_P (orig
))
694 code
= GET_CODE (orig
);
712 copy
= rtx_alloc (code
);
713 PUT_MODE (copy
, GET_MODE (orig
));
714 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
715 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
716 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
718 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
720 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
722 switch (*format_ptr
++)
725 XEXP (copy
, i
) = XEXP (orig
, i
);
726 if (XEXP (orig
, i
) != NULL
)
727 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
732 XVEC (copy
, i
) = XVEC (orig
, i
);
733 if (XVEC (orig
, i
) != NULL
)
735 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
736 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
737 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
743 XINT (copy
, i
) = XINT (orig
, i
);
747 XWINT (copy
, i
) = XWINT (orig
, i
);
752 XSTR (copy
, i
) = XSTR (orig
, i
);
762 /* Given a test expression for an attribute, ensure it is validly formed.
763 IS_CONST indicates whether the expression is constant for each compiler
764 run (a constant expression may not test any particular insn).
766 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
767 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
768 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
770 Update the string address in EQ_ATTR expression to be the same used
771 in the attribute (or `alternative_name') to speed up subsequent
772 `find_attr' calls and eliminate most `strcmp' calls.
774 Return the new expression, if any. */
777 check_attr_test (rtx exp
, int is_const
, int lineno
)
779 struct attr_desc
*attr
;
780 struct attr_value
*av
;
781 const char *name_ptr
, *p
;
784 switch (GET_CODE (exp
))
787 /* Handle negation test. */
788 if (XSTR (exp
, 1)[0] == '!')
789 return check_attr_test (attr_rtx (NOT
,
790 attr_eq (XSTR (exp
, 0),
794 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
796 attr
= find_attr (&XSTR (exp
, 0), 0);
799 if (! strcmp (XSTR (exp
, 0), "alternative"))
800 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
802 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
805 if (is_const
&& ! attr
->is_const
)
806 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
809 /* Copy this just to make it permanent,
810 so expressions using it can be permanent too. */
811 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
813 /* It shouldn't be possible to simplify the value given to a
814 constant attribute, so don't expand this until it's time to
815 write the test expression. */
817 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
819 if (attr
->is_numeric
)
821 for (p
= XSTR (exp
, 1); *p
; p
++)
823 fatal ("attribute `%s' takes only numeric values",
828 for (av
= attr
->first_value
; av
; av
= av
->next
)
829 if (GET_CODE (av
->value
) == CONST_STRING
830 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
834 fatal ("unknown value `%s' for `%s' attribute",
835 XSTR (exp
, 1), XSTR (exp
, 0));
840 if (! strcmp (XSTR (exp
, 0), "alternative"))
844 name_ptr
= XSTR (exp
, 1);
845 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
846 set
|= 1 << atoi (p
);
848 return mk_attr_alt (set
);
852 /* Make an IOR tree of the possible values. */
854 name_ptr
= XSTR (exp
, 1);
855 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
857 newexp
= attr_eq (XSTR (exp
, 0), p
);
858 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
861 return check_attr_test (orexp
, is_const
, lineno
);
870 /* Either TRUE or FALSE. */
878 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
879 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
883 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
888 fatal ("RTL operator \"%s\" not valid in constant attribute test",
889 GET_RTX_NAME (GET_CODE (exp
)));
890 /* These cases can't be simplified. */
891 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
894 case LE
: case LT
: case GT
: case GE
:
895 case LEU
: case LTU
: case GTU
: case GEU
:
897 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
898 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
899 exp
= attr_rtx (GET_CODE (exp
),
900 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
901 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
902 /* These cases can't be simplified. */
903 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
909 /* These cases are valid for constant attributes, but can't be
911 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
912 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
916 fatal ("RTL operator \"%s\" not valid in attribute test",
917 GET_RTX_NAME (GET_CODE (exp
)));
923 /* Given an expression, ensure that it is validly formed and that all named
924 attribute values are valid for the given attribute. Issue a fatal error
925 if not. If no attribute is specified, assume a numeric attribute.
927 Return a perhaps modified replacement expression for the value. */
930 check_attr_value (rtx exp
, struct attr_desc
*attr
)
932 struct attr_value
*av
;
936 switch (GET_CODE (exp
))
939 if (attr
&& ! attr
->is_numeric
)
941 message_with_line (attr
->lineno
,
942 "CONST_INT not valid for non-numeric attribute %s",
948 if (INTVAL (exp
) < 0)
950 message_with_line (attr
->lineno
,
951 "negative numeric value specified for attribute %s",
959 if (! strcmp (XSTR (exp
, 0), "*"))
962 if (attr
== 0 || attr
->is_numeric
)
968 message_with_line (attr
? attr
->lineno
: 0,
969 "non-numeric value for numeric attribute %s",
970 attr
? attr
->name
: "internal");
977 for (av
= attr
->first_value
; av
; av
= av
->next
)
978 if (GET_CODE (av
->value
) == CONST_STRING
979 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
984 message_with_line (attr
->lineno
,
985 "unknown value `%s' for `%s' attribute",
986 XSTR (exp
, 0), attr
? attr
->name
: "internal");
992 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
993 attr
? attr
->is_const
: 0,
994 attr
? attr
->lineno
: 0);
995 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
996 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
1004 if (attr
&& !attr
->is_numeric
)
1006 message_with_line (attr
->lineno
,
1007 "invalid operation `%s' for non-numeric attribute value",
1008 GET_RTX_NAME (GET_CODE (exp
)));
1016 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1017 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1025 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1029 if (XVECLEN (exp
, 0) % 2 != 0)
1031 message_with_line (attr
->lineno
,
1032 "first operand of COND must have even length");
1037 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1039 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1040 attr
? attr
->is_const
: 0,
1041 attr
? attr
->lineno
: 0);
1042 XVECEXP (exp
, 0, i
+ 1)
1043 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1046 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1051 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1054 message_with_line (attr
? attr
->lineno
: 0,
1055 "unknown attribute `%s' in ATTR",
1059 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1061 message_with_line (attr
->lineno
,
1062 "non-constant attribute `%s' referenced from `%s'",
1063 XSTR (exp
, 0), attr
->name
);
1067 && attr
->is_numeric
!= attr2
->is_numeric
)
1069 message_with_line (attr
->lineno
,
1070 "numeric attribute mismatch calling `%s' from `%s'",
1071 XSTR (exp
, 0), attr
->name
);
1078 /* A constant SYMBOL_REF is valid as a constant attribute test and
1079 is expanded later by make_canonical into a COND. In a non-constant
1080 attribute test, it is left be. */
1081 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1084 message_with_line (attr
? attr
->lineno
: 0,
1085 "invalid operation `%s' for attribute value",
1086 GET_RTX_NAME (GET_CODE (exp
)));
1094 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1095 It becomes a COND with each test being (eq_attr "alternative" "n") */
1098 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1100 int num_alt
= id
->num_alternatives
;
1104 if (XVECLEN (exp
, 1) != num_alt
)
1106 message_with_line (id
->lineno
,
1107 "bad number of entries in SET_ATTR_ALTERNATIVE");
1112 /* Make a COND with all tests but the last. Select the last value via the
1114 condexp
= rtx_alloc (COND
);
1115 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1117 for (i
= 0; i
< num_alt
- 1; i
++)
1120 p
= attr_numeral (i
);
1122 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1123 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1126 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1128 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1131 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1132 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1135 convert_set_attr (rtx exp
, struct insn_def
*id
)
1138 const char *name_ptr
;
1142 /* See how many alternative specified. */
1143 n
= n_comma_elts (XSTR (exp
, 1));
1145 return attr_rtx (SET
,
1146 attr_rtx (ATTR
, XSTR (exp
, 0)),
1147 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1149 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1150 XSTR (newexp
, 0) = XSTR (exp
, 0);
1151 XVEC (newexp
, 1) = rtvec_alloc (n
);
1153 /* Process each comma-separated name. */
1154 name_ptr
= XSTR (exp
, 1);
1156 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1157 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1159 return convert_set_attr_alternative (newexp
, id
);
1162 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1163 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1169 struct insn_def
*id
;
1170 struct attr_desc
*attr
;
1174 for (id
= defs
; id
; id
= id
->next
)
1176 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1179 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1181 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1182 switch (GET_CODE (value
))
1185 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1187 message_with_line (id
->lineno
, "bad attribute set");
1193 case SET_ATTR_ALTERNATIVE
:
1194 value
= convert_set_attr_alternative (value
, id
);
1198 value
= convert_set_attr (value
, id
);
1202 message_with_line (id
->lineno
, "invalid attribute code %s",
1203 GET_RTX_NAME (GET_CODE (value
)));
1207 if (value
== NULL_RTX
)
1210 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1212 message_with_line (id
->lineno
, "unknown attribute %s",
1213 XSTR (XEXP (value
, 0), 0));
1218 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1219 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1224 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1225 expressions by converting them into a COND. This removes cases from this
1226 program. Also, replace an attribute value of "*" with the default attribute
1230 make_canonical (struct attr_desc
*attr
, rtx exp
)
1235 switch (GET_CODE (exp
))
1238 exp
= make_numeric_value (INTVAL (exp
));
1242 if (! strcmp (XSTR (exp
, 0), "*"))
1244 if (attr
== 0 || attr
->default_val
== 0)
1245 fatal ("(attr_value \"*\") used in invalid context");
1246 exp
= attr
->default_val
->value
;
1249 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1254 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1256 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1257 This makes the COND something that won't be considered an arbitrary
1258 expression by walk_attr_value. */
1259 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1260 exp
= check_attr_value (exp
, attr
);
1264 newexp
= rtx_alloc (COND
);
1265 XVEC (newexp
, 0) = rtvec_alloc (2);
1266 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1267 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1269 XEXP (newexp
, 1) = XEXP (exp
, 2);
1272 /* Fall through to COND case since this is now a COND. */
1279 /* First, check for degenerate COND. */
1280 if (XVECLEN (exp
, 0) == 0)
1281 return make_canonical (attr
, XEXP (exp
, 1));
1282 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1284 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1286 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1287 XVECEXP (exp
, 0, i
+ 1)
1288 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1289 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1305 copy_boolean (rtx exp
)
1307 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1308 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1309 copy_boolean (XEXP (exp
, 1)));
1310 if (GET_CODE (exp
) == MATCH_OPERAND
)
1312 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1313 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1315 else if (GET_CODE (exp
) == EQ_ATTR
)
1317 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1318 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1324 /* Given a value and an attribute description, return a `struct attr_value *'
1325 that represents that value. This is either an existing structure, if the
1326 value has been previously encountered, or a newly-created structure.
1328 `insn_code' is the code of an insn whose attribute has the specified
1329 value (-2 if not processing an insn). We ensure that all insns for
1330 a given value have the same number of alternatives if the value checks
1333 static struct attr_value
*
1334 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1336 struct attr_value
*av
;
1339 value
= make_canonical (attr
, value
);
1340 if (compares_alternatives_p (value
))
1342 if (insn_code
< 0 || insn_alternatives
== NULL
)
1343 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1345 num_alt
= insn_alternatives
[insn_code
];
1348 for (av
= attr
->first_value
; av
; av
= av
->next
)
1349 if (rtx_equal_p (value
, av
->value
)
1350 && (num_alt
== 0 || av
->first_insn
== NULL
1351 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1354 av
= oballoc (sizeof (struct attr_value
));
1356 av
->next
= attr
->first_value
;
1357 attr
->first_value
= av
;
1358 av
->first_insn
= NULL
;
1360 av
->has_asm_insn
= 0;
1365 /* After all DEFINE_DELAYs have been read in, create internal attributes
1366 to generate the required routines.
1368 First, we compute the number of delay slots for each insn (as a COND of
1369 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1370 delay type is specified, we compute a similar function giving the
1371 DEFINE_DELAY ordinal for each insn.
1373 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1374 tells whether a given insn can be in that delay slot.
1376 Normal attribute filling and optimization expands these to contain the
1377 information needed to handle delay slots. */
1380 expand_delays (void)
1382 struct delay_desc
*delay
;
1388 /* First, generate data for `num_delay_slots' function. */
1390 condexp
= rtx_alloc (COND
);
1391 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1392 XEXP (condexp
, 1) = make_numeric_value (0);
1394 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1396 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1397 XVECEXP (condexp
, 0, i
+ 1)
1398 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1401 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1403 /* If more than one delay type, do the same for computing the delay type. */
1406 condexp
= rtx_alloc (COND
);
1407 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1408 XEXP (condexp
, 1) = make_numeric_value (0);
1410 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1412 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1413 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1416 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1419 /* For each delay possibility and delay slot, compute an eligibility
1420 attribute for non-annulled insns and for each type of annulled (annul
1421 if true and annul if false). */
1422 for (delay
= delays
; delay
; delay
= delay
->next
)
1424 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1426 condexp
= XVECEXP (delay
->def
, 1, i
);
1428 condexp
= false_rtx
;
1429 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1430 make_numeric_value (1), make_numeric_value (0));
1432 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1433 "*delay_%d_%d", delay
->num
, i
/ 3);
1434 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1436 if (have_annul_true
)
1438 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1439 if (condexp
== 0) condexp
= false_rtx
;
1440 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1441 make_numeric_value (1),
1442 make_numeric_value (0));
1443 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1444 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1445 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1448 if (have_annul_false
)
1450 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1451 if (condexp
== 0) condexp
= false_rtx
;
1452 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1453 make_numeric_value (1),
1454 make_numeric_value (0));
1455 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1456 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1457 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1463 /* Once all attributes and insns have been read and checked, we construct for
1464 each attribute value a list of all the insns that have that value for
1468 fill_attr (struct attr_desc
*attr
)
1470 struct attr_value
*av
;
1471 struct insn_ent
*ie
;
1472 struct insn_def
*id
;
1476 /* Don't fill constant attributes. The value is independent of
1477 any particular insn. */
1481 for (id
= defs
; id
; id
= id
->next
)
1483 /* If no value is specified for this insn for this attribute, use the
1486 if (XVEC (id
->def
, id
->vec_idx
))
1487 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1488 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1490 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1493 av
= attr
->default_val
;
1495 av
= get_attr_value (value
, attr
, id
->insn_code
);
1497 ie
= oballoc (sizeof (struct insn_ent
));
1499 insert_insn_ent (av
, ie
);
1503 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1504 test that checks relative positions of insns (uses MATCH_DUP or PC).
1505 If so, replace it with what is obtained by passing the expression to
1506 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1507 recursively on each value (including the default value). Otherwise,
1508 return the value returned by NO_ADDRESS_FN applied to EXP. */
1511 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1512 rtx (*address_fn
) (rtx
))
1517 if (GET_CODE (exp
) == COND
)
1519 /* See if any tests use addresses. */
1521 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1522 walk_attr_value (XVECEXP (exp
, 0, i
));
1525 return (*address_fn
) (exp
);
1527 /* Make a new copy of this COND, replacing each element. */
1528 newexp
= rtx_alloc (COND
);
1529 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1530 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1532 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1533 XVECEXP (newexp
, 0, i
+ 1)
1534 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1535 no_address_fn
, address_fn
);
1538 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1539 no_address_fn
, address_fn
);
1544 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1547 walk_attr_value (XEXP (exp
, 0));
1549 return (*address_fn
) (exp
);
1551 return attr_rtx (IF_THEN_ELSE
,
1552 substitute_address (XEXP (exp
, 0),
1553 no_address_fn
, address_fn
),
1554 substitute_address (XEXP (exp
, 1),
1555 no_address_fn
, address_fn
),
1556 substitute_address (XEXP (exp
, 2),
1557 no_address_fn
, address_fn
));
1560 return (*no_address_fn
) (exp
);
1563 /* Make new attributes from the `length' attribute. The following are made,
1564 each corresponding to a function called from `shorten_branches' or
1567 *insn_default_length This is the length of the insn to be returned
1568 by `get_attr_length' before `shorten_branches'
1569 has been called. In each case where the length
1570 depends on relative addresses, the largest
1571 possible is used. This routine is also used
1572 to compute the initial size of the insn.
1574 *insn_variable_length_p This returns 1 if the insn's length depends
1575 on relative addresses, zero otherwise.
1577 *insn_current_length This is only called when it is known that the
1578 insn has a variable length and returns the
1579 current length, based on relative addresses.
1583 make_length_attrs (void)
1585 static const char *new_names
[] =
1587 "*insn_default_length",
1589 "*insn_variable_length_p",
1590 "*insn_current_length"
1592 static rtx (*const no_address_fn
[]) (rtx
)
1593 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1594 static rtx (*const address_fn
[]) (rtx
)
1595 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1597 struct attr_desc
*length_attr
, *new_attr
;
1598 struct attr_value
*av
, *new_av
;
1599 struct insn_ent
*ie
, *new_ie
;
1601 /* See if length attribute is defined. If so, it must be numeric. Make
1602 it special so we don't output anything for it. */
1603 length_attr
= find_attr (&length_str
, 0);
1604 if (length_attr
== 0)
1607 if (! length_attr
->is_numeric
)
1608 fatal ("length attribute must be numeric");
1610 length_attr
->is_const
= 0;
1611 length_attr
->is_special
= 1;
1613 /* Make each new attribute, in turn. */
1614 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1616 make_internal_attr (new_names
[i
],
1617 substitute_address (length_attr
->default_val
->value
,
1618 no_address_fn
[i
], address_fn
[i
]),
1620 new_attr
= find_attr (&new_names
[i
], 0);
1621 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1622 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1624 new_av
= get_attr_value (substitute_address (av
->value
,
1627 new_attr
, ie
->def
->insn_code
);
1628 new_ie
= oballoc (sizeof (struct insn_ent
));
1629 new_ie
->def
= ie
->def
;
1630 insert_insn_ent (new_av
, new_ie
);
1635 /* Utility functions called from above routine. */
1638 identity_fn (rtx exp
)
1644 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1646 return make_numeric_value (0);
1650 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1652 return make_numeric_value (1);
1659 return make_numeric_value (max_attr_value (exp
, &unknown
));
1666 return make_numeric_value (min_attr_value (exp
, &unknown
));
1670 write_length_unit_log (void)
1672 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1673 struct attr_value
*av
;
1674 struct insn_ent
*ie
;
1675 unsigned int length_unit_log
, length_or
;
1678 if (length_attr
== 0)
1680 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1681 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1682 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1683 length_or
|= or_attr_value (av
->value
, &unknown
);
1686 length_unit_log
= 0;
1689 length_or
= ~length_or
;
1690 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1693 printf ("int length_unit_log = %u;\n", length_unit_log
);
1696 /* Take a COND expression and see if any of the conditions in it can be
1697 simplified. If any are known true or known false for the particular insn
1698 code, the COND can be further simplified.
1700 Also call ourselves on any COND operations that are values of this COND.
1702 We do not modify EXP; rather, we make and return a new rtx. */
1705 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1708 /* We store the desired contents here,
1709 then build a new expression if they don't match EXP. */
1710 rtx defval
= XEXP (exp
, 1);
1711 rtx new_defval
= XEXP (exp
, 1);
1712 int len
= XVECLEN (exp
, 0);
1713 rtx
*tests
= xmalloc (len
* sizeof (rtx
));
1717 /* This lets us free all storage allocated below, if appropriate. */
1718 obstack_finish (rtl_obstack
);
1720 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1722 /* See if default value needs simplification. */
1723 if (GET_CODE (defval
) == COND
)
1724 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1726 /* Simplify the subexpressions, and see what tests we can get rid of. */
1728 for (i
= 0; i
< len
; i
+= 2)
1730 rtx newtest
, newval
;
1732 /* Simplify this test. */
1733 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1736 newval
= tests
[i
+ 1];
1737 /* See if this value may need simplification. */
1738 if (GET_CODE (newval
) == COND
)
1739 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1741 /* Look for ways to delete or combine this test. */
1742 if (newtest
== true_rtx
)
1744 /* If test is true, make this value the default
1745 and discard this + any following tests. */
1747 defval
= tests
[i
+ 1];
1748 new_defval
= newval
;
1751 else if (newtest
== false_rtx
)
1753 /* If test is false, discard it and its value. */
1754 for (j
= i
; j
< len
- 2; j
++)
1755 tests
[j
] = tests
[j
+ 2];
1760 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1762 /* If this value and the value for the prev test are the same,
1766 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1767 insn_code
, insn_index
);
1769 /* Delete this test/value. */
1770 for (j
= i
; j
< len
- 2; j
++)
1771 tests
[j
] = tests
[j
+ 2];
1777 tests
[i
+ 1] = newval
;
1780 /* If the last test in a COND has the same value
1781 as the default value, that test isn't needed. */
1783 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1786 /* See if we changed anything. */
1787 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1790 for (i
= 0; i
< len
; i
++)
1791 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1799 if (GET_CODE (defval
) == COND
)
1800 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1808 rtx newexp
= rtx_alloc (COND
);
1810 XVEC (newexp
, 0) = rtvec_alloc (len
);
1811 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1812 XEXP (newexp
, 1) = new_defval
;
1819 /* Remove an insn entry from an attribute value. */
1822 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1824 struct insn_ent
*previe
;
1826 if (av
->first_insn
== ie
)
1827 av
->first_insn
= ie
->next
;
1830 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1832 previe
->next
= ie
->next
;
1836 if (ie
->def
->insn_code
== -1)
1837 av
->has_asm_insn
= 0;
1842 /* Insert an insn entry in an attribute value list. */
1845 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1847 ie
->next
= av
->first_insn
;
1848 av
->first_insn
= ie
;
1850 if (ie
->def
->insn_code
== -1)
1851 av
->has_asm_insn
= 1;
1856 /* This is a utility routine to take an expression that is a tree of either
1857 AND or IOR expressions and insert a new term. The new term will be
1858 inserted at the right side of the first node whose code does not match
1859 the root. A new node will be created with the root's code. Its left
1860 side will be the old right side and its right side will be the new
1863 If the `term' is itself a tree, all its leaves will be inserted. */
1866 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1870 /* Avoid consing in some special cases. */
1871 if (code
== AND
&& term
== true_rtx
)
1873 if (code
== AND
&& term
== false_rtx
)
1875 if (code
== AND
&& exp
== true_rtx
)
1877 if (code
== AND
&& exp
== false_rtx
)
1879 if (code
== IOR
&& term
== true_rtx
)
1881 if (code
== IOR
&& term
== false_rtx
)
1883 if (code
== IOR
&& exp
== true_rtx
)
1885 if (code
== IOR
&& exp
== false_rtx
)
1887 if (attr_equal_p (exp
, term
))
1890 if (GET_CODE (term
) == code
)
1892 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1893 insn_code
, insn_index
);
1894 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1895 insn_code
, insn_index
);
1900 if (GET_CODE (exp
) == code
)
1902 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1903 term
, insn_code
, insn_index
);
1904 if (new != XEXP (exp
, 1))
1905 /* Make a copy of this expression and call recursively. */
1906 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1912 /* Insert the new term. */
1913 newexp
= attr_rtx (code
, exp
, term
);
1916 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1919 /* If we have an expression which AND's a bunch of
1920 (not (eq_attrq "alternative" "n"))
1921 terms, we may have covered all or all but one of the possible alternatives.
1922 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1924 This routine is passed an expression and either AND or IOR. It returns a
1925 bitmask indicating which alternatives are mentioned within EXP. */
1928 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1931 if (GET_CODE (exp
) == code
)
1932 return compute_alternative_mask (XEXP (exp
, 0), code
)
1933 | compute_alternative_mask (XEXP (exp
, 1), code
);
1935 else if (code
== AND
&& GET_CODE (exp
) == NOT
1936 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1937 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1938 string
= XSTR (XEXP (exp
, 0), 1);
1940 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1941 && XSTR (exp
, 0) == alternative_name
)
1942 string
= XSTR (exp
, 1);
1944 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1946 if (code
== AND
&& XINT (exp
, 1))
1947 return XINT (exp
, 0);
1949 if (code
== IOR
&& !XINT (exp
, 1))
1950 return XINT (exp
, 0);
1958 return 1 << (string
[0] - '0');
1959 return 1 << atoi (string
);
1962 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1963 attribute with the value represented by that bit. */
1966 make_alternative_compare (int mask
)
1968 return mk_attr_alt (mask
);
1971 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1972 of "attr" for this insn code. From that value, we can compute a test
1973 showing when the EQ_ATTR will be true. This routine performs that
1974 computation. If a test condition involves an address, we leave the EQ_ATTR
1975 intact because addresses are only valid for the `length' attribute.
1977 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1978 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1981 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
1988 switch (GET_CODE (value
))
1991 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2002 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2003 gcc_assert (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2
2006 strcpy (string
, XSTR (exp
, 0));
2007 strcat (string
, "_");
2008 strcat (string
, XSTR (exp
, 1));
2009 for (p
= string
; *p
; p
++)
2012 newexp
= attr_rtx (EQ
, value
,
2013 attr_rtx (SYMBOL_REF
,
2014 DEF_ATTR_STRING (string
)));
2019 /* We construct an IOR of all the cases for which the
2020 requested attribute value is present. Since we start with
2021 FALSE, if it is not present, FALSE will be returned.
2023 Each case is the AND of the NOT's of the previous conditions with the
2024 current condition; in the default case the current condition is TRUE.
2026 For each possible COND value, call ourselves recursively.
2028 The extra TRUE and FALSE expressions will be eliminated by another
2029 call to the simplification routine. */
2034 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2036 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2037 insn_code
, insn_index
);
2039 right
= insert_right_side (AND
, andexp
, this,
2040 insn_code
, insn_index
);
2041 right
= insert_right_side (AND
, right
,
2042 evaluate_eq_attr (exp
,
2045 insn_code
, insn_index
),
2046 insn_code
, insn_index
);
2047 orexp
= insert_right_side (IOR
, orexp
, right
,
2048 insn_code
, insn_index
);
2050 /* Add this condition into the AND expression. */
2051 newexp
= attr_rtx (NOT
, this);
2052 andexp
= insert_right_side (AND
, andexp
, newexp
,
2053 insn_code
, insn_index
);
2056 /* Handle the default case. */
2057 right
= insert_right_side (AND
, andexp
,
2058 evaluate_eq_attr (exp
, XEXP (value
, 1),
2059 insn_code
, insn_index
),
2060 insn_code
, insn_index
);
2061 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2068 /* If uses an address, must return original expression. But set the
2069 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2072 walk_attr_value (newexp
);
2076 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2077 return copy_rtx_unchanging (exp
);
2084 /* This routine is called when an AND of a term with a tree of AND's is
2085 encountered. If the term or its complement is present in the tree, it
2086 can be replaced with TRUE or FALSE, respectively.
2088 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2089 be true and hence are complementary.
2091 There is one special case: If we see
2092 (and (not (eq_attr "att" "v1"))
2093 (eq_attr "att" "v2"))
2094 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2095 replace the term, not anything in the AND tree. So we pass a pointer to
2099 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2104 int left_eliminates_term
, right_eliminates_term
;
2106 if (GET_CODE (exp
) == AND
)
2108 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2109 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2110 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2112 newexp
= attr_rtx (AND
, left
, right
);
2114 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2118 else if (GET_CODE (exp
) == IOR
)
2120 /* For the IOR case, we do the same as above, except that we can
2121 only eliminate `term' if both sides of the IOR would do so. */
2123 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2124 left_eliminates_term
= (temp
== true_rtx
);
2127 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2128 right_eliminates_term
= (temp
== true_rtx
);
2130 if (left_eliminates_term
&& right_eliminates_term
)
2133 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2135 newexp
= attr_rtx (IOR
, left
, right
);
2137 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2141 /* Check for simplifications. Do some extra checking here since this
2142 routine is called so many times. */
2147 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2150 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2153 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2155 if (attr_alt_subset_p (*pterm
, exp
))
2158 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2161 if (attr_alt_subset_p (exp
, *pterm
))
2167 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2169 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2172 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2178 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2179 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2181 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2184 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2190 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2191 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2193 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2196 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2202 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2204 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2208 else if (GET_CODE (exp
) == NOT
)
2210 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2214 else if (GET_CODE (*pterm
) == NOT
)
2216 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2220 else if (attr_equal_p (exp
, *pterm
))
2226 /* Similar to `simplify_and_tree', but for IOR trees. */
2229 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2234 int left_eliminates_term
, right_eliminates_term
;
2236 if (GET_CODE (exp
) == IOR
)
2238 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2239 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2240 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2242 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2244 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2248 else if (GET_CODE (exp
) == AND
)
2250 /* For the AND case, we do the same as above, except that we can
2251 only eliminate `term' if both sides of the AND would do so. */
2253 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2254 left_eliminates_term
= (temp
== false_rtx
);
2257 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2258 right_eliminates_term
= (temp
== false_rtx
);
2260 if (left_eliminates_term
&& right_eliminates_term
)
2263 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2265 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2267 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2271 if (attr_equal_p (exp
, *pterm
))
2274 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2277 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2280 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2281 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2282 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2285 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2286 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2287 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2293 /* Compute approximate cost of the expression. Used to decide whether
2294 expression is cheap enough for inline. */
2296 attr_rtx_cost (rtx x
)
2302 code
= GET_CODE (x
);
2315 /* Alternatives don't result into function call. */
2316 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2323 const char *fmt
= GET_RTX_FORMAT (code
);
2324 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2330 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2331 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2334 cost
+= attr_rtx_cost (XEXP (x
, i
));
2344 /* Simplify test expression and use temporary obstack in order to avoid
2345 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2346 and avoid unnecessary copying if possible. */
2349 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2352 struct obstack
*old
;
2353 if (ATTR_IND_SIMPLIFIED_P (exp
))
2356 rtl_obstack
= temp_obstack
;
2357 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2359 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2361 return attr_copy_rtx (x
);
2364 /* Returns true if S1 is a subset of S2. */
2367 attr_alt_subset_p (rtx s1
, rtx s2
)
2369 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2372 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2375 return !(XINT (s1
, 0) & XINT (s2
, 0));
2381 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2388 /* Returns true if S1 is a subset of complement of S2. */
2391 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2393 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2396 return !(XINT (s1
, 0) & XINT (s2
, 0));
2399 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2402 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2412 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2415 attr_alt_intersection (rtx s1
, rtx s2
)
2417 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2419 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2422 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2425 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2428 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2431 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2436 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2441 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2444 attr_alt_union (rtx s1
, rtx s2
)
2446 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2448 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2451 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2454 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2457 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2460 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2466 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2470 /* Return EQ_ATTR_ALT expression representing complement of S. */
2473 attr_alt_complement (rtx s
)
2475 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2477 XINT (result
, 0) = XINT (s
, 0);
2478 XINT (result
, 1) = 1 - XINT (s
, 1);
2483 /* Return EQ_ATTR_ALT expression representing set containing elements set
2489 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2491 XINT (result
, 0) = e
;
2492 XINT (result
, 1) = 0;
2497 /* Given an expression, see if it can be simplified for a particular insn
2498 code based on the values of other attributes being tested. This can
2499 eliminate nested get_attr_... calls.
2501 Note that if an endless recursion is specified in the patterns, the
2502 optimization will loop. However, it will do so in precisely the cases where
2503 an infinite recursion loop could occur during compilation. It's better that
2507 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2510 struct attr_desc
*attr
;
2511 struct attr_value
*av
;
2512 struct insn_ent
*ie
;
2515 bool left_alt
, right_alt
;
2517 /* Don't re-simplify something we already simplified. */
2518 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2521 switch (GET_CODE (exp
))
2524 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2525 if (left
== false_rtx
)
2527 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2528 if (right
== false_rtx
)
2531 if (GET_CODE (left
) == EQ_ATTR_ALT
2532 && GET_CODE (right
) == EQ_ATTR_ALT
)
2534 exp
= attr_alt_intersection (left
, right
);
2535 return simplify_test_exp (exp
, insn_code
, insn_index
);
2538 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2539 present on both sides, apply the distributive law since this will
2540 yield simplifications. */
2541 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2542 && compute_alternative_mask (left
, IOR
)
2543 && compute_alternative_mask (right
, IOR
))
2545 if (GET_CODE (left
) == IOR
)
2552 newexp
= attr_rtx (IOR
,
2553 attr_rtx (AND
, left
, XEXP (right
, 0)),
2554 attr_rtx (AND
, left
, XEXP (right
, 1)));
2556 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2559 /* Try with the term on both sides. */
2560 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2561 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2562 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2564 if (left
== false_rtx
|| right
== false_rtx
)
2566 else if (left
== true_rtx
)
2570 else if (right
== true_rtx
)
2574 /* See if all or all but one of the insn's alternatives are specified
2575 in this tree. Optimize if so. */
2577 if (GET_CODE (left
) == NOT
)
2578 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2579 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2581 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2584 if (GET_CODE (right
) == NOT
)
2585 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2586 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2588 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2589 && XINT (right
, 1));
2592 && (GET_CODE (left
) == AND
2594 || GET_CODE (right
) == AND
2597 i
= compute_alternative_mask (exp
, AND
);
2598 if (i
& ~insn_alternatives
[insn_code
])
2599 fatal ("invalid alternative specified for pattern number %d",
2602 /* If all alternatives are excluded, this is false. */
2603 i
^= insn_alternatives
[insn_code
];
2606 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2608 /* If just one excluded, AND a comparison with that one to the
2609 front of the tree. The others will be eliminated by
2610 optimization. We do not want to do this if the insn has one
2611 alternative and we have tested none of them! */
2612 left
= make_alternative_compare (i
);
2613 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2614 newexp
= attr_rtx (AND
, left
, right
);
2616 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2620 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2622 newexp
= attr_rtx (AND
, left
, right
);
2623 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2628 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2629 if (left
== true_rtx
)
2631 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2632 if (right
== true_rtx
)
2635 if (GET_CODE (left
) == EQ_ATTR_ALT
2636 && GET_CODE (right
) == EQ_ATTR_ALT
)
2638 exp
= attr_alt_union (left
, right
);
2639 return simplify_test_exp (exp
, insn_code
, insn_index
);
2642 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2643 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2644 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2646 if (right
== true_rtx
|| left
== true_rtx
)
2648 else if (left
== false_rtx
)
2652 else if (right
== false_rtx
)
2657 /* Test for simple cases where the distributive law is useful. I.e.,
2658 convert (ior (and (x) (y))
2664 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2665 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2667 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2669 left
= XEXP (left
, 0);
2671 newexp
= attr_rtx (AND
, left
, right
);
2672 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2675 /* See if all or all but one of the insn's alternatives are specified
2676 in this tree. Optimize if so. */
2678 else if (insn_code
>= 0
2679 && (GET_CODE (left
) == IOR
2680 || (GET_CODE (left
) == EQ_ATTR_ALT
2682 || (GET_CODE (left
) == EQ_ATTR
2683 && XSTR (left
, 0) == alternative_name
)
2684 || GET_CODE (right
) == IOR
2685 || (GET_CODE (right
) == EQ_ATTR_ALT
2686 && !XINT (right
, 1))
2687 || (GET_CODE (right
) == EQ_ATTR
2688 && XSTR (right
, 0) == alternative_name
)))
2690 i
= compute_alternative_mask (exp
, IOR
);
2691 if (i
& ~insn_alternatives
[insn_code
])
2692 fatal ("invalid alternative specified for pattern number %d",
2695 /* If all alternatives are included, this is true. */
2696 i
^= insn_alternatives
[insn_code
];
2699 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2701 /* If just one excluded, IOR a comparison with that one to the
2702 front of the tree. The others will be eliminated by
2703 optimization. We do not want to do this if the insn has one
2704 alternative and we have tested none of them! */
2705 left
= make_alternative_compare (i
);
2706 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2707 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2709 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2713 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2715 newexp
= attr_rtx (IOR
, left
, right
);
2716 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2721 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2723 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2724 insn_code
, insn_index
);
2728 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2729 if (GET_CODE (left
) == NOT
)
2730 return XEXP (left
, 0);
2732 if (left
== false_rtx
)
2734 if (left
== true_rtx
)
2737 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2739 exp
= attr_alt_complement (left
);
2740 return simplify_test_exp (exp
, insn_code
, insn_index
);
2743 /* Try to apply De`Morgan's laws. */
2744 if (GET_CODE (left
) == IOR
)
2746 newexp
= attr_rtx (AND
,
2747 attr_rtx (NOT
, XEXP (left
, 0)),
2748 attr_rtx (NOT
, XEXP (left
, 1)));
2750 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2752 else if (GET_CODE (left
) == AND
)
2754 newexp
= attr_rtx (IOR
,
2755 attr_rtx (NOT
, XEXP (left
, 0)),
2756 attr_rtx (NOT
, XEXP (left
, 1)));
2758 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2760 else if (left
!= XEXP (exp
, 0))
2762 newexp
= attr_rtx (NOT
, left
);
2768 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2772 if (XSTR (exp
, 0) == alternative_name
)
2774 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2778 /* Look at the value for this insn code in the specified attribute.
2779 We normally can replace this comparison with the condition that
2780 would give this insn the values being tested for. */
2782 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2783 for (av
= attr
->first_value
; av
; av
= av
->next
)
2784 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2785 if (ie
->def
->insn_code
== insn_code
)
2788 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2789 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2790 if (attr_rtx_cost(x
) < 20)
2799 /* We have already simplified this expression. Simplifying it again
2800 won't buy anything unless we weren't given a valid insn code
2801 to process (i.e., we are canonicalizing something.). */
2803 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2804 return copy_rtx_unchanging (newexp
);
2809 /* Optimize the attribute lists by seeing if we can determine conditional
2810 values from the known values of other attributes. This will save subroutine
2811 calls during the compilation. */
2814 optimize_attrs (void)
2816 struct attr_desc
*attr
;
2817 struct attr_value
*av
;
2818 struct insn_ent
*ie
;
2821 struct attr_value_list
2823 struct attr_value
*av
;
2824 struct insn_ent
*ie
;
2825 struct attr_desc
*attr
;
2826 struct attr_value_list
*next
;
2828 struct attr_value_list
**insn_code_values
;
2829 struct attr_value_list
*ivbuf
;
2830 struct attr_value_list
*iv
;
2832 /* For each insn code, make a list of all the insn_ent's for it,
2833 for all values for all attributes. */
2835 if (num_insn_ents
== 0)
2838 /* Make 2 extra elements, for "code" values -2 and -1. */
2839 insn_code_values
= xcalloc ((insn_code_number
+ 2),
2840 sizeof (struct attr_value_list
*));
2842 /* Offset the table address so we can index by -2 or -1. */
2843 insn_code_values
+= 2;
2845 iv
= ivbuf
= xmalloc (num_insn_ents
* sizeof (struct attr_value_list
));
2847 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2848 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2849 for (av
= attr
->first_value
; av
; av
= av
->next
)
2850 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2855 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2856 insn_code_values
[ie
->def
->insn_code
] = iv
;
2860 /* Sanity check on num_insn_ents. */
2861 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2863 /* Process one insn code at a time. */
2864 for (i
= -2; i
< insn_code_number
; i
++)
2866 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2867 We use it to mean "already simplified for this insn". */
2868 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2869 clear_struct_flag (iv
->av
->value
);
2871 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2873 struct obstack
*old
= rtl_obstack
;
2878 if (GET_CODE (av
->value
) != COND
)
2881 rtl_obstack
= temp_obstack
;
2883 while (GET_CODE (newexp
) == COND
)
2885 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2886 ie
->def
->insn_index
);
2887 if (newexp2
== newexp
)
2893 if (newexp
!= av
->value
)
2895 newexp
= attr_copy_rtx (newexp
);
2896 remove_insn_ent (av
, ie
);
2897 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2899 insert_insn_ent (av
, ie
);
2905 free (insn_code_values
- 2);
2908 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2911 clear_struct_flag (rtx x
)
2918 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2919 if (ATTR_IND_SIMPLIFIED_P (x
))
2922 code
= GET_CODE (x
);
2942 /* Compare the elements. If any pair of corresponding elements
2943 fail to match, return 0 for the whole things. */
2945 fmt
= GET_RTX_FORMAT (code
);
2946 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2952 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2953 clear_struct_flag (XVECEXP (x
, i
, j
));
2957 clear_struct_flag (XEXP (x
, i
));
2963 /* Create table entries for DEFINE_ATTR. */
2966 gen_attr (rtx exp
, int lineno
)
2968 struct attr_desc
*attr
;
2969 struct attr_value
*av
;
2970 const char *name_ptr
;
2973 /* Make a new attribute structure. Check for duplicate by looking at
2974 attr->default_val, since it is initialized by this routine. */
2975 attr
= find_attr (&XSTR (exp
, 0), 1);
2976 if (attr
->default_val
)
2978 message_with_line (lineno
, "duplicate definition for attribute %s",
2980 message_with_line (attr
->lineno
, "previous definition");
2984 attr
->lineno
= lineno
;
2986 if (*XSTR (exp
, 1) == '\0')
2987 attr
->is_numeric
= 1;
2990 name_ptr
= XSTR (exp
, 1);
2991 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
2993 av
= oballoc (sizeof (struct attr_value
));
2994 av
->value
= attr_rtx (CONST_STRING
, p
);
2995 av
->next
= attr
->first_value
;
2996 attr
->first_value
= av
;
2997 av
->first_insn
= NULL
;
2999 av
->has_asm_insn
= 0;
3003 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3006 if (attr
->is_numeric
)
3008 message_with_line (lineno
,
3009 "constant attributes may not take numeric values");
3013 /* Get rid of the CONST node. It is allowed only at top-level. */
3014 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3017 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3019 message_with_line (lineno
,
3020 "`length' attribute must take numeric values");
3024 /* Set up the default value. */
3025 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3026 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3029 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3030 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3031 number of alternatives as this should be checked elsewhere. */
3034 count_alternatives (rtx exp
)
3039 if (GET_CODE (exp
) == MATCH_OPERAND
)
3040 return n_comma_elts (XSTR (exp
, 2));
3042 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3043 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3048 n
= count_alternatives (XEXP (exp
, i
));
3055 if (XVEC (exp
, i
) != NULL
)
3056 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3058 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3067 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3068 `alternative' attribute. */
3071 compares_alternatives_p (rtx exp
)
3076 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3079 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3080 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3085 if (compares_alternatives_p (XEXP (exp
, i
)))
3090 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3091 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3099 /* Returns nonzero is INNER is contained in EXP. */
3102 contained_in_p (rtx inner
, rtx exp
)
3107 if (rtx_equal_p (inner
, exp
))
3110 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3111 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3116 if (contained_in_p (inner
, XEXP (exp
, i
)))
3121 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3122 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
3130 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3133 gen_insn (rtx exp
, int lineno
)
3135 struct insn_def
*id
;
3137 id
= oballoc (sizeof (struct insn_def
));
3141 id
->lineno
= lineno
;
3143 switch (GET_CODE (exp
))
3146 id
->insn_code
= insn_code_number
;
3147 id
->insn_index
= insn_index_number
;
3148 id
->num_alternatives
= count_alternatives (exp
);
3149 if (id
->num_alternatives
== 0)
3150 id
->num_alternatives
= 1;
3154 case DEFINE_PEEPHOLE
:
3155 id
->insn_code
= insn_code_number
;
3156 id
->insn_index
= insn_index_number
;
3157 id
->num_alternatives
= count_alternatives (exp
);
3158 if (id
->num_alternatives
== 0)
3159 id
->num_alternatives
= 1;
3163 case DEFINE_ASM_ATTRIBUTES
:
3165 id
->insn_index
= -1;
3166 id
->num_alternatives
= 1;
3168 got_define_asm_attributes
= 1;
3176 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3177 true or annul false is specified, and make a `struct delay_desc'. */
3180 gen_delay (rtx def
, int lineno
)
3182 struct delay_desc
*delay
;
3185 if (XVECLEN (def
, 1) % 3 != 0)
3187 message_with_line (lineno
,
3188 "number of elements in DEFINE_DELAY must be multiple of three");
3193 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3195 if (XVECEXP (def
, 1, i
+ 1))
3196 have_annul_true
= 1;
3197 if (XVECEXP (def
, 1, i
+ 2))
3198 have_annul_false
= 1;
3201 delay
= oballoc (sizeof (struct delay_desc
));
3203 delay
->num
= ++num_delays
;
3204 delay
->next
= delays
;
3205 delay
->lineno
= lineno
;
3209 /* Given a piece of RTX, print a C expression to test its truth value.
3210 We use AND and IOR both for logical and bit-wise operations, so
3211 interpret them as logical unless they are inside a comparison expression.
3212 The first bit of FLAGS will be nonzero in that case.
3214 Set the second bit of FLAGS to make references to attribute values use
3215 a cached local variable instead of calling a function. */
3218 write_test_expr (rtx exp
, int flags
)
3220 int comparison_operator
= 0;
3222 struct attr_desc
*attr
;
3224 /* In order not to worry about operator precedence, surround our part of
3225 the expression with parentheses. */
3228 code
= GET_CODE (exp
);
3231 /* Binary operators. */
3234 printf ("(unsigned) ");
3240 comparison_operator
= 1;
3242 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3243 case AND
: case IOR
: case XOR
:
3244 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3245 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3261 printf (" >= (unsigned) ");
3264 printf (" > (unsigned) ");
3273 printf (" <= (unsigned) ");
3276 printf (" < (unsigned) ");
3319 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3323 /* Special-case (not (eq_attrq "alternative" "x")) */
3324 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3325 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3327 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3331 /* Otherwise, fall through to normal unary operator. */
3333 /* Unary operators. */
3353 write_test_expr (XEXP (exp
, 0), flags
);
3358 int set
= XINT (exp
, 0), bit
= 0;
3361 fatal ("EQ_ATTR_ALT not valid inside comparison");
3364 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3366 if (!(set
& (set
- 1)))
3368 if (!(set
& 0xffff))
3391 printf ("which_alternative %s= %d",
3392 XINT (exp
, 1) ? "!" : "=", bit
);
3396 printf ("%s((1 << which_alternative) & 0x%x)",
3397 XINT (exp
, 1) ? "!" : "", set
);
3402 /* Comparison test of an attribute with a value. Most of these will
3403 have been removed by optimization. Handle "alternative"
3404 specially and give error if EQ_ATTR present inside a comparison. */
3407 fatal ("EQ_ATTR not valid inside comparison");
3409 if (XSTR (exp
, 0) == alternative_name
)
3411 printf ("which_alternative == %s", XSTR (exp
, 1));
3415 attr
= find_attr (&XSTR (exp
, 0), 0);
3418 /* Now is the time to expand the value of a constant attribute. */
3421 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3428 printf ("attr_%s", attr
->name
);
3430 printf ("get_attr_%s (insn)", attr
->name
);
3432 write_attr_valueq (attr
, XSTR (exp
, 1));
3436 /* Comparison test of flags for define_delays. */
3439 fatal ("ATTR_FLAG not valid inside comparison");
3440 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3443 /* See if an operand matches a predicate. */
3445 /* If only a mode is given, just ensure the mode matches the operand.
3446 If neither a mode nor predicate is given, error. */
3447 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3449 if (GET_MODE (exp
) == VOIDmode
)
3450 fatal ("null MATCH_OPERAND specified as test");
3452 printf ("GET_MODE (operands[%d]) == %smode",
3453 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3456 printf ("%s (operands[%d], %smode)",
3457 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3460 /* Constant integer. */
3462 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3465 /* A random C expression. */
3467 print_c_condition (XSTR (exp
, 0));
3470 /* The address of the branch target. */
3472 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3473 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3477 /* The address of the current insn. We implement this actually as the
3478 address of the current insn for backward branches, but the last
3479 address of the next insn for forward branches, and both with
3480 adjustments that account for the worst-case possible stretching of
3481 intervening alignments between this insn and its destination. */
3482 printf ("insn_current_reference_address (insn)");
3486 printf ("%s", XSTR (exp
, 0));
3490 write_test_expr (XEXP (exp
, 0), flags
& 2);
3492 write_test_expr (XEXP (exp
, 1), flags
| 1);
3494 write_test_expr (XEXP (exp
, 2), flags
| 1);
3498 fatal ("bad RTX code `%s' in attribute calculation\n",
3499 GET_RTX_NAME (code
));
3505 /* Given an attribute value, return the maximum CONST_STRING argument
3506 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3509 max_attr_value (rtx exp
, int *unknownp
)
3514 switch (GET_CODE (exp
))
3517 current_max
= atoi (XSTR (exp
, 0));
3521 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3522 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3524 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3525 if (n
> current_max
)
3531 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3532 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3533 if (n
> current_max
)
3539 current_max
= INT_MAX
;
3546 /* Given an attribute value, return the minimum CONST_STRING argument
3547 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3550 min_attr_value (rtx exp
, int *unknownp
)
3555 switch (GET_CODE (exp
))
3558 current_min
= atoi (XSTR (exp
, 0));
3562 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3563 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3565 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3566 if (n
< current_min
)
3572 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3573 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3574 if (n
< current_min
)
3580 current_min
= INT_MAX
;
3587 /* Given an attribute value, return the result of ORing together all
3588 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3589 if the numeric value is not known. */
3592 or_attr_value (rtx exp
, int *unknownp
)
3597 switch (GET_CODE (exp
))
3600 current_or
= atoi (XSTR (exp
, 0));
3604 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3605 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3606 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3610 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3611 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3623 /* Scan an attribute value, possibly a conditional, and record what actions
3624 will be required to do any conditional tests in it.
3627 `must_extract' if we need to extract the insn operands
3628 `must_constrain' if we must compute `which_alternative'
3629 `address_used' if an address expression was used
3630 `length_used' if an (eq_attr "length" ...) was used
3634 walk_attr_value (rtx exp
)
3643 code
= GET_CODE (exp
);
3647 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3648 /* Since this is an arbitrary expression, it can look at anything.
3649 However, constant expressions do not depend on any particular
3651 must_extract
= must_constrain
= 1;
3659 must_extract
= must_constrain
= 1;
3663 if (XSTR (exp
, 0) == alternative_name
)
3664 must_extract
= must_constrain
= 1;
3665 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3685 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3690 walk_attr_value (XEXP (exp
, i
));
3694 if (XVEC (exp
, i
) != NULL
)
3695 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3696 walk_attr_value (XVECEXP (exp
, i
, j
));
3701 /* Write out a function to obtain the attribute for a given INSN. */
3704 write_attr_get (struct attr_desc
*attr
)
3706 struct attr_value
*av
, *common_av
;
3708 /* Find the most used attribute value. Handle that as the `default' of the
3709 switch we will generate. */
3710 common_av
= find_most_used (attr
);
3712 /* Write out start of function, then all values with explicit `case' lines,
3713 then a `default', then the value with the most uses. */
3716 if (!attr
->is_numeric
)
3717 printf ("enum attr_%s\n", attr
->name
);
3721 /* If the attribute name starts with a star, the remainder is the name of
3722 the subroutine to use, instead of `get_attr_...'. */
3723 if (attr
->name
[0] == '*')
3724 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3725 else if (attr
->is_const
== 0)
3726 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3729 printf ("get_attr_%s (void)\n", attr
->name
);
3732 for (av
= attr
->first_value
; av
; av
= av
->next
)
3733 if (av
->num_insns
== 1)
3734 write_attr_set (attr
, 2, av
->value
, "return", ";",
3735 true_rtx
, av
->first_insn
->def
->insn_code
,
3736 av
->first_insn
->def
->insn_index
);
3737 else if (av
->num_insns
!= 0)
3738 write_attr_set (attr
, 2, av
->value
, "return", ";",
3746 printf (" switch (recog_memoized (insn))\n");
3749 for (av
= attr
->first_value
; av
; av
= av
->next
)
3750 if (av
!= common_av
)
3751 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3753 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3754 printf (" }\n}\n\n");
3757 /* Given an AND tree of known true terms (because we are inside an `if' with
3758 that as the condition or are in an `else' clause) and an expression,
3759 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3760 the bulk of the work. */
3763 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3767 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3769 if (GET_CODE (known_true
) == AND
)
3771 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3772 insn_code
, insn_index
);
3773 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3774 insn_code
, insn_index
);
3779 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3785 /* Write out a series of tests and assignment statements to perform tests and
3786 sets of an attribute value. We are passed an indentation amount and prefix
3787 and suffix strings to write around each attribute value (e.g., "return"
3791 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3792 const char *prefix
, const char *suffix
, rtx known_true
,
3793 int insn_code
, int insn_index
)
3795 if (GET_CODE (value
) == COND
)
3797 /* Assume the default value will be the default of the COND unless we
3798 find an always true expression. */
3799 rtx default_val
= XEXP (value
, 1);
3800 rtx our_known_true
= known_true
;
3805 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3810 testexp
= eliminate_known_true (our_known_true
,
3811 XVECEXP (value
, 0, i
),
3812 insn_code
, insn_index
);
3813 newexp
= attr_rtx (NOT
, testexp
);
3814 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3815 insn_code
, insn_index
);
3817 /* If the test expression is always true or if the next `known_true'
3818 expression is always false, this is the last case, so break
3819 out and let this value be the `else' case. */
3820 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3822 default_val
= XVECEXP (value
, 0, i
+ 1);
3826 /* Compute the expression to pass to our recursive call as being
3828 inner_true
= insert_right_side (AND
, our_known_true
,
3829 testexp
, insn_code
, insn_index
);
3831 /* If this is always false, skip it. */
3832 if (inner_true
== false_rtx
)
3835 write_indent (indent
);
3836 printf ("%sif ", first_if
? "" : "else ");
3838 write_test_expr (testexp
, 0);
3840 write_indent (indent
+ 2);
3843 write_attr_set (attr
, indent
+ 4,
3844 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3845 inner_true
, insn_code
, insn_index
);
3846 write_indent (indent
+ 2);
3848 our_known_true
= newexp
;
3853 write_indent (indent
);
3855 write_indent (indent
+ 2);
3859 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
3860 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
3864 write_indent (indent
+ 2);
3870 write_indent (indent
);
3871 printf ("%s ", prefix
);
3872 write_attr_value (attr
, value
);
3873 printf ("%s\n", suffix
);
3877 /* Write a series of case statements for every instruction in list IE.
3878 INDENT is the amount of indentation to write before each case. */
3881 write_insn_cases (struct insn_ent
*ie
, int indent
)
3883 for (; ie
!= 0; ie
= ie
->next
)
3884 if (ie
->def
->insn_code
!= -1)
3886 write_indent (indent
);
3887 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
3888 printf ("case %d: /* define_peephole, line %d */\n",
3889 ie
->def
->insn_code
, ie
->def
->lineno
);
3891 printf ("case %d: /* %s */\n",
3892 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
3896 /* Write out the computation for one attribute value. */
3899 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
3900 int write_case_lines
, const char *prefix
, const char *suffix
,
3901 int indent
, rtx known_true
)
3903 if (av
->num_insns
== 0)
3906 if (av
->has_asm_insn
)
3908 write_indent (indent
);
3909 printf ("case -1:\n");
3910 write_indent (indent
+ 2);
3911 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3912 write_indent (indent
+ 2);
3913 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3914 write_indent (indent
+ 2);
3915 printf (" fatal_insn_not_found (insn);\n");
3918 if (write_case_lines
)
3919 write_insn_cases (av
->first_insn
, indent
);
3922 write_indent (indent
);
3923 printf ("default:\n");
3926 /* See what we have to do to output this value. */
3927 must_extract
= must_constrain
= address_used
= 0;
3928 walk_attr_value (av
->value
);
3932 write_indent (indent
+ 2);
3933 printf ("extract_constrain_insn_cached (insn);\n");
3935 else if (must_extract
)
3937 write_indent (indent
+ 2);
3938 printf ("extract_insn_cached (insn);\n");
3941 if (av
->num_insns
== 1)
3942 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3943 known_true
, av
->first_insn
->def
->insn_code
,
3944 av
->first_insn
->def
->insn_index
);
3946 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3949 if (strncmp (prefix
, "return", 6))
3951 write_indent (indent
+ 2);
3952 printf ("break;\n");
3957 /* Search for uses of non-const attributes and write code to cache them. */
3960 write_expr_attr_cache (rtx p
, struct attr_desc
*attr
)
3965 if (GET_CODE (p
) == EQ_ATTR
)
3967 if (XSTR (p
, 0) != attr
->name
)
3970 if (!attr
->is_numeric
)
3971 printf (" enum attr_%s ", attr
->name
);
3975 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
3979 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
3980 ie
= GET_RTX_LENGTH (GET_CODE (p
));
3981 for (i
= 0; i
< ie
; i
++)
3986 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
3991 je
= XVECLEN (p
, i
);
3992 for (j
= 0; j
< je
; ++j
)
3993 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
4002 /* Utilities to write in various forms. */
4005 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
4007 if (attr
->is_numeric
)
4013 if (num
> 9 || num
< 0)
4014 printf (" /* 0x%x */", num
);
4018 write_upcase (attr
->name
);
4025 write_attr_value (struct attr_desc
*attr
, rtx value
)
4029 switch (GET_CODE (value
))
4032 write_attr_valueq (attr
, XSTR (value
, 0));
4036 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4040 print_c_condition (XSTR (value
, 0));
4045 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4046 printf ("get_attr_%s (%s)", attr2
->name
,
4047 (attr2
->is_const
? "" : "insn"));
4068 write_attr_value (attr
, XEXP (value
, 0));
4072 write_attr_value (attr
, XEXP (value
, 1));
4081 write_upcase (const char *str
)
4085 /* The argument of TOUPPER should not have side effects. */
4086 putchar (TOUPPER(*str
));
4092 write_indent (int indent
)
4094 for (; indent
> 8; indent
-= 8)
4097 for (; indent
; indent
--)
4101 /* Write a subroutine that is given an insn that requires a delay slot, a
4102 delay slot ordinal, and a candidate insn. It returns nonzero if the
4103 candidate can be placed in the specified delay slot of the insn.
4105 We can write as many as three subroutines. `eligible_for_delay'
4106 handles normal delay slots, `eligible_for_annul_true' indicates that
4107 the specified insn can be annulled if the branch is true, and likewise
4108 for `eligible_for_annul_false'.
4110 KIND is a string distinguishing these three cases ("delay", "annul_true",
4111 or "annul_false"). */
4114 write_eligible_delay (const char *kind
)
4116 struct delay_desc
*delay
;
4120 struct attr_desc
*attr
;
4121 struct attr_value
*av
, *common_av
;
4124 /* Compute the maximum number of delay slots required. We use the delay
4125 ordinal times this number plus one, plus the slot number as an index into
4126 the appropriate predicate to test. */
4128 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4129 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4130 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4132 /* Write function prelude. */
4135 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4138 printf (" rtx insn;\n");
4140 printf (" gcc_assert (slot < %d);\n", max_slots
);
4142 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4143 converts a compound instruction into a loop. */
4144 printf (" if (!INSN_P (candidate_insn))\n");
4145 printf (" return 0;\n");
4148 /* If more than one delay type, find out which type the delay insn is. */
4152 attr
= find_attr (&delay_type_str
, 0);
4154 common_av
= find_most_used (attr
);
4156 printf (" insn = delay_insn;\n");
4157 printf (" switch (recog_memoized (insn))\n");
4160 sprintf (str
, " * %d;\n break;", max_slots
);
4161 for (av
= attr
->first_value
; av
; av
= av
->next
)
4162 if (av
!= common_av
)
4163 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4165 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4168 /* Ensure matched. Otherwise, shouldn't have been called. */
4169 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4172 /* If just one type of delay slot, write simple switch. */
4173 if (num_delays
== 1 && max_slots
== 1)
4175 printf (" insn = candidate_insn;\n");
4176 printf (" switch (recog_memoized (insn))\n");
4179 attr
= find_attr (&delay_1_0_str
, 0);
4181 common_av
= find_most_used (attr
);
4183 for (av
= attr
->first_value
; av
; av
= av
->next
)
4184 if (av
!= common_av
)
4185 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4187 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4193 /* Write a nested CASE. The first indicates which condition we need to
4194 test, and the inner CASE tests the condition. */
4195 printf (" insn = candidate_insn;\n");
4196 printf (" switch (slot)\n");
4199 for (delay
= delays
; delay
; delay
= delay
->next
)
4200 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4202 printf (" case %d:\n",
4203 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4204 printf (" switch (recog_memoized (insn))\n");
4207 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4209 attr
= find_attr (&pstr
, 0);
4211 common_av
= find_most_used (attr
);
4213 for (av
= attr
->first_value
; av
; av
= av
->next
)
4214 if (av
!= common_av
)
4215 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4217 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4221 printf (" default:\n");
4222 printf (" gcc_unreachable ();\n");
4229 /* This page contains miscellaneous utility routines. */
4231 /* Given a pointer to a (char *), return a malloc'ed string containing the
4232 next comma-separated element. Advance the pointer to after the string
4233 scanned, or the end-of-string. Return NULL if at end of string. */
4236 next_comma_elt (const char **pstr
)
4240 start
= scan_comma_elt (pstr
);
4245 return attr_string (start
, *pstr
- start
);
4248 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4249 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4250 replaced by a pointer to a canonical copy of the string. */
4252 static struct attr_desc
*
4253 find_attr (const char **name_p
, int create
)
4255 struct attr_desc
*attr
;
4257 const char *name
= *name_p
;
4259 /* Before we resort to using `strcmp', see if the string address matches
4260 anywhere. In most cases, it should have been canonicalized to do so. */
4261 if (name
== alternative_name
)
4264 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4265 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4266 if (name
== attr
->name
)
4269 /* Otherwise, do it the slow way. */
4270 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4271 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4273 *name_p
= attr
->name
;
4280 attr
= oballoc (sizeof (struct attr_desc
));
4281 attr
->name
= DEF_ATTR_STRING (name
);
4282 attr
->first_value
= attr
->default_val
= NULL
;
4283 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4285 attr
->next
= attrs
[index
];
4286 attrs
[index
] = attr
;
4288 *name_p
= attr
->name
;
4293 /* Create internal attribute with the given default value. */
4296 make_internal_attr (const char *name
, rtx value
, int special
)
4298 struct attr_desc
*attr
;
4300 attr
= find_attr (&name
, 1);
4301 gcc_assert (!attr
->default_val
);
4303 attr
->is_numeric
= 1;
4305 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4306 attr
->static_p
= (special
& ATTR_STATIC
) != 0;
4307 attr
->default_val
= get_attr_value (value
, attr
, -2);
4310 /* Find the most used value of an attribute. */
4312 static struct attr_value
*
4313 find_most_used (struct attr_desc
*attr
)
4315 struct attr_value
*av
;
4316 struct attr_value
*most_used
;
4322 for (av
= attr
->first_value
; av
; av
= av
->next
)
4323 if (av
->num_insns
> nuses
)
4324 nuses
= av
->num_insns
, most_used
= av
;
4329 /* Return (attr_value "n") */
4332 make_numeric_value (int n
)
4334 static rtx int_values
[20];
4338 gcc_assert (n
>= 0);
4340 if (n
< 20 && int_values
[n
])
4341 return int_values
[n
];
4343 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4344 exp
= attr_rtx (CONST_STRING
, p
);
4347 int_values
[n
] = exp
;
4353 copy_rtx_unchanging (rtx orig
)
4355 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4358 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4362 /* Determine if an insn has a constant number of delay slots, i.e., the
4363 number of delay slots is not a function of the length of the insn. */
4366 write_const_num_delay_slots (void)
4368 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4369 struct attr_value
*av
;
4373 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4375 printf (" switch (recog_memoized (insn))\n");
4378 for (av
= attr
->first_value
; av
; av
= av
->next
)
4381 walk_attr_value (av
->value
);
4383 write_insn_cases (av
->first_insn
, 4);
4386 printf (" default:\n");
4387 printf (" return 1;\n");
4388 printf (" }\n}\n\n");
4393 main (int argc
, char **argv
)
4396 struct attr_desc
*attr
;
4397 struct insn_def
*id
;
4401 progname
= "genattrtab";
4403 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
4404 return (FATAL_EXIT_CODE
);
4406 obstack_init (hash_obstack
);
4407 obstack_init (temp_obstack
);
4409 /* Set up true and false rtx's */
4410 true_rtx
= rtx_alloc (CONST_INT
);
4411 XWINT (true_rtx
, 0) = 1;
4412 false_rtx
= rtx_alloc (CONST_INT
);
4413 XWINT (false_rtx
, 0) = 0;
4414 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4415 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4417 alternative_name
= DEF_ATTR_STRING ("alternative");
4418 length_str
= DEF_ATTR_STRING ("length");
4419 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4420 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4421 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4423 printf ("/* Generated automatically by the program `genattrtab'\n\
4424 from the machine description file `md'. */\n\n");
4426 /* Read the machine description. */
4428 initiate_automaton_gen (argc
, argv
);
4433 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4437 switch (GET_CODE (desc
))
4440 case DEFINE_PEEPHOLE
:
4441 case DEFINE_ASM_ATTRIBUTES
:
4442 gen_insn (desc
, lineno
);
4446 gen_attr (desc
, lineno
);
4450 gen_delay (desc
, lineno
);
4453 case DEFINE_CPU_UNIT
:
4454 gen_cpu_unit (desc
);
4457 case DEFINE_QUERY_CPU_UNIT
:
4458 gen_query_cpu_unit (desc
);
4466 gen_excl_set (desc
);
4470 gen_presence_set (desc
);
4473 case FINAL_PRESENCE_SET
:
4474 gen_final_presence_set (desc
);
4478 gen_absence_set (desc
);
4481 case FINAL_ABSENCE_SET
:
4482 gen_final_absence_set (desc
);
4485 case DEFINE_AUTOMATON
:
4486 gen_automaton (desc
);
4489 case AUTOMATA_OPTION
:
4490 gen_automata_option (desc
);
4493 case DEFINE_RESERVATION
:
4497 case DEFINE_INSN_RESERVATION
:
4498 gen_insn_reserv (desc
);
4504 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4505 insn_index_number
++;
4509 return FATAL_EXIT_CODE
;
4513 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4514 if (! got_define_asm_attributes
)
4516 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4517 XVEC (tem
, 0) = rtvec_alloc (0);
4521 /* Expand DEFINE_DELAY information into new attribute. */
4525 /* Build DFA, output some functions and expand DFA information
4526 to new attributes. */
4530 printf ("#include \"config.h\"\n");
4531 printf ("#include \"system.h\"\n");
4532 printf ("#include \"coretypes.h\"\n");
4533 printf ("#include \"tm.h\"\n");
4534 printf ("#include \"rtl.h\"\n");
4535 printf ("#include \"tm_p.h\"\n");
4536 printf ("#include \"insn-config.h\"\n");
4537 printf ("#include \"recog.h\"\n");
4538 printf ("#include \"regs.h\"\n");
4539 printf ("#include \"real.h\"\n");
4540 printf ("#include \"output.h\"\n");
4541 printf ("#include \"insn-attr.h\"\n");
4542 printf ("#include \"toplev.h\"\n");
4543 printf ("#include \"flags.h\"\n");
4544 printf ("#include \"function.h\"\n");
4546 printf ("#define operands recog_data.operand\n\n");
4548 /* Make `insn_alternatives'. */
4549 insn_alternatives
= oballoc (insn_code_number
* sizeof (int));
4550 for (id
= defs
; id
; id
= id
->next
)
4551 if (id
->insn_code
>= 0)
4552 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4554 /* Make `insn_n_alternatives'. */
4555 insn_n_alternatives
= oballoc (insn_code_number
* sizeof (int));
4556 for (id
= defs
; id
; id
= id
->next
)
4557 if (id
->insn_code
>= 0)
4558 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4560 /* Prepare to write out attribute subroutines by checking everything stored
4561 away and building the attribute cases. */
4565 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4566 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4567 attr
->default_val
->value
4568 = check_attr_value (attr
->default_val
->value
, attr
);
4571 return FATAL_EXIT_CODE
;
4573 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4574 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4577 /* Construct extra attributes for `length'. */
4578 make_length_attrs ();
4580 /* Perform any possible optimizations to speed up compilation. */
4583 /* Now write out all the `gen_attr_...' routines. Do these before the
4584 special routines so that they get defined before they are used. */
4586 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4587 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4589 if (! attr
->is_special
&& ! attr
->is_const
)
4594 = (attr
->name
[0] == '*'
4595 && strcmp (&attr
->name
[1], INSN_ALTS_FUNC_NAME
) == 0);
4597 printf ("\n#if AUTOMATON_ALTS\n");
4598 write_attr_get (attr
);
4600 printf ("#endif\n\n");
4604 /* Write out delay eligibility information, if DEFINE_DELAY present.
4605 (The function to compute the number of delay slots will be written
4609 write_eligible_delay ("delay");
4610 if (have_annul_true
)
4611 write_eligible_delay ("annul_true");
4612 if (have_annul_false
)
4613 write_eligible_delay ("annul_false");
4616 /* Output code for pipeline hazards recognition based on DFA
4617 (deterministic finite-state automata). */
4621 /* Write out constant delay slot info. */
4622 write_const_num_delay_slots ();
4624 write_length_unit_log ();
4627 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);
4630 /* Define this so we can link with print-rtl.o to get debug_rtx function. */
4632 get_insn_name (int code ATTRIBUTE_UNUSED
)