1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998,
3 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
94 `volatil' (ATTR_EQ_ATTR_P): During simplify_by_exploding the value of an
95 EQ_ATTR rtx is true if !volatil and false if volatil. */
97 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
98 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
99 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
100 #define ATTR_EQ_ATTR_P(RTX) (RTX_FLAG((RTX), volatil))
103 #define strcmp_check(S1, S2) ((S1) == (S2) \
105 : (gcc_assert (strcmp ((S1), (S2))), 1))
107 #define strcmp_check(S1, S2) ((S1) != (S2))
112 #include "coretypes.h"
116 #include "gensupport.h"
118 #ifdef HAVE_SYS_RESOURCE_H
119 # include <sys/resource.h>
122 /* We must include obstack.h after <sys/time.h>, to avoid lossage with
123 /usr/include/sys/stdtypes.h on Sun OS 4.x. */
127 #include "genattrtab.h"
129 static struct obstack obstack1
, obstack2
;
130 struct obstack
*hash_obstack
= &obstack1
;
131 struct obstack
*temp_obstack
= &obstack2
;
133 /* enough space to reserve for printing out ints */
134 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
136 /* Define structures used to record attributes and values. */
138 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
139 encountered, we store all the relevant information into a
140 `struct insn_def'. This is done to allow attribute definitions to occur
141 anywhere in the file. */
145 struct insn_def
*next
; /* Next insn in chain. */
146 rtx def
; /* The DEFINE_... */
147 int insn_code
; /* Instruction number. */
148 int insn_index
; /* Expression numer in file, for errors. */
149 int lineno
; /* Line number. */
150 int num_alternatives
; /* Number of alternatives. */
151 int vec_idx
; /* Index of attribute vector in `def'. */
154 /* Once everything has been read in, we store in each attribute value a list
155 of insn codes that have that value. Here is the structure used for the
160 struct insn_ent
*next
; /* Next in chain. */
161 struct insn_def
*def
; /* Instruction definition. */
164 /* Each value of an attribute (either constant or computed) is assigned a
165 structure which is used as the listhead of the insns that have that
170 rtx value
; /* Value of attribute. */
171 struct attr_value
*next
; /* Next attribute value in chain. */
172 struct insn_ent
*first_insn
; /* First insn with this value. */
173 int num_insns
; /* Number of insns with this value. */
174 int has_asm_insn
; /* True if this value used for `asm' insns */
177 /* Structure for each attribute. */
181 char *name
; /* Name of attribute. */
182 struct attr_desc
*next
; /* Next attribute. */
183 struct attr_value
*first_value
; /* First value of this attribute. */
184 struct attr_value
*default_val
; /* Default value for this attribute. */
185 int lineno
: 24; /* Line number. */
186 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
187 unsigned negative_ok
: 1; /* Allow negative numeric values. */
188 unsigned unsigned_p
: 1; /* Make the output function unsigned int. */
189 unsigned is_const
: 1; /* Attribute value constant for each run. */
190 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
191 unsigned static_p
: 1; /* Make the output function static. */
194 #define NULL_ATTR (struct attr_desc *) NULL
196 /* Structure for each DEFINE_DELAY. */
200 rtx def
; /* DEFINE_DELAY expression. */
201 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
202 int num
; /* Number of DEFINE_DELAY, starting at 1. */
203 int lineno
; /* Line number. */
206 /* Listheads of above structures. */
208 /* This one is indexed by the first character of the attribute name. */
209 #define MAX_ATTRS_INDEX 256
210 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
211 static struct insn_def
*defs
;
212 static struct delay_desc
*delays
;
214 /* Other variables. */
216 static int insn_code_number
;
217 static int insn_index_number
;
218 static int got_define_asm_attributes
;
219 static int must_extract
;
220 static int must_constrain
;
221 static int address_used
;
222 static int length_used
;
223 static int num_delays
;
224 static int have_annul_true
, have_annul_false
;
225 static int num_insn_ents
;
229 /* Stores, for each insn code, the number of constraint alternatives. */
231 static int *insn_n_alternatives
;
233 /* Stores, for each insn code, a bitmap that has bits on for each possible
236 static int *insn_alternatives
;
238 /* If nonzero, assume that the `alternative' attr has this value.
239 This is the hashed, unique string for the numeral
240 whose value is chosen alternative. */
242 static const char *current_alternative_string
;
244 /* Used to simplify expressions. */
246 static rtx true_rtx
, false_rtx
;
248 /* Used to reduce calls to `strcmp' */
250 static char *alternative_name
;
251 static const char *length_str
;
252 static const char *delay_type_str
;
253 static const char *delay_1_0_str
;
254 static const char *num_delay_slots_str
;
256 /* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever
259 int reload_completed
= 0;
261 /* Some machines test `optimize' in macros called from rtlanal.c, so we need
262 to define it here. */
266 /* Simplify an expression. Only call the routine if there is something to
268 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
269 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
270 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
272 /* Simplify (eq_attr ("alternative") ...)
273 when we are working with a particular alternative. */
274 #define SIMPLIFY_ALTERNATIVE(EXP) \
275 if (current_alternative_string \
276 && GET_CODE ((EXP)) == EQ_ATTR \
277 && XSTR ((EXP), 0) == alternative_name) \
278 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \
279 ? true_rtx : false_rtx);
281 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
283 /* These are referenced by rtlanal.c and hence need to be defined somewhere.
284 They won't actually be used. */
286 rtx global_rtl
[GR_MAX
];
287 rtx pic_offset_table_rtx
;
289 static void attr_hash_add_rtx (int, rtx
);
290 static void attr_hash_add_string (int, char *);
291 static rtx
attr_rtx (enum rtx_code
, ...);
292 static rtx
attr_rtx_1 (enum rtx_code
, va_list);
293 static char *attr_string (const char *, int);
294 static rtx
check_attr_value (rtx
, struct attr_desc
*);
295 static rtx
convert_set_attr_alternative (rtx
, struct insn_def
*);
296 static rtx
convert_set_attr (rtx
, struct insn_def
*);
297 static void check_defs (void);
298 static rtx
make_canonical (struct attr_desc
*, rtx
);
299 static struct attr_value
*get_attr_value (rtx
, struct attr_desc
*, int);
300 static rtx
copy_rtx_unchanging (rtx
);
301 static rtx
copy_boolean (rtx
);
302 static void expand_delays (void);
303 static void fill_attr (struct attr_desc
*);
304 static rtx
substitute_address (rtx
, rtx (*) (rtx
), rtx (*) (rtx
));
305 static void make_length_attrs (void);
306 static rtx
identity_fn (rtx
);
307 static rtx
zero_fn (rtx
);
308 static rtx
one_fn (rtx
);
309 static rtx
max_fn (rtx
);
310 static void write_length_unit_log (void);
311 static rtx
simplify_cond (rtx
, int, int);
312 static void clear_struct_flag (rtx
);
313 static void remove_insn_ent (struct attr_value
*, struct insn_ent
*);
314 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
315 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
316 static rtx
make_alternative_compare (int);
317 static int compute_alternative_mask (rtx
, enum rtx_code
);
318 static rtx
evaluate_eq_attr (rtx
, rtx
, int, int);
319 static rtx
simplify_and_tree (rtx
, rtx
*, int, int);
320 static rtx
simplify_or_tree (rtx
, rtx
*, int, int);
321 static rtx
simplify_test_exp (rtx
, int, int);
322 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
323 static void optimize_attrs (void);
324 static void gen_attr (rtx
, int);
325 static int count_alternatives (rtx
);
326 static int compares_alternatives_p (rtx
);
327 static int contained_in_p (rtx
, rtx
);
328 static void gen_insn (rtx
, int);
329 static void gen_delay (rtx
, int);
330 static void write_test_expr (rtx
, int);
331 static int max_attr_value (rtx
, int*);
332 static int or_attr_value (rtx
, int*);
333 static void walk_attr_value (rtx
);
334 static void write_attr_get (struct attr_desc
*);
335 static rtx
eliminate_known_true (rtx
, rtx
, int, int);
336 static void write_attr_set (struct attr_desc
*, int, rtx
,
337 const char *, const char *, rtx
,
339 static void write_insn_cases (struct insn_ent
*, int);
340 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
341 int, const char *, const char *, int, rtx
);
342 static void write_attr_valueq (struct attr_desc
*, const char *);
343 static void write_attr_value (struct attr_desc
*, rtx
);
344 static void write_upcase (const char *);
345 static void write_indent (int);
346 static void write_eligible_delay (const char *);
347 static int write_expr_attr_cache (rtx
, struct attr_desc
*);
348 static void write_const_num_delay_slots (void);
349 static char *next_comma_elt (const char **);
350 static struct attr_desc
*find_attr (const char **, int);
351 static struct attr_value
*find_most_used (struct attr_desc
*);
352 static rtx
attr_eq (const char *, const char *);
353 static const char *attr_numeral (int);
354 static int attr_equal_p (rtx
, rtx
);
355 static rtx
attr_copy_rtx (rtx
);
356 static int attr_rtx_cost (rtx
);
357 static bool attr_alt_subset_p (rtx
, rtx
);
358 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
359 static rtx
attr_alt_intersection (rtx
, rtx
);
360 static rtx
attr_alt_union (rtx
, rtx
);
361 static rtx
attr_alt_complement (rtx
);
362 static bool attr_alt_bit_p (rtx
, int);
363 static rtx
mk_attr_alt (int);
365 #define oballoc(size) obstack_alloc (hash_obstack, size)
367 /* Hash table for sharing RTL and strings. */
369 /* Each hash table slot is a bucket containing a chain of these structures.
370 Strings are given negative hash codes; RTL expressions are given positive
375 struct attr_hash
*next
; /* Next structure in the bucket. */
376 int hashcode
; /* Hash code of this rtx or string. */
379 char *str
; /* The string (negative hash codes) */
380 rtx rtl
; /* or the RTL recorded here. */
384 /* Now here is the hash table. When recording an RTL, it is added to
385 the slot whose index is the hash code mod the table size. Note
386 that the hash table is used for several kinds of RTL (see attr_rtx)
387 and for strings. While all these live in the same table, they are
388 completely independent, and the hash code is computed differently
391 #define RTL_HASH_SIZE 4093
392 struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
394 /* Here is how primitive or already-shared RTL's hash
396 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
398 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
401 attr_hash_add_rtx (int hashcode
, rtx rtl
)
405 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
406 h
->hashcode
= hashcode
;
408 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
409 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
412 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
415 attr_hash_add_string (int hashcode
, char *str
)
419 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
420 h
->hashcode
= -hashcode
;
422 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
423 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
426 /* Generate an RTL expression, but avoid duplicates.
427 Set the ATTR_PERMANENT_P flag for these permanent objects.
429 In some cases we cannot uniquify; then we return an ordinary
430 impermanent rtx with ATTR_PERMANENT_P clear.
434 rtx attr_rtx (code, [element1, ..., elementn]) */
437 attr_rtx_1 (enum rtx_code code
, va_list p
)
439 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
442 struct obstack
*old_obstack
= rtl_obstack
;
444 /* For each of several cases, search the hash table for an existing entry.
445 Use that entry if one is found; otherwise create a new RTL and add it
448 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
450 rtx arg0
= va_arg (p
, rtx
);
452 /* A permanent object cannot point to impermanent ones. */
453 if (! ATTR_PERMANENT_P (arg0
))
455 rt_val
= rtx_alloc (code
);
456 XEXP (rt_val
, 0) = arg0
;
460 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
461 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
462 if (h
->hashcode
== hashcode
463 && GET_CODE (h
->u
.rtl
) == code
464 && XEXP (h
->u
.rtl
, 0) == arg0
)
469 rtl_obstack
= hash_obstack
;
470 rt_val
= rtx_alloc (code
);
471 XEXP (rt_val
, 0) = arg0
;
474 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
475 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
476 || GET_RTX_CLASS (code
) == RTX_COMPARE
477 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
479 rtx arg0
= va_arg (p
, rtx
);
480 rtx arg1
= va_arg (p
, rtx
);
482 /* A permanent object cannot point to impermanent ones. */
483 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
485 rt_val
= rtx_alloc (code
);
486 XEXP (rt_val
, 0) = arg0
;
487 XEXP (rt_val
, 1) = arg1
;
491 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
492 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
493 if (h
->hashcode
== hashcode
494 && GET_CODE (h
->u
.rtl
) == code
495 && XEXP (h
->u
.rtl
, 0) == arg0
496 && XEXP (h
->u
.rtl
, 1) == arg1
)
501 rtl_obstack
= hash_obstack
;
502 rt_val
= rtx_alloc (code
);
503 XEXP (rt_val
, 0) = arg0
;
504 XEXP (rt_val
, 1) = arg1
;
507 else if (GET_RTX_LENGTH (code
) == 1
508 && GET_RTX_FORMAT (code
)[0] == 's')
510 char *arg0
= va_arg (p
, char *);
512 arg0
= DEF_ATTR_STRING (arg0
);
514 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
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
)
523 rtl_obstack
= hash_obstack
;
524 rt_val
= rtx_alloc (code
);
525 XSTR (rt_val
, 0) = arg0
;
528 else if (GET_RTX_LENGTH (code
) == 2
529 && GET_RTX_FORMAT (code
)[0] == 's'
530 && GET_RTX_FORMAT (code
)[1] == 's')
532 char *arg0
= va_arg (p
, char *);
533 char *arg1
= va_arg (p
, char *);
535 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
536 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
537 if (h
->hashcode
== hashcode
538 && GET_CODE (h
->u
.rtl
) == code
539 && XSTR (h
->u
.rtl
, 0) == arg0
540 && XSTR (h
->u
.rtl
, 1) == arg1
)
545 rtl_obstack
= hash_obstack
;
546 rt_val
= rtx_alloc (code
);
547 XSTR (rt_val
, 0) = arg0
;
548 XSTR (rt_val
, 1) = arg1
;
551 else if (code
== CONST_INT
)
553 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
563 int i
; /* Array indices... */
564 const char *fmt
; /* Current rtx's format... */
566 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
568 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
569 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
573 case '0': /* Unused field. */
576 case 'i': /* An integer? */
577 XINT (rt_val
, i
) = va_arg (p
, int);
580 case 'w': /* A wide integer? */
581 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
584 case 's': /* A string? */
585 XSTR (rt_val
, i
) = va_arg (p
, char *);
588 case 'e': /* An expression? */
589 case 'u': /* An insn? Same except when printing. */
590 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
593 case 'E': /* An RTX vector? */
594 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
604 rtl_obstack
= old_obstack
;
605 attr_hash_add_rtx (hashcode
, rt_val
);
606 ATTR_PERMANENT_P (rt_val
) = 1;
611 attr_rtx (enum rtx_code code
, ...)
617 result
= attr_rtx_1 (code
, p
);
622 /* Create a new string printed with the printf line arguments into a space
623 of at most LEN bytes:
625 rtx attr_printf (len, format, [arg1, ..., argn]) */
628 attr_printf (unsigned int len
, const char *fmt
, ...)
635 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
637 vsprintf (str
, fmt
, p
);
640 return DEF_ATTR_STRING (str
);
644 attr_eq (const char *name
, const char *value
)
646 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
652 return XSTR (make_numeric_value (n
), 0);
655 /* Return a permanent (possibly shared) copy of a string STR (not assumed
656 to be null terminated) with LEN bytes. */
659 attr_string (const char *str
, int len
)
666 /* Compute the hash code. */
667 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
668 for (i
= 1; i
<= len
; i
+= 2)
669 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
671 hashcode
= -hashcode
;
673 /* Search the table for the string. */
674 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
675 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
676 && !strncmp (h
->u
.str
, str
, len
))
677 return h
->u
.str
; /* <-- return if found. */
679 /* Not found; create a permanent copy and add it to the hash table. */
680 new_str
= obstack_alloc (hash_obstack
, len
+ 1);
681 memcpy (new_str
, str
, len
);
683 attr_hash_add_string (hashcode
, new_str
);
685 return new_str
; /* Return the new string. */
688 /* Check two rtx's for equality of contents,
689 taking advantage of the fact that if both are hashed
690 then they can't be equal unless they are the same object. */
693 attr_equal_p (rtx x
, rtx y
)
695 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
696 && rtx_equal_p (x
, y
)));
699 /* Copy an attribute value expression,
700 descending to all depths, but not copying any
701 permanent hashed subexpressions. */
704 attr_copy_rtx (rtx orig
)
709 const char *format_ptr
;
711 /* No need to copy a permanent object. */
712 if (ATTR_PERMANENT_P (orig
))
715 code
= GET_CODE (orig
);
733 copy
= rtx_alloc (code
);
734 PUT_MODE (copy
, GET_MODE (orig
));
735 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
736 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
737 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
738 ATTR_EQ_ATTR_P (copy
) = ATTR_EQ_ATTR_P (orig
);
740 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
742 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
744 switch (*format_ptr
++)
747 XEXP (copy
, i
) = XEXP (orig
, i
);
748 if (XEXP (orig
, i
) != NULL
)
749 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
754 XVEC (copy
, i
) = XVEC (orig
, i
);
755 if (XVEC (orig
, i
) != NULL
)
757 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
758 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
759 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
765 XINT (copy
, i
) = XINT (orig
, i
);
769 XWINT (copy
, i
) = XWINT (orig
, i
);
774 XSTR (copy
, i
) = XSTR (orig
, i
);
784 /* Given a test expression for an attribute, ensure it is validly formed.
785 IS_CONST indicates whether the expression is constant for each compiler
786 run (a constant expression may not test any particular insn).
788 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
789 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
790 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
792 Update the string address in EQ_ATTR expression to be the same used
793 in the attribute (or `alternative_name') to speed up subsequent
794 `find_attr' calls and eliminate most `strcmp' calls.
796 Return the new expression, if any. */
799 check_attr_test (rtx exp
, int is_const
, int lineno
)
801 struct attr_desc
*attr
;
802 struct attr_value
*av
;
803 const char *name_ptr
, *p
;
806 switch (GET_CODE (exp
))
809 /* Handle negation test. */
810 if (XSTR (exp
, 1)[0] == '!')
811 return check_attr_test (attr_rtx (NOT
,
812 attr_eq (XSTR (exp
, 0),
816 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
818 attr
= find_attr (&XSTR (exp
, 0), 0);
821 if (! strcmp (XSTR (exp
, 0), "alternative"))
822 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
824 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
827 if (is_const
&& ! attr
->is_const
)
828 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
831 /* Copy this just to make it permanent,
832 so expressions using it can be permanent too. */
833 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
835 /* It shouldn't be possible to simplify the value given to a
836 constant attribute, so don't expand this until it's time to
837 write the test expression. */
839 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
841 if (attr
->is_numeric
)
843 for (p
= XSTR (exp
, 1); *p
; p
++)
845 fatal ("attribute `%s' takes only numeric values",
850 for (av
= attr
->first_value
; av
; av
= av
->next
)
851 if (GET_CODE (av
->value
) == CONST_STRING
852 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
856 fatal ("unknown value `%s' for `%s' attribute",
857 XSTR (exp
, 1), XSTR (exp
, 0));
862 if (! strcmp (XSTR (exp
, 0), "alternative"))
866 name_ptr
= XSTR (exp
, 1);
867 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
868 set
|= 1 << atoi (p
);
870 return mk_attr_alt (set
);
874 /* Make an IOR tree of the possible values. */
876 name_ptr
= XSTR (exp
, 1);
877 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
879 newexp
= attr_eq (XSTR (exp
, 0), p
);
880 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
883 return check_attr_test (orexp
, is_const
, lineno
);
892 /* Either TRUE or FALSE. */
900 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
901 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
905 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
910 fatal ("RTL operator \"%s\" not valid in constant attribute test",
911 GET_RTX_NAME (GET_CODE (exp
)));
912 /* These cases can't be simplified. */
913 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
916 case LE
: case LT
: case GT
: case GE
:
917 case LEU
: case LTU
: case GTU
: case GEU
:
919 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
920 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
921 exp
= attr_rtx (GET_CODE (exp
),
922 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
923 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
924 /* These cases can't be simplified. */
925 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
931 /* These cases are valid for constant attributes, but can't be
933 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
934 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
938 fatal ("RTL operator \"%s\" not valid in attribute test",
939 GET_RTX_NAME (GET_CODE (exp
)));
945 /* Given an expression, ensure that it is validly formed and that all named
946 attribute values are valid for the given attribute. Issue a fatal error
947 if not. If no attribute is specified, assume a numeric attribute.
949 Return a perhaps modified replacement expression for the value. */
952 check_attr_value (rtx exp
, struct attr_desc
*attr
)
954 struct attr_value
*av
;
958 switch (GET_CODE (exp
))
961 if (attr
&& ! attr
->is_numeric
)
963 message_with_line (attr
->lineno
,
964 "CONST_INT not valid for non-numeric attribute %s",
970 if (INTVAL (exp
) < 0 && ! attr
->negative_ok
)
972 message_with_line (attr
->lineno
,
973 "negative numeric value specified for attribute %s",
981 if (! strcmp (XSTR (exp
, 0), "*"))
984 if (attr
== 0 || attr
->is_numeric
)
987 if (attr
&& attr
->negative_ok
&& *p
== '-')
992 message_with_line (attr
? attr
->lineno
: 0,
993 "non-numeric value for numeric attribute %s",
994 attr
? attr
->name
: "internal");
1001 for (av
= attr
->first_value
; av
; av
= av
->next
)
1002 if (GET_CODE (av
->value
) == CONST_STRING
1003 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
1008 message_with_line (attr
->lineno
,
1009 "unknown value `%s' for `%s' attribute",
1010 XSTR (exp
, 0), attr
? attr
->name
: "internal");
1016 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
1017 attr
? attr
->is_const
: 0,
1018 attr
? attr
->lineno
: 0);
1019 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1020 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
1028 if (attr
&& !attr
->is_numeric
)
1030 message_with_line (attr
->lineno
,
1031 "invalid operation `%s' for non-numeric attribute value",
1032 GET_RTX_NAME (GET_CODE (exp
)));
1040 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1041 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1049 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1053 if (XVECLEN (exp
, 0) % 2 != 0)
1055 message_with_line (attr
->lineno
,
1056 "first operand of COND must have even length");
1061 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1063 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1064 attr
? attr
->is_const
: 0,
1065 attr
? attr
->lineno
: 0);
1066 XVECEXP (exp
, 0, i
+ 1)
1067 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1070 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1075 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1078 message_with_line (attr
? attr
->lineno
: 0,
1079 "unknown attribute `%s' in ATTR",
1083 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1085 message_with_line (attr
->lineno
,
1086 "non-constant attribute `%s' referenced from `%s'",
1087 XSTR (exp
, 0), attr
->name
);
1091 && (attr
->is_numeric
!= attr2
->is_numeric
1092 || (! attr
->negative_ok
&& attr2
->negative_ok
)))
1094 message_with_line (attr
->lineno
,
1095 "numeric attribute mismatch calling `%s' from `%s'",
1096 XSTR (exp
, 0), attr
->name
);
1103 /* A constant SYMBOL_REF is valid as a constant attribute test and
1104 is expanded later by make_canonical into a COND. In a non-constant
1105 attribute test, it is left be. */
1106 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1109 message_with_line (attr
? attr
->lineno
: 0,
1110 "invalid operation `%s' for attribute value",
1111 GET_RTX_NAME (GET_CODE (exp
)));
1119 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1120 It becomes a COND with each test being (eq_attr "alternative "n") */
1123 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1125 int num_alt
= id
->num_alternatives
;
1129 if (XVECLEN (exp
, 1) != num_alt
)
1131 message_with_line (id
->lineno
,
1132 "bad number of entries in SET_ATTR_ALTERNATIVE");
1137 /* Make a COND with all tests but the last. Select the last value via the
1139 condexp
= rtx_alloc (COND
);
1140 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1142 for (i
= 0; i
< num_alt
- 1; i
++)
1145 p
= attr_numeral (i
);
1147 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1148 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1151 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1153 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1156 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1157 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1160 convert_set_attr (rtx exp
, struct insn_def
*id
)
1163 const char *name_ptr
;
1167 /* See how many alternative specified. */
1168 n
= n_comma_elts (XSTR (exp
, 1));
1170 return attr_rtx (SET
,
1171 attr_rtx (ATTR
, XSTR (exp
, 0)),
1172 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1174 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1175 XSTR (newexp
, 0) = XSTR (exp
, 0);
1176 XVEC (newexp
, 1) = rtvec_alloc (n
);
1178 /* Process each comma-separated name. */
1179 name_ptr
= XSTR (exp
, 1);
1181 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1182 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1184 return convert_set_attr_alternative (newexp
, id
);
1187 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1188 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1194 struct insn_def
*id
;
1195 struct attr_desc
*attr
;
1199 for (id
= defs
; id
; id
= id
->next
)
1201 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1204 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1206 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1207 switch (GET_CODE (value
))
1210 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1212 message_with_line (id
->lineno
, "bad attribute set");
1218 case SET_ATTR_ALTERNATIVE
:
1219 value
= convert_set_attr_alternative (value
, id
);
1223 value
= convert_set_attr (value
, id
);
1227 message_with_line (id
->lineno
, "invalid attribute code %s",
1228 GET_RTX_NAME (GET_CODE (value
)));
1232 if (value
== NULL_RTX
)
1235 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1237 message_with_line (id
->lineno
, "unknown attribute %s",
1238 XSTR (XEXP (value
, 0), 0));
1243 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1244 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1249 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1250 expressions by converting them into a COND. This removes cases from this
1251 program. Also, replace an attribute value of "*" with the default attribute
1255 make_canonical (struct attr_desc
*attr
, rtx exp
)
1260 switch (GET_CODE (exp
))
1263 exp
= make_numeric_value (INTVAL (exp
));
1267 if (! strcmp (XSTR (exp
, 0), "*"))
1269 if (attr
== 0 || attr
->default_val
== 0)
1270 fatal ("(attr_value \"*\") used in invalid context");
1271 exp
= attr
->default_val
->value
;
1274 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1279 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1281 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1282 This makes the COND something that won't be considered an arbitrary
1283 expression by walk_attr_value. */
1284 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1285 exp
= check_attr_value (exp
, attr
);
1289 newexp
= rtx_alloc (COND
);
1290 XVEC (newexp
, 0) = rtvec_alloc (2);
1291 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1292 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1294 XEXP (newexp
, 1) = XEXP (exp
, 2);
1297 /* Fall through to COND case since this is now a COND. */
1304 /* First, check for degenerate COND. */
1305 if (XVECLEN (exp
, 0) == 0)
1306 return make_canonical (attr
, XEXP (exp
, 1));
1307 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1309 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1311 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1312 XVECEXP (exp
, 0, i
+ 1)
1313 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1314 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1330 copy_boolean (rtx exp
)
1332 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1333 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1334 copy_boolean (XEXP (exp
, 1)));
1335 if (GET_CODE (exp
) == MATCH_OPERAND
)
1337 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1338 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1340 else if (GET_CODE (exp
) == EQ_ATTR
)
1342 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1343 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1349 /* Given a value and an attribute description, return a `struct attr_value *'
1350 that represents that value. This is either an existing structure, if the
1351 value has been previously encountered, or a newly-created structure.
1353 `insn_code' is the code of an insn whose attribute has the specified
1354 value (-2 if not processing an insn). We ensure that all insns for
1355 a given value have the same number of alternatives if the value checks
1358 static struct attr_value
*
1359 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1361 struct attr_value
*av
;
1364 value
= make_canonical (attr
, value
);
1365 if (compares_alternatives_p (value
))
1367 if (insn_code
< 0 || insn_alternatives
== NULL
)
1368 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1370 num_alt
= insn_alternatives
[insn_code
];
1373 for (av
= attr
->first_value
; av
; av
= av
->next
)
1374 if (rtx_equal_p (value
, av
->value
)
1375 && (num_alt
== 0 || av
->first_insn
== NULL
1376 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1379 av
= oballoc (sizeof (struct attr_value
));
1381 av
->next
= attr
->first_value
;
1382 attr
->first_value
= av
;
1383 av
->first_insn
= NULL
;
1385 av
->has_asm_insn
= 0;
1390 /* After all DEFINE_DELAYs have been read in, create internal attributes
1391 to generate the required routines.
1393 First, we compute the number of delay slots for each insn (as a COND of
1394 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1395 delay type is specified, we compute a similar function giving the
1396 DEFINE_DELAY ordinal for each insn.
1398 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1399 tells whether a given insn can be in that delay slot.
1401 Normal attribute filling and optimization expands these to contain the
1402 information needed to handle delay slots. */
1405 expand_delays (void)
1407 struct delay_desc
*delay
;
1413 /* First, generate data for `num_delay_slots' function. */
1415 condexp
= rtx_alloc (COND
);
1416 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1417 XEXP (condexp
, 1) = make_numeric_value (0);
1419 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1421 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1422 XVECEXP (condexp
, 0, i
+ 1)
1423 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1426 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1428 /* If more than one delay type, do the same for computing the delay type. */
1431 condexp
= rtx_alloc (COND
);
1432 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1433 XEXP (condexp
, 1) = make_numeric_value (0);
1435 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1437 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1438 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1441 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1444 /* For each delay possibility and delay slot, compute an eligibility
1445 attribute for non-annulled insns and for each type of annulled (annul
1446 if true and annul if false). */
1447 for (delay
= delays
; delay
; delay
= delay
->next
)
1449 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1451 condexp
= XVECEXP (delay
->def
, 1, i
);
1453 condexp
= false_rtx
;
1454 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1455 make_numeric_value (1), make_numeric_value (0));
1457 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1458 "*delay_%d_%d", delay
->num
, i
/ 3);
1459 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1461 if (have_annul_true
)
1463 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1464 if (condexp
== 0) condexp
= false_rtx
;
1465 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1466 make_numeric_value (1),
1467 make_numeric_value (0));
1468 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1469 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1470 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1473 if (have_annul_false
)
1475 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1476 if (condexp
== 0) condexp
= false_rtx
;
1477 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1478 make_numeric_value (1),
1479 make_numeric_value (0));
1480 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1481 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1482 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1488 /* Once all attributes and insns have been read and checked, we construct for
1489 each attribute value a list of all the insns that have that value for
1493 fill_attr (struct attr_desc
*attr
)
1495 struct attr_value
*av
;
1496 struct insn_ent
*ie
;
1497 struct insn_def
*id
;
1501 /* Don't fill constant attributes. The value is independent of
1502 any particular insn. */
1506 for (id
= defs
; id
; id
= id
->next
)
1508 /* If no value is specified for this insn for this attribute, use the
1511 if (XVEC (id
->def
, id
->vec_idx
))
1512 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1513 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1515 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1518 av
= attr
->default_val
;
1520 av
= get_attr_value (value
, attr
, id
->insn_code
);
1522 ie
= oballoc (sizeof (struct insn_ent
));
1524 insert_insn_ent (av
, ie
);
1528 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1529 test that checks relative positions of insns (uses MATCH_DUP or PC).
1530 If so, replace it with what is obtained by passing the expression to
1531 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1532 recursively on each value (including the default value). Otherwise,
1533 return the value returned by NO_ADDRESS_FN applied to EXP. */
1536 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1537 rtx (*address_fn
) (rtx
))
1542 if (GET_CODE (exp
) == COND
)
1544 /* See if any tests use addresses. */
1546 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1547 walk_attr_value (XVECEXP (exp
, 0, i
));
1550 return (*address_fn
) (exp
);
1552 /* Make a new copy of this COND, replacing each element. */
1553 newexp
= rtx_alloc (COND
);
1554 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1555 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1557 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1558 XVECEXP (newexp
, 0, i
+ 1)
1559 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1560 no_address_fn
, address_fn
);
1563 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1564 no_address_fn
, address_fn
);
1569 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1572 walk_attr_value (XEXP (exp
, 0));
1574 return (*address_fn
) (exp
);
1576 return attr_rtx (IF_THEN_ELSE
,
1577 substitute_address (XEXP (exp
, 0),
1578 no_address_fn
, address_fn
),
1579 substitute_address (XEXP (exp
, 1),
1580 no_address_fn
, address_fn
),
1581 substitute_address (XEXP (exp
, 2),
1582 no_address_fn
, address_fn
));
1585 return (*no_address_fn
) (exp
);
1588 /* Make new attributes from the `length' attribute. The following are made,
1589 each corresponding to a function called from `shorten_branches' or
1592 *insn_default_length This is the length of the insn to be returned
1593 by `get_attr_length' before `shorten_branches'
1594 has been called. In each case where the length
1595 depends on relative addresses, the largest
1596 possible is used. This routine is also used
1597 to compute the initial size of the insn.
1599 *insn_variable_length_p This returns 1 if the insn's length depends
1600 on relative addresses, zero otherwise.
1602 *insn_current_length This is only called when it is known that the
1603 insn has a variable length and returns the
1604 current length, based on relative addresses.
1608 make_length_attrs (void)
1610 static const char *new_names
[] =
1612 "*insn_default_length",
1613 "*insn_variable_length_p",
1614 "*insn_current_length"
1616 static rtx (*const no_address_fn
[]) (rtx
) = {identity_fn
, zero_fn
, zero_fn
};
1617 static rtx (*const address_fn
[]) (rtx
) = {max_fn
, one_fn
, identity_fn
};
1619 struct attr_desc
*length_attr
, *new_attr
;
1620 struct attr_value
*av
, *new_av
;
1621 struct insn_ent
*ie
, *new_ie
;
1623 /* See if length attribute is defined. If so, it must be numeric. Make
1624 it special so we don't output anything for it. */
1625 length_attr
= find_attr (&length_str
, 0);
1626 if (length_attr
== 0)
1629 if (! length_attr
->is_numeric
)
1630 fatal ("length attribute must be numeric");
1632 length_attr
->is_const
= 0;
1633 length_attr
->is_special
= 1;
1635 /* Make each new attribute, in turn. */
1636 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1638 make_internal_attr (new_names
[i
],
1639 substitute_address (length_attr
->default_val
->value
,
1640 no_address_fn
[i
], address_fn
[i
]),
1642 new_attr
= find_attr (&new_names
[i
], 0);
1643 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1644 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1646 new_av
= get_attr_value (substitute_address (av
->value
,
1649 new_attr
, ie
->def
->insn_code
);
1650 new_ie
= oballoc (sizeof (struct insn_ent
));
1651 new_ie
->def
= ie
->def
;
1652 insert_insn_ent (new_av
, new_ie
);
1657 /* Utility functions called from above routine. */
1660 identity_fn (rtx exp
)
1666 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1668 return make_numeric_value (0);
1672 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1674 return make_numeric_value (1);
1681 return make_numeric_value (max_attr_value (exp
, &unknown
));
1685 write_length_unit_log (void)
1687 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1688 struct attr_value
*av
;
1689 struct insn_ent
*ie
;
1690 unsigned int length_unit_log
, length_or
;
1693 if (length_attr
== 0)
1695 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1696 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1697 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1698 length_or
|= or_attr_value (av
->value
, &unknown
);
1701 length_unit_log
= 0;
1704 length_or
= ~length_or
;
1705 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1708 printf ("int length_unit_log = %u;\n", length_unit_log
);
1711 /* Take a COND expression and see if any of the conditions in it can be
1712 simplified. If any are known true or known false for the particular insn
1713 code, the COND can be further simplified.
1715 Also call ourselves on any COND operations that are values of this COND.
1717 We do not modify EXP; rather, we make and return a new rtx. */
1720 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1723 /* We store the desired contents here,
1724 then build a new expression if they don't match EXP. */
1725 rtx defval
= XEXP (exp
, 1);
1726 rtx new_defval
= XEXP (exp
, 1);
1727 int len
= XVECLEN (exp
, 0);
1728 rtx
*tests
= xmalloc (len
* sizeof (rtx
));
1732 /* This lets us free all storage allocated below, if appropriate. */
1733 obstack_finish (rtl_obstack
);
1735 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1737 /* See if default value needs simplification. */
1738 if (GET_CODE (defval
) == COND
)
1739 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1741 /* Simplify the subexpressions, and see what tests we can get rid of. */
1743 for (i
= 0; i
< len
; i
+= 2)
1745 rtx newtest
, newval
;
1747 /* Simplify this test. */
1748 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1751 newval
= tests
[i
+ 1];
1752 /* See if this value may need simplification. */
1753 if (GET_CODE (newval
) == COND
)
1754 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1756 /* Look for ways to delete or combine this test. */
1757 if (newtest
== true_rtx
)
1759 /* If test is true, make this value the default
1760 and discard this + any following tests. */
1762 defval
= tests
[i
+ 1];
1763 new_defval
= newval
;
1766 else if (newtest
== false_rtx
)
1768 /* If test is false, discard it and its value. */
1769 for (j
= i
; j
< len
- 2; j
++)
1770 tests
[j
] = tests
[j
+ 2];
1775 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1777 /* If this value and the value for the prev test are the same,
1781 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1782 insn_code
, insn_index
);
1784 /* Delete this test/value. */
1785 for (j
= i
; j
< len
- 2; j
++)
1786 tests
[j
] = tests
[j
+ 2];
1792 tests
[i
+ 1] = newval
;
1795 /* If the last test in a COND has the same value
1796 as the default value, that test isn't needed. */
1798 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1801 /* See if we changed anything. */
1802 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1805 for (i
= 0; i
< len
; i
++)
1806 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1814 if (GET_CODE (defval
) == COND
)
1815 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1823 rtx newexp
= rtx_alloc (COND
);
1825 XVEC (newexp
, 0) = rtvec_alloc (len
);
1826 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1827 XEXP (newexp
, 1) = new_defval
;
1834 /* Remove an insn entry from an attribute value. */
1837 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1839 struct insn_ent
*previe
;
1841 if (av
->first_insn
== ie
)
1842 av
->first_insn
= ie
->next
;
1845 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1847 previe
->next
= ie
->next
;
1851 if (ie
->def
->insn_code
== -1)
1852 av
->has_asm_insn
= 0;
1857 /* Insert an insn entry in an attribute value list. */
1860 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1862 ie
->next
= av
->first_insn
;
1863 av
->first_insn
= ie
;
1865 if (ie
->def
->insn_code
== -1)
1866 av
->has_asm_insn
= 1;
1871 /* This is a utility routine to take an expression that is a tree of either
1872 AND or IOR expressions and insert a new term. The new term will be
1873 inserted at the right side of the first node whose code does not match
1874 the root. A new node will be created with the root's code. Its left
1875 side will be the old right side and its right side will be the new
1878 If the `term' is itself a tree, all its leaves will be inserted. */
1881 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1885 /* Avoid consing in some special cases. */
1886 if (code
== AND
&& term
== true_rtx
)
1888 if (code
== AND
&& term
== false_rtx
)
1890 if (code
== AND
&& exp
== true_rtx
)
1892 if (code
== AND
&& exp
== false_rtx
)
1894 if (code
== IOR
&& term
== true_rtx
)
1896 if (code
== IOR
&& term
== false_rtx
)
1898 if (code
== IOR
&& exp
== true_rtx
)
1900 if (code
== IOR
&& exp
== false_rtx
)
1902 if (attr_equal_p (exp
, term
))
1905 if (GET_CODE (term
) == code
)
1907 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1908 insn_code
, insn_index
);
1909 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1910 insn_code
, insn_index
);
1915 if (GET_CODE (exp
) == code
)
1917 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1918 term
, insn_code
, insn_index
);
1919 if (new != XEXP (exp
, 1))
1920 /* Make a copy of this expression and call recursively. */
1921 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1927 /* Insert the new term. */
1928 newexp
= attr_rtx (code
, exp
, term
);
1931 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1934 /* If we have an expression which AND's a bunch of
1935 (not (eq_attrq "alternative" "n"))
1936 terms, we may have covered all or all but one of the possible alternatives.
1937 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1939 This routine is passed an expression and either AND or IOR. It returns a
1940 bitmask indicating which alternatives are mentioned within EXP. */
1943 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1946 if (GET_CODE (exp
) == code
)
1947 return compute_alternative_mask (XEXP (exp
, 0), code
)
1948 | compute_alternative_mask (XEXP (exp
, 1), code
);
1950 else if (code
== AND
&& GET_CODE (exp
) == NOT
1951 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1952 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1953 string
= XSTR (XEXP (exp
, 0), 1);
1955 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1956 && XSTR (exp
, 0) == alternative_name
)
1957 string
= XSTR (exp
, 1);
1959 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1961 if (code
== AND
&& XINT (exp
, 1))
1962 return XINT (exp
, 0);
1964 if (code
== IOR
&& !XINT (exp
, 1))
1965 return XINT (exp
, 0);
1973 return 1 << (string
[0] - '0');
1974 return 1 << atoi (string
);
1977 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1978 attribute with the value represented by that bit. */
1981 make_alternative_compare (int mask
)
1983 return mk_attr_alt (mask
);
1986 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1987 of "attr" for this insn code. From that value, we can compute a test
1988 showing when the EQ_ATTR will be true. This routine performs that
1989 computation. If a test condition involves an address, we leave the EQ_ATTR
1990 intact because addresses are only valid for the `length' attribute.
1992 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1993 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1996 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
2003 switch (GET_CODE (value
))
2006 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2017 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2018 gcc_assert (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2
2021 strcpy (string
, XSTR (exp
, 0));
2022 strcat (string
, "_");
2023 strcat (string
, XSTR (exp
, 1));
2024 for (p
= string
; *p
; p
++)
2027 newexp
= attr_rtx (EQ
, value
,
2028 attr_rtx (SYMBOL_REF
,
2029 DEF_ATTR_STRING (string
)));
2034 /* We construct an IOR of all the cases for which the
2035 requested attribute value is present. Since we start with
2036 FALSE, if it is not present, FALSE will be returned.
2038 Each case is the AND of the NOT's of the previous conditions with the
2039 current condition; in the default case the current condition is TRUE.
2041 For each possible COND value, call ourselves recursively.
2043 The extra TRUE and FALSE expressions will be eliminated by another
2044 call to the simplification routine. */
2049 if (current_alternative_string
)
2050 clear_struct_flag (value
);
2052 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2054 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2055 insn_code
, insn_index
);
2057 SIMPLIFY_ALTERNATIVE (this);
2059 right
= insert_right_side (AND
, andexp
, this,
2060 insn_code
, insn_index
);
2061 right
= insert_right_side (AND
, right
,
2062 evaluate_eq_attr (exp
,
2065 insn_code
, insn_index
),
2066 insn_code
, insn_index
);
2067 orexp
= insert_right_side (IOR
, orexp
, right
,
2068 insn_code
, insn_index
);
2070 /* Add this condition into the AND expression. */
2071 newexp
= attr_rtx (NOT
, this);
2072 andexp
= insert_right_side (AND
, andexp
, newexp
,
2073 insn_code
, insn_index
);
2076 /* Handle the default case. */
2077 right
= insert_right_side (AND
, andexp
,
2078 evaluate_eq_attr (exp
, XEXP (value
, 1),
2079 insn_code
, insn_index
),
2080 insn_code
, insn_index
);
2081 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2088 /* If uses an address, must return original expression. But set the
2089 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2092 walk_attr_value (newexp
);
2096 /* This had `&& current_alternative_string', which seems to be wrong. */
2097 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2098 return copy_rtx_unchanging (exp
);
2105 /* This routine is called when an AND of a term with a tree of AND's is
2106 encountered. If the term or its complement is present in the tree, it
2107 can be replaced with TRUE or FALSE, respectively.
2109 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2110 be true and hence are complementary.
2112 There is one special case: If we see
2113 (and (not (eq_attr "att" "v1"))
2114 (eq_attr "att" "v2"))
2115 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2116 replace the term, not anything in the AND tree. So we pass a pointer to
2120 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2125 int left_eliminates_term
, right_eliminates_term
;
2127 if (GET_CODE (exp
) == AND
)
2129 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2130 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2131 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2133 newexp
= attr_rtx (AND
, left
, right
);
2135 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2139 else if (GET_CODE (exp
) == IOR
)
2141 /* For the IOR case, we do the same as above, except that we can
2142 only eliminate `term' if both sides of the IOR would do so. */
2144 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2145 left_eliminates_term
= (temp
== true_rtx
);
2148 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2149 right_eliminates_term
= (temp
== true_rtx
);
2151 if (left_eliminates_term
&& right_eliminates_term
)
2154 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2156 newexp
= attr_rtx (IOR
, left
, right
);
2158 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2162 /* Check for simplifications. Do some extra checking here since this
2163 routine is called so many times. */
2168 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2171 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2174 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2176 if (attr_alt_subset_p (*pterm
, exp
))
2179 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2182 if (attr_alt_subset_p (exp
, *pterm
))
2188 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2190 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2193 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2199 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2200 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2202 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2205 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2211 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2212 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2214 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2217 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2223 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2225 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2229 else if (GET_CODE (exp
) == NOT
)
2231 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2235 else if (GET_CODE (*pterm
) == NOT
)
2237 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2241 else if (attr_equal_p (exp
, *pterm
))
2247 /* Similar to `simplify_and_tree', but for IOR trees. */
2250 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2255 int left_eliminates_term
, right_eliminates_term
;
2257 if (GET_CODE (exp
) == IOR
)
2259 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2260 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2261 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2263 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2265 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2269 else if (GET_CODE (exp
) == AND
)
2271 /* For the AND case, we do the same as above, except that we can
2272 only eliminate `term' if both sides of the AND would do so. */
2274 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2275 left_eliminates_term
= (temp
== false_rtx
);
2278 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2279 right_eliminates_term
= (temp
== false_rtx
);
2281 if (left_eliminates_term
&& right_eliminates_term
)
2284 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2286 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2288 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2292 if (attr_equal_p (exp
, *pterm
))
2295 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2298 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2301 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2302 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2303 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2306 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2307 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2308 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2314 /* Compute approximate cost of the expression. Used to decide whether
2315 expression is cheap enough for inline. */
2317 attr_rtx_cost (rtx x
)
2323 code
= GET_CODE (x
);
2336 /* Alternatives don't result into function call. */
2337 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2344 const char *fmt
= GET_RTX_FORMAT (code
);
2345 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2351 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2352 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2355 cost
+= attr_rtx_cost (XEXP (x
, i
));
2365 /* Simplify test expression and use temporary obstack in order to avoid
2366 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2367 and avoid unnecessary copying if possible. */
2370 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2373 struct obstack
*old
;
2374 if (ATTR_IND_SIMPLIFIED_P (exp
))
2377 rtl_obstack
= temp_obstack
;
2378 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2380 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2382 return attr_copy_rtx (x
);
2385 /* Returns true if S1 is a subset of S2. */
2388 attr_alt_subset_p (rtx s1
, rtx s2
)
2390 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2393 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2396 return !(XINT (s1
, 0) & XINT (s2
, 0));
2402 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2409 /* Returns true if S1 is a subset of complement of S2. */
2412 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2414 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2417 return !(XINT (s1
, 0) & XINT (s2
, 0));
2420 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2423 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2433 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2436 attr_alt_intersection (rtx s1
, rtx s2
)
2438 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2440 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2443 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2446 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2449 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2452 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2457 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2462 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2465 attr_alt_union (rtx s1
, rtx s2
)
2467 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2469 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2472 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2475 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2478 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2481 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2487 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2491 /* Return EQ_ATTR_ALT expression representing complement of S. */
2494 attr_alt_complement (rtx s
)
2496 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2498 XINT (result
, 0) = XINT (s
, 0);
2499 XINT (result
, 1) = 1 - XINT (s
, 1);
2504 /* Tests whether a bit B belongs to the set represented by S. */
2507 attr_alt_bit_p (rtx s
, int b
)
2509 return XINT (s
, 1) ^ ((XINT (s
, 0) >> b
) & 1);
2512 /* Return EQ_ATTR_ALT expression representing set containing elements set
2518 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2520 XINT (result
, 0) = e
;
2521 XINT (result
, 1) = 0;
2526 /* Given an expression, see if it can be simplified for a particular insn
2527 code based on the values of other attributes being tested. This can
2528 eliminate nested get_attr_... calls.
2530 Note that if an endless recursion is specified in the patterns, the
2531 optimization will loop. However, it will do so in precisely the cases where
2532 an infinite recursion loop could occur during compilation. It's better that
2536 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2539 struct attr_desc
*attr
;
2540 struct attr_value
*av
;
2541 struct insn_ent
*ie
;
2544 bool left_alt
, right_alt
;
2546 /* Don't re-simplify something we already simplified. */
2547 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2550 switch (GET_CODE (exp
))
2553 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2554 SIMPLIFY_ALTERNATIVE (left
);
2555 if (left
== false_rtx
)
2557 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2558 SIMPLIFY_ALTERNATIVE (right
);
2559 if (left
== false_rtx
)
2562 if (GET_CODE (left
) == EQ_ATTR_ALT
2563 && GET_CODE (right
) == EQ_ATTR_ALT
)
2565 exp
= attr_alt_intersection (left
, right
);
2566 return simplify_test_exp (exp
, insn_code
, insn_index
);
2569 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2570 present on both sides, apply the distributive law since this will
2571 yield simplifications. */
2572 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2573 && compute_alternative_mask (left
, IOR
)
2574 && compute_alternative_mask (right
, IOR
))
2576 if (GET_CODE (left
) == IOR
)
2583 newexp
= attr_rtx (IOR
,
2584 attr_rtx (AND
, left
, XEXP (right
, 0)),
2585 attr_rtx (AND
, left
, XEXP (right
, 1)));
2587 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2590 /* Try with the term on both sides. */
2591 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2592 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2593 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2595 if (left
== false_rtx
|| right
== false_rtx
)
2597 else if (left
== true_rtx
)
2601 else if (right
== true_rtx
)
2605 /* See if all or all but one of the insn's alternatives are specified
2606 in this tree. Optimize if so. */
2608 if (GET_CODE (left
) == NOT
)
2609 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2610 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2612 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2615 if (GET_CODE (right
) == NOT
)
2616 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2617 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2619 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2620 && XINT (right
, 1));
2623 && (GET_CODE (left
) == AND
2625 || GET_CODE (right
) == AND
2628 i
= compute_alternative_mask (exp
, AND
);
2629 if (i
& ~insn_alternatives
[insn_code
])
2630 fatal ("invalid alternative specified for pattern number %d",
2633 /* If all alternatives are excluded, this is false. */
2634 i
^= insn_alternatives
[insn_code
];
2637 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2639 /* If just one excluded, AND a comparison with that one to the
2640 front of the tree. The others will be eliminated by
2641 optimization. We do not want to do this if the insn has one
2642 alternative and we have tested none of them! */
2643 left
= make_alternative_compare (i
);
2644 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2645 newexp
= attr_rtx (AND
, left
, right
);
2647 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2651 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2653 newexp
= attr_rtx (AND
, left
, right
);
2654 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2659 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2660 SIMPLIFY_ALTERNATIVE (left
);
2661 if (left
== true_rtx
)
2663 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2664 SIMPLIFY_ALTERNATIVE (right
);
2665 if (right
== true_rtx
)
2668 if (GET_CODE (left
) == EQ_ATTR_ALT
2669 && GET_CODE (right
) == EQ_ATTR_ALT
)
2671 exp
= attr_alt_union (left
, right
);
2672 return simplify_test_exp (exp
, insn_code
, insn_index
);
2675 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2676 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2677 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2679 if (right
== true_rtx
|| left
== true_rtx
)
2681 else if (left
== false_rtx
)
2685 else if (right
== false_rtx
)
2690 /* Test for simple cases where the distributive law is useful. I.e.,
2691 convert (ior (and (x) (y))
2697 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2698 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2700 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2702 left
= XEXP (left
, 0);
2704 newexp
= attr_rtx (AND
, left
, right
);
2705 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2708 /* See if all or all but one of the insn's alternatives are specified
2709 in this tree. Optimize if so. */
2711 else if (insn_code
>= 0
2712 && (GET_CODE (left
) == IOR
2713 || (GET_CODE (left
) == EQ_ATTR_ALT
2715 || (GET_CODE (left
) == EQ_ATTR
2716 && XSTR (left
, 0) == alternative_name
)
2717 || GET_CODE (right
) == IOR
2718 || (GET_CODE (right
) == EQ_ATTR_ALT
2719 && !XINT (right
, 1))
2720 || (GET_CODE (right
) == EQ_ATTR
2721 && XSTR (right
, 0) == alternative_name
)))
2723 i
= compute_alternative_mask (exp
, IOR
);
2724 if (i
& ~insn_alternatives
[insn_code
])
2725 fatal ("invalid alternative specified for pattern number %d",
2728 /* If all alternatives are included, this is true. */
2729 i
^= insn_alternatives
[insn_code
];
2732 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2734 /* If just one excluded, IOR a comparison with that one to the
2735 front of the tree. The others will be eliminated by
2736 optimization. We do not want to do this if the insn has one
2737 alternative and we have tested none of them! */
2738 left
= make_alternative_compare (i
);
2739 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2740 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2742 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2746 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2748 newexp
= attr_rtx (IOR
, left
, right
);
2749 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2754 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2756 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2757 insn_code
, insn_index
);
2758 SIMPLIFY_ALTERNATIVE (left
);
2762 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2763 SIMPLIFY_ALTERNATIVE (left
);
2764 if (GET_CODE (left
) == NOT
)
2765 return XEXP (left
, 0);
2767 if (left
== false_rtx
)
2769 if (left
== true_rtx
)
2772 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2774 exp
= attr_alt_complement (left
);
2775 return simplify_test_exp (exp
, insn_code
, insn_index
);
2778 /* Try to apply De`Morgan's laws. */
2779 if (GET_CODE (left
) == IOR
)
2781 newexp
= attr_rtx (AND
,
2782 attr_rtx (NOT
, XEXP (left
, 0)),
2783 attr_rtx (NOT
, XEXP (left
, 1)));
2785 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2787 else if (GET_CODE (left
) == AND
)
2789 newexp
= attr_rtx (IOR
,
2790 attr_rtx (NOT
, XEXP (left
, 0)),
2791 attr_rtx (NOT
, XEXP (left
, 1)));
2793 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2795 else if (left
!= XEXP (exp
, 0))
2797 newexp
= attr_rtx (NOT
, left
);
2802 if (current_alternative_string
)
2803 return attr_alt_bit_p (exp
, atoi (current_alternative_string
)) ? true_rtx
: false_rtx
;
2806 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2810 if (current_alternative_string
&& XSTR (exp
, 0) == alternative_name
)
2811 return (XSTR (exp
, 1) == current_alternative_string
2812 ? true_rtx
: false_rtx
);
2814 if (XSTR (exp
, 0) == alternative_name
)
2816 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2820 /* Look at the value for this insn code in the specified attribute.
2821 We normally can replace this comparison with the condition that
2822 would give this insn the values being tested for. */
2823 if (XSTR (exp
, 0) != alternative_name
2824 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2825 for (av
= attr
->first_value
; av
; av
= av
->next
)
2826 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2827 if (ie
->def
->insn_code
== insn_code
)
2830 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2831 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2832 if (attr_rtx_cost(x
) < 20)
2841 /* We have already simplified this expression. Simplifying it again
2842 won't buy anything unless we weren't given a valid insn code
2843 to process (i.e., we are canonicalizing something.). */
2844 if (insn_code
!= -2 /* Seems wrong: && current_alternative_string. */
2845 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2846 return copy_rtx_unchanging (newexp
);
2851 /* Optimize the attribute lists by seeing if we can determine conditional
2852 values from the known values of other attributes. This will save subroutine
2853 calls during the compilation. */
2856 optimize_attrs (void)
2858 struct attr_desc
*attr
;
2859 struct attr_value
*av
;
2860 struct insn_ent
*ie
;
2863 struct attr_value_list
2865 struct attr_value
*av
;
2866 struct insn_ent
*ie
;
2867 struct attr_desc
*attr
;
2868 struct attr_value_list
*next
;
2870 struct attr_value_list
**insn_code_values
;
2871 struct attr_value_list
*ivbuf
;
2872 struct attr_value_list
*iv
;
2874 /* For each insn code, make a list of all the insn_ent's for it,
2875 for all values for all attributes. */
2877 if (num_insn_ents
== 0)
2880 /* Make 2 extra elements, for "code" values -2 and -1. */
2881 insn_code_values
= xcalloc ((insn_code_number
+ 2),
2882 sizeof (struct attr_value_list
*));
2884 /* Offset the table address so we can index by -2 or -1. */
2885 insn_code_values
+= 2;
2887 iv
= ivbuf
= xmalloc (num_insn_ents
* sizeof (struct attr_value_list
));
2889 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2890 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2891 for (av
= attr
->first_value
; av
; av
= av
->next
)
2892 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2897 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2898 insn_code_values
[ie
->def
->insn_code
] = iv
;
2902 /* Sanity check on num_insn_ents. */
2903 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2905 /* Process one insn code at a time. */
2906 for (i
= -2; i
< insn_code_number
; i
++)
2908 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2909 We use it to mean "already simplified for this insn". */
2910 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2911 clear_struct_flag (iv
->av
->value
);
2913 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2915 struct obstack
*old
= rtl_obstack
;
2920 if (GET_CODE (av
->value
) != COND
)
2923 rtl_obstack
= temp_obstack
;
2925 while (GET_CODE (newexp
) == COND
)
2927 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2928 ie
->def
->insn_index
);
2929 if (newexp2
== newexp
)
2935 if (newexp
!= av
->value
)
2937 newexp
= attr_copy_rtx (newexp
);
2938 remove_insn_ent (av
, ie
);
2939 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2941 insert_insn_ent (av
, ie
);
2947 free (insn_code_values
- 2);
2950 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2953 clear_struct_flag (rtx x
)
2960 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2961 if (ATTR_IND_SIMPLIFIED_P (x
))
2964 code
= GET_CODE (x
);
2984 /* Compare the elements. If any pair of corresponding elements
2985 fail to match, return 0 for the whole things. */
2987 fmt
= GET_RTX_FORMAT (code
);
2988 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2994 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2995 clear_struct_flag (XVECEXP (x
, i
, j
));
2999 clear_struct_flag (XEXP (x
, i
));
3005 /* Create table entries for DEFINE_ATTR. */
3008 gen_attr (rtx exp
, int lineno
)
3010 struct attr_desc
*attr
;
3011 struct attr_value
*av
;
3012 const char *name_ptr
;
3015 /* Make a new attribute structure. Check for duplicate by looking at
3016 attr->default_val, since it is initialized by this routine. */
3017 attr
= find_attr (&XSTR (exp
, 0), 1);
3018 if (attr
->default_val
)
3020 message_with_line (lineno
, "duplicate definition for attribute %s",
3022 message_with_line (attr
->lineno
, "previous definition");
3026 attr
->lineno
= lineno
;
3028 if (*XSTR (exp
, 1) == '\0')
3029 attr
->is_numeric
= 1;
3032 name_ptr
= XSTR (exp
, 1);
3033 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3035 av
= oballoc (sizeof (struct attr_value
));
3036 av
->value
= attr_rtx (CONST_STRING
, p
);
3037 av
->next
= attr
->first_value
;
3038 attr
->first_value
= av
;
3039 av
->first_insn
= NULL
;
3041 av
->has_asm_insn
= 0;
3045 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3048 if (attr
->is_numeric
)
3050 message_with_line (lineno
,
3051 "constant attributes may not take numeric values");
3055 /* Get rid of the CONST node. It is allowed only at top-level. */
3056 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3059 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3061 message_with_line (lineno
,
3062 "`length' attribute must take numeric values");
3066 /* Set up the default value. */
3067 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3068 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3071 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3072 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3073 number of alternatives as this should be checked elsewhere. */
3076 count_alternatives (rtx exp
)
3081 if (GET_CODE (exp
) == MATCH_OPERAND
)
3082 return n_comma_elts (XSTR (exp
, 2));
3084 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3085 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3090 n
= count_alternatives (XEXP (exp
, i
));
3097 if (XVEC (exp
, i
) != NULL
)
3098 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3100 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3109 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3110 `alternative' attribute. */
3113 compares_alternatives_p (rtx exp
)
3118 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3121 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3122 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3127 if (compares_alternatives_p (XEXP (exp
, i
)))
3132 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3133 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3141 /* Returns nonzero is INNER is contained in EXP. */
3144 contained_in_p (rtx inner
, rtx exp
)
3149 if (rtx_equal_p (inner
, exp
))
3152 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3153 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3158 if (contained_in_p (inner
, XEXP (exp
, i
)))
3163 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3164 if (contained_in_p (inner
, XVECEXP (exp
, i
, j
)))
3172 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3175 gen_insn (rtx exp
, int lineno
)
3177 struct insn_def
*id
;
3179 id
= oballoc (sizeof (struct insn_def
));
3183 id
->lineno
= lineno
;
3185 switch (GET_CODE (exp
))
3188 id
->insn_code
= insn_code_number
;
3189 id
->insn_index
= insn_index_number
;
3190 id
->num_alternatives
= count_alternatives (exp
);
3191 if (id
->num_alternatives
== 0)
3192 id
->num_alternatives
= 1;
3196 case DEFINE_PEEPHOLE
:
3197 id
->insn_code
= insn_code_number
;
3198 id
->insn_index
= insn_index_number
;
3199 id
->num_alternatives
= count_alternatives (exp
);
3200 if (id
->num_alternatives
== 0)
3201 id
->num_alternatives
= 1;
3205 case DEFINE_ASM_ATTRIBUTES
:
3207 id
->insn_index
= -1;
3208 id
->num_alternatives
= 1;
3210 got_define_asm_attributes
= 1;
3218 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3219 true or annul false is specified, and make a `struct delay_desc'. */
3222 gen_delay (rtx def
, int lineno
)
3224 struct delay_desc
*delay
;
3227 if (XVECLEN (def
, 1) % 3 != 0)
3229 message_with_line (lineno
,
3230 "number of elements in DEFINE_DELAY must be multiple of three");
3235 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3237 if (XVECEXP (def
, 1, i
+ 1))
3238 have_annul_true
= 1;
3239 if (XVECEXP (def
, 1, i
+ 2))
3240 have_annul_false
= 1;
3243 delay
= oballoc (sizeof (struct delay_desc
));
3245 delay
->num
= ++num_delays
;
3246 delay
->next
= delays
;
3247 delay
->lineno
= lineno
;
3251 /* Given a piece of RTX, print a C expression to test its truth value.
3252 We use AND and IOR both for logical and bit-wise operations, so
3253 interpret them as logical unless they are inside a comparison expression.
3254 The first bit of FLAGS will be nonzero in that case.
3256 Set the second bit of FLAGS to make references to attribute values use
3257 a cached local variable instead of calling a function. */
3260 write_test_expr (rtx exp
, int flags
)
3262 int comparison_operator
= 0;
3264 struct attr_desc
*attr
;
3266 /* In order not to worry about operator precedence, surround our part of
3267 the expression with parentheses. */
3270 code
= GET_CODE (exp
);
3273 /* Binary operators. */
3276 printf ("(unsigned) ");
3282 comparison_operator
= 1;
3284 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3285 case AND
: case IOR
: case XOR
:
3286 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3287 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3303 printf (" >= (unsigned) ");
3306 printf (" > (unsigned) ");
3315 printf (" <= (unsigned) ");
3318 printf (" < (unsigned) ");
3361 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3365 /* Special-case (not (eq_attrq "alternative" "x")) */
3366 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3367 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3369 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3373 /* Otherwise, fall through to normal unary operator. */
3375 /* Unary operators. */
3395 write_test_expr (XEXP (exp
, 0), flags
);
3400 int set
= XINT (exp
, 0), bit
= 0;
3403 fatal ("EQ_ATTR_ALT not valid inside comparison");
3406 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3408 if (!(set
& (set
- 1)))
3410 if (!(set
& 0xffff))
3433 printf ("which_alternative %s= %d",
3434 XINT (exp
, 1) ? "!" : "=", bit
);
3438 printf ("%s((1 << which_alternative) & 0x%x)",
3439 XINT (exp
, 1) ? "!" : "", set
);
3444 /* Comparison test of an attribute with a value. Most of these will
3445 have been removed by optimization. Handle "alternative"
3446 specially and give error if EQ_ATTR present inside a comparison. */
3449 fatal ("EQ_ATTR not valid inside comparison");
3451 if (XSTR (exp
, 0) == alternative_name
)
3453 printf ("which_alternative == %s", XSTR (exp
, 1));
3457 attr
= find_attr (&XSTR (exp
, 0), 0);
3460 /* Now is the time to expand the value of a constant attribute. */
3463 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3470 printf ("attr_%s", attr
->name
);
3472 printf ("get_attr_%s (insn)", attr
->name
);
3474 write_attr_valueq (attr
, XSTR (exp
, 1));
3478 /* Comparison test of flags for define_delays. */
3481 fatal ("ATTR_FLAG not valid inside comparison");
3482 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3485 /* See if an operand matches a predicate. */
3487 /* If only a mode is given, just ensure the mode matches the operand.
3488 If neither a mode nor predicate is given, error. */
3489 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3491 if (GET_MODE (exp
) == VOIDmode
)
3492 fatal ("null MATCH_OPERAND specified as test");
3494 printf ("GET_MODE (operands[%d]) == %smode",
3495 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3498 printf ("%s (operands[%d], %smode)",
3499 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3502 /* Constant integer. */
3504 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3507 /* A random C expression. */
3509 printf ("%s", XSTR (exp
, 0));
3512 /* The address of the branch target. */
3514 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3515 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3519 /* The address of the current insn. We implement this actually as the
3520 address of the current insn for backward branches, but the last
3521 address of the next insn for forward branches, and both with
3522 adjustments that account for the worst-case possible stretching of
3523 intervening alignments between this insn and its destination. */
3524 printf ("insn_current_reference_address (insn)");
3528 printf ("%s", XSTR (exp
, 0));
3532 write_test_expr (XEXP (exp
, 0), flags
& 2);
3534 write_test_expr (XEXP (exp
, 1), flags
| 1);
3536 write_test_expr (XEXP (exp
, 2), flags
| 1);
3540 fatal ("bad RTX code `%s' in attribute calculation\n",
3541 GET_RTX_NAME (code
));
3547 /* Given an attribute value, return the maximum CONST_STRING argument
3548 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3551 max_attr_value (rtx exp
, int *unknownp
)
3556 switch (GET_CODE (exp
))
3559 current_max
= atoi (XSTR (exp
, 0));
3563 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3564 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3566 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3567 if (n
> current_max
)
3573 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3574 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3575 if (n
> current_max
)
3581 current_max
= INT_MAX
;
3588 /* Given an attribute value, return the result of ORing together all
3589 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3590 if the numeric value is not known. */
3593 or_attr_value (rtx exp
, int *unknownp
)
3598 switch (GET_CODE (exp
))
3601 current_or
= atoi (XSTR (exp
, 0));
3605 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3606 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3607 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3611 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3612 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3624 /* Scan an attribute value, possibly a conditional, and record what actions
3625 will be required to do any conditional tests in it.
3628 `must_extract' if we need to extract the insn operands
3629 `must_constrain' if we must compute `which_alternative'
3630 `address_used' if an address expression was used
3631 `length_used' if an (eq_attr "length" ...) was used
3635 walk_attr_value (rtx exp
)
3644 code
= GET_CODE (exp
);
3648 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3649 /* Since this is an arbitrary expression, it can look at anything.
3650 However, constant expressions do not depend on any particular
3652 must_extract
= must_constrain
= 1;
3660 must_extract
= must_constrain
= 1;
3664 if (XSTR (exp
, 0) == alternative_name
)
3665 must_extract
= must_constrain
= 1;
3666 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3686 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3691 walk_attr_value (XEXP (exp
, i
));
3695 if (XVEC (exp
, i
) != NULL
)
3696 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3697 walk_attr_value (XVECEXP (exp
, i
, j
));
3702 /* Write out a function to obtain the attribute for a given INSN. */
3705 write_attr_get (struct attr_desc
*attr
)
3707 struct attr_value
*av
, *common_av
;
3709 /* Find the most used attribute value. Handle that as the `default' of the
3710 switch we will generate. */
3711 common_av
= find_most_used (attr
);
3713 /* Write out start of function, then all values with explicit `case' lines,
3714 then a `default', then the value with the most uses. */
3717 if (!attr
->is_numeric
)
3718 printf ("enum attr_%s\n", attr
->name
);
3719 else if (attr
->unsigned_p
)
3720 printf ("unsigned int\n");
3724 /* If the attribute name starts with a star, the remainder is the name of
3725 the subroutine to use, instead of `get_attr_...'. */
3726 if (attr
->name
[0] == '*')
3727 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3728 else if (attr
->is_const
== 0)
3729 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3732 printf ("get_attr_%s (void)\n", attr
->name
);
3735 for (av
= attr
->first_value
; av
; av
= av
->next
)
3736 if (av
->num_insns
!= 0)
3737 write_attr_set (attr
, 2, av
->value
, "return", ";",
3738 true_rtx
, av
->first_insn
->def
->insn_code
,
3739 av
->first_insn
->def
->insn_index
);
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 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3942 known_true
, av
->first_insn
->def
->insn_code
,
3943 av
->first_insn
->def
->insn_index
);
3945 if (strncmp (prefix
, "return", 6))
3947 write_indent (indent
+ 2);
3948 printf ("break;\n");
3953 /* Search for uses of non-const attributes and write code to cache them. */
3956 write_expr_attr_cache (rtx p
, struct attr_desc
*attr
)
3961 if (GET_CODE (p
) == EQ_ATTR
)
3963 if (XSTR (p
, 0) != attr
->name
)
3966 if (!attr
->is_numeric
)
3967 printf (" enum attr_%s ", attr
->name
);
3968 else if (attr
->unsigned_p
)
3969 printf (" unsigned int ");
3973 printf ("attr_%s = get_attr_%s (insn);\n", attr
->name
, attr
->name
);
3977 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
3978 ie
= GET_RTX_LENGTH (GET_CODE (p
));
3979 for (i
= 0; i
< ie
; i
++)
3984 if (write_expr_attr_cache (XEXP (p
, i
), attr
))
3989 je
= XVECLEN (p
, i
);
3990 for (j
= 0; j
< je
; ++j
)
3991 if (write_expr_attr_cache (XVECEXP (p
, i
, j
), attr
))
4000 /* Utilities to write in various forms. */
4003 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
4005 if (attr
->is_numeric
)
4011 if (num
> 9 || num
< 0)
4012 printf (" /* 0x%x */", num
);
4016 write_upcase (attr
->name
);
4023 write_attr_value (struct attr_desc
*attr
, rtx value
)
4027 switch (GET_CODE (value
))
4030 write_attr_valueq (attr
, XSTR (value
, 0));
4034 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4038 fputs (XSTR (value
, 0), stdout
);
4043 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4044 printf ("get_attr_%s (%s)", attr2
->name
,
4045 (attr2
->is_const
? "" : "insn"));
4066 write_attr_value (attr
, XEXP (value
, 0));
4070 write_attr_value (attr
, XEXP (value
, 1));
4079 write_upcase (const char *str
)
4083 /* The argument of TOUPPER should not have side effects. */
4084 putchar (TOUPPER(*str
));
4090 write_indent (int indent
)
4092 for (; indent
> 8; indent
-= 8)
4095 for (; indent
; indent
--)
4099 /* Write a subroutine that is given an insn that requires a delay slot, a
4100 delay slot ordinal, and a candidate insn. It returns nonzero if the
4101 candidate can be placed in the specified delay slot of the insn.
4103 We can write as many as three subroutines. `eligible_for_delay'
4104 handles normal delay slots, `eligible_for_annul_true' indicates that
4105 the specified insn can be annulled if the branch is true, and likewise
4106 for `eligible_for_annul_false'.
4108 KIND is a string distinguishing these three cases ("delay", "annul_true",
4109 or "annul_false"). */
4112 write_eligible_delay (const char *kind
)
4114 struct delay_desc
*delay
;
4118 struct attr_desc
*attr
;
4119 struct attr_value
*av
, *common_av
;
4122 /* Compute the maximum number of delay slots required. We use the delay
4123 ordinal times this number plus one, plus the slot number as an index into
4124 the appropriate predicate to test. */
4126 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4127 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4128 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4130 /* Write function prelude. */
4133 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4136 printf (" rtx insn;\n");
4138 printf (" gcc_assert (slot < %d);\n", max_slots
);
4140 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4141 converts a compound instruction into a loop. */
4142 printf (" if (!INSN_P (candidate_insn))\n");
4143 printf (" return 0;\n");
4146 /* If more than one delay type, find out which type the delay insn is. */
4150 attr
= find_attr (&delay_type_str
, 0);
4152 common_av
= find_most_used (attr
);
4154 printf (" insn = delay_insn;\n");
4155 printf (" switch (recog_memoized (insn))\n");
4158 sprintf (str
, " * %d;\n break;", max_slots
);
4159 for (av
= attr
->first_value
; av
; av
= av
->next
)
4160 if (av
!= common_av
)
4161 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4163 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4166 /* Ensure matched. Otherwise, shouldn't have been called. */
4167 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4170 /* If just one type of delay slot, write simple switch. */
4171 if (num_delays
== 1 && max_slots
== 1)
4173 printf (" insn = candidate_insn;\n");
4174 printf (" switch (recog_memoized (insn))\n");
4177 attr
= find_attr (&delay_1_0_str
, 0);
4179 common_av
= find_most_used (attr
);
4181 for (av
= attr
->first_value
; av
; av
= av
->next
)
4182 if (av
!= common_av
)
4183 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4185 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4191 /* Write a nested CASE. The first indicates which condition we need to
4192 test, and the inner CASE tests the condition. */
4193 printf (" insn = candidate_insn;\n");
4194 printf (" switch (slot)\n");
4197 for (delay
= delays
; delay
; delay
= delay
->next
)
4198 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4200 printf (" case %d:\n",
4201 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4202 printf (" switch (recog_memoized (insn))\n");
4205 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4207 attr
= find_attr (&pstr
, 0);
4209 common_av
= find_most_used (attr
);
4211 for (av
= attr
->first_value
; av
; av
= av
->next
)
4212 if (av
!= common_av
)
4213 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4215 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4219 printf (" default:\n");
4220 printf (" gcc_unreachable ();\n");
4227 /* This page contains miscellaneous utility routines. */
4229 /* Given a pointer to a (char *), return a malloc'ed string containing the
4230 next comma-separated element. Advance the pointer to after the string
4231 scanned, or the end-of-string. Return NULL if at end of string. */
4234 next_comma_elt (const char **pstr
)
4238 start
= scan_comma_elt (pstr
);
4243 return attr_string (start
, *pstr
- start
);
4246 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4247 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4248 replaced by a pointer to a canonical copy of the string. */
4250 static struct attr_desc
*
4251 find_attr (const char **name_p
, int create
)
4253 struct attr_desc
*attr
;
4255 const char *name
= *name_p
;
4257 /* Before we resort to using `strcmp', see if the string address matches
4258 anywhere. In most cases, it should have been canonicalized to do so. */
4259 if (name
== alternative_name
)
4262 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4263 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4264 if (name
== attr
->name
)
4267 /* Otherwise, do it the slow way. */
4268 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4269 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4271 *name_p
= attr
->name
;
4278 attr
= oballoc (sizeof (struct attr_desc
));
4279 attr
->name
= DEF_ATTR_STRING (name
);
4280 attr
->first_value
= attr
->default_val
= NULL
;
4281 attr
->is_numeric
= attr
->negative_ok
= attr
->is_const
= attr
->is_special
= 0;
4282 attr
->unsigned_p
= attr
->static_p
= 0;
4283 attr
->next
= attrs
[index
];
4284 attrs
[index
] = attr
;
4286 *name_p
= attr
->name
;
4291 /* Create internal attribute with the given default value. */
4294 make_internal_attr (const char *name
, rtx value
, int special
)
4296 struct attr_desc
*attr
;
4298 attr
= find_attr (&name
, 1);
4299 gcc_assert (!attr
->default_val
);
4301 attr
->is_numeric
= 1;
4303 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4304 attr
->negative_ok
= (special
& ATTR_NEGATIVE_OK
) != 0;
4305 attr
->unsigned_p
= (special
& ATTR_UNSIGNED
) != 0;
4306 attr
->static_p
= (special
& ATTR_STATIC
) != 0;
4307 attr
->default_val
= get_attr_value (value
, attr
, -2);
4310 /* Find the most used value of an attribute. */
4312 static struct attr_value
*
4313 find_most_used (struct attr_desc
*attr
)
4315 struct attr_value
*av
;
4316 struct attr_value
*most_used
;
4322 for (av
= attr
->first_value
; av
; av
= av
->next
)
4323 if (av
->num_insns
> nuses
)
4324 nuses
= av
->num_insns
, most_used
= av
;
4329 /* Return (attr_value "n") */
4332 make_numeric_value (int n
)
4334 static rtx int_values
[20];
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
)