1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 2002, 2003, 2004, 2005, 2006, 2007 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 3, 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 COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* This program handles insn attributes and the DEFINE_DELAY and
23 DEFINE_INSN_RESERVATION definitions.
25 It produces a series of functions named `get_attr_...', one for each insn
26 attribute. Each of these is given the rtx for an insn and returns a member
27 of the enum for the attribute.
29 These subroutines have the form of a `switch' on the INSN_CODE (via
30 `recog_memoized'). Each case either returns a constant attribute value
31 or a value that depends on tests on other attributes, the form of
32 operands, or some random C expression (encoded with a SYMBOL_REF
35 If the attribute `alternative', or a random C expression is present,
36 `constrain_operands' is called. If either of these cases of a reference to
37 an operand is found, `extract_insn' is called.
39 The special attribute `length' is also recognized. For this operand,
40 expressions involving the address of an operand or the current insn,
41 (address (pc)), are valid. In this case, an initial pass is made to
42 set all lengths that do not depend on address. Those that do are set to
43 the maximum length. Then each insn that depends on an address is checked
44 and possibly has its length changed. The process repeats until no further
45 changed are made. The resulting lengths are saved for use by
48 A special form of DEFINE_ATTR, where the expression for default value is a
49 CONST expression, indicates an attribute that is constant for a given run
50 of the compiler. The subroutine generated for these attributes has no
51 parameters as it does not depend on any particular insn. Constant
52 attributes are typically used to specify which variety of processor is
55 Internal attributes are defined to handle DEFINE_DELAY and
56 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
58 This program works by keeping a list of possible values for each attribute.
59 These include the basic attribute choices, default values for attribute, and
60 all derived quantities.
62 As the description file is read, the definition for each insn is saved in a
63 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
64 is created for each insn and chained to the corresponding attribute value,
65 either that specified, or the default.
67 An optimization phase is then run. This simplifies expressions for each
68 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
69 indicates when the attribute has the specified value for the insn. This
70 avoids recursive calls during compilation.
72 The strategy used when processing DEFINE_DELAY definitions is to create
73 arbitrarily complex expressions and have the optimization simplify them.
75 Once optimization is complete, any required routines and definitions
78 An optimization that is not yet implemented is to hoist the constant
79 expressions entirely out of the routines and definitions that are written.
80 A way to do this is to iterate over all possible combinations of values
81 for constant attributes and generate a set of functions for that given
82 combination. An initialization function would be written that evaluates
83 the attributes and installs the corresponding set of routines and
84 definitions (each would be accessed through a pointer).
86 We use the flags in an RTX as follows:
87 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
88 independent of the insn code.
89 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
90 for the insn code currently being processed (see optimize_attrs).
91 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
94 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
95 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
96 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
99 #define strcmp_check(S1, S2) ((S1) == (S2) \
101 : (gcc_assert (strcmp ((S1), (S2))), 1))
103 #define strcmp_check(S1, S2) ((S1) != (S2))
108 #include "coretypes.h"
111 #include "gensupport.h"
115 /* Flags for make_internal_attr's `special' parameter. */
117 #define ATTR_SPECIAL (1 << 0)
119 static struct obstack obstack1
, obstack2
;
120 static struct obstack
*hash_obstack
= &obstack1
;
121 static struct obstack
*temp_obstack
= &obstack2
;
123 /* enough space to reserve for printing out ints */
124 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
126 /* Define structures used to record attributes and values. */
128 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
129 encountered, we store all the relevant information into a
130 `struct insn_def'. This is done to allow attribute definitions to occur
131 anywhere in the file. */
135 struct insn_def
*next
; /* Next insn in chain. */
136 rtx def
; /* The DEFINE_... */
137 int insn_code
; /* Instruction number. */
138 int insn_index
; /* Expression numer in file, for errors. */
139 int lineno
; /* Line number. */
140 int num_alternatives
; /* Number of alternatives. */
141 int vec_idx
; /* Index of attribute vector in `def'. */
144 /* Once everything has been read in, we store in each attribute value a list
145 of insn codes that have that value. Here is the structure used for the
150 struct insn_ent
*next
; /* Next in chain. */
151 struct insn_def
*def
; /* Instruction definition. */
154 /* Each value of an attribute (either constant or computed) is assigned a
155 structure which is used as the listhead of the insns that have that
160 rtx value
; /* Value of attribute. */
161 struct attr_value
*next
; /* Next attribute value in chain. */
162 struct insn_ent
*first_insn
; /* First insn with this value. */
163 int num_insns
; /* Number of insns with this value. */
164 int has_asm_insn
; /* True if this value used for `asm' insns */
167 /* Structure for each attribute. */
171 char *name
; /* Name of attribute. */
172 struct attr_desc
*next
; /* Next attribute. */
173 struct attr_value
*first_value
; /* First value of this attribute. */
174 struct attr_value
*default_val
; /* Default value for this attribute. */
175 int lineno
: 24; /* Line number. */
176 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
177 unsigned is_const
: 1; /* Attribute value constant for each run. */
178 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
181 /* Structure for each DEFINE_DELAY. */
185 rtx def
; /* DEFINE_DELAY expression. */
186 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
187 int num
; /* Number of DEFINE_DELAY, starting at 1. */
188 int lineno
; /* Line number. */
191 struct attr_value_list
193 struct attr_value
*av
;
195 struct attr_desc
*attr
;
196 struct attr_value_list
*next
;
199 /* Listheads of above structures. */
201 /* This one is indexed by the first character of the attribute name. */
202 #define MAX_ATTRS_INDEX 256
203 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
204 static struct insn_def
*defs
;
205 static struct delay_desc
*delays
;
206 struct attr_value_list
**insn_code_values
;
208 /* Other variables. */
210 static int insn_code_number
;
211 static int insn_index_number
;
212 static int got_define_asm_attributes
;
213 static int must_extract
;
214 static int must_constrain
;
215 static int address_used
;
216 static int length_used
;
217 static int num_delays
;
218 static int have_annul_true
, have_annul_false
;
219 static int num_insn_ents
;
221 /* Stores, for each insn code, the number of constraint alternatives. */
223 static int *insn_n_alternatives
;
225 /* Stores, for each insn code, a bitmap that has bits on for each possible
228 static int *insn_alternatives
;
230 /* Used to simplify expressions. */
232 static rtx true_rtx
, false_rtx
;
234 /* Used to reduce calls to `strcmp' */
236 static const char *alternative_name
;
237 static const char *length_str
;
238 static const char *delay_type_str
;
239 static const char *delay_1_0_str
;
240 static const char *num_delay_slots_str
;
242 /* Simplify an expression. Only call the routine if there is something to
244 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
245 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
246 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
248 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
250 /* Forward declarations of functions used before their definitions, only. */
251 static char *attr_string (const char *, int);
252 static char *attr_printf (unsigned int, const char *, ...)
254 static rtx
make_numeric_value (int);
255 static struct attr_desc
*find_attr (const char **, int);
256 static rtx
mk_attr_alt (int);
257 static char *next_comma_elt (const char **);
258 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
259 static rtx
copy_boolean (rtx
);
260 static int compares_alternatives_p (rtx
);
261 static void make_internal_attr (const char *, rtx
, int);
262 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
263 static void walk_attr_value (rtx
);
264 static int max_attr_value (rtx
, int*);
265 static int min_attr_value (rtx
, int*);
266 static int or_attr_value (rtx
, int*);
267 static rtx
simplify_test_exp (rtx
, int, int);
268 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
269 static rtx
copy_rtx_unchanging (rtx
);
270 static bool attr_alt_subset_p (rtx
, rtx
);
271 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
272 static void clear_struct_flag (rtx
);
273 static void write_attr_valueq (struct attr_desc
*, const char *);
274 static struct attr_value
*find_most_used (struct attr_desc
*);
275 static void write_attr_set (struct attr_desc
*, int, rtx
,
276 const char *, const char *, rtx
,
278 static void write_attr_case (struct attr_desc
*, struct attr_value
*,
279 int, const char *, const char *, int, rtx
);
280 static void write_attr_value (struct attr_desc
*, rtx
);
281 static void write_upcase (const char *);
282 static void write_indent (int);
283 static rtx
identity_fn (rtx
);
284 static rtx
zero_fn (rtx
);
285 static rtx
one_fn (rtx
);
286 static rtx
max_fn (rtx
);
287 static rtx
min_fn (rtx
);
289 #define oballoc(size) obstack_alloc (hash_obstack, size)
291 /* Hash table for sharing RTL and strings. */
293 /* Each hash table slot is a bucket containing a chain of these structures.
294 Strings are given negative hash codes; RTL expressions are given positive
299 struct attr_hash
*next
; /* Next structure in the bucket. */
300 int hashcode
; /* Hash code of this rtx or string. */
303 char *str
; /* The string (negative hash codes) */
304 rtx rtl
; /* or the RTL recorded here. */
308 /* Now here is the hash table. When recording an RTL, it is added to
309 the slot whose index is the hash code mod the table size. Note
310 that the hash table is used for several kinds of RTL (see attr_rtx)
311 and for strings. While all these live in the same table, they are
312 completely independent, and the hash code is computed differently
315 #define RTL_HASH_SIZE 4093
316 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
318 /* Here is how primitive or already-shared RTL's hash
320 #define RTL_HASH(RTL) ((long) (RTL) & 0777777)
322 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
325 attr_hash_add_rtx (int hashcode
, rtx rtl
)
329 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
330 h
->hashcode
= hashcode
;
332 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
333 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
336 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
339 attr_hash_add_string (int hashcode
, char *str
)
343 h
= obstack_alloc (hash_obstack
, sizeof (struct attr_hash
));
344 h
->hashcode
= -hashcode
;
346 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
347 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
350 /* Generate an RTL expression, but avoid duplicates.
351 Set the ATTR_PERMANENT_P flag for these permanent objects.
353 In some cases we cannot uniquify; then we return an ordinary
354 impermanent rtx with ATTR_PERMANENT_P clear.
358 rtx attr_rtx (code, [element1, ..., elementn]) */
361 attr_rtx_1 (enum rtx_code code
, va_list p
)
363 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
366 struct obstack
*old_obstack
= rtl_obstack
;
368 /* For each of several cases, search the hash table for an existing entry.
369 Use that entry if one is found; otherwise create a new RTL and add it
372 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
374 rtx arg0
= va_arg (p
, rtx
);
376 /* A permanent object cannot point to impermanent ones. */
377 if (! ATTR_PERMANENT_P (arg0
))
379 rt_val
= rtx_alloc (code
);
380 XEXP (rt_val
, 0) = arg0
;
384 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
385 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
386 if (h
->hashcode
== hashcode
387 && GET_CODE (h
->u
.rtl
) == code
388 && XEXP (h
->u
.rtl
, 0) == arg0
)
393 rtl_obstack
= hash_obstack
;
394 rt_val
= rtx_alloc (code
);
395 XEXP (rt_val
, 0) = arg0
;
398 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
399 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
400 || GET_RTX_CLASS (code
) == RTX_COMPARE
401 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
403 rtx arg0
= va_arg (p
, rtx
);
404 rtx arg1
= va_arg (p
, rtx
);
406 /* A permanent object cannot point to impermanent ones. */
407 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
409 rt_val
= rtx_alloc (code
);
410 XEXP (rt_val
, 0) = arg0
;
411 XEXP (rt_val
, 1) = arg1
;
415 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
416 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
417 if (h
->hashcode
== hashcode
418 && GET_CODE (h
->u
.rtl
) == code
419 && XEXP (h
->u
.rtl
, 0) == arg0
420 && XEXP (h
->u
.rtl
, 1) == arg1
)
425 rtl_obstack
= hash_obstack
;
426 rt_val
= rtx_alloc (code
);
427 XEXP (rt_val
, 0) = arg0
;
428 XEXP (rt_val
, 1) = arg1
;
431 else if (GET_RTX_LENGTH (code
) == 1
432 && GET_RTX_FORMAT (code
)[0] == 's')
434 char *arg0
= va_arg (p
, char *);
436 arg0
= DEF_ATTR_STRING (arg0
);
438 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
439 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
440 if (h
->hashcode
== hashcode
441 && GET_CODE (h
->u
.rtl
) == code
442 && XSTR (h
->u
.rtl
, 0) == arg0
)
447 rtl_obstack
= hash_obstack
;
448 rt_val
= rtx_alloc (code
);
449 XSTR (rt_val
, 0) = arg0
;
452 else if (GET_RTX_LENGTH (code
) == 2
453 && GET_RTX_FORMAT (code
)[0] == 's'
454 && GET_RTX_FORMAT (code
)[1] == 's')
456 char *arg0
= va_arg (p
, char *);
457 char *arg1
= va_arg (p
, char *);
459 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
460 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
461 if (h
->hashcode
== hashcode
462 && GET_CODE (h
->u
.rtl
) == code
463 && XSTR (h
->u
.rtl
, 0) == arg0
464 && XSTR (h
->u
.rtl
, 1) == arg1
)
469 rtl_obstack
= hash_obstack
;
470 rt_val
= rtx_alloc (code
);
471 XSTR (rt_val
, 0) = arg0
;
472 XSTR (rt_val
, 1) = arg1
;
475 else if (code
== CONST_INT
)
477 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
487 int i
; /* Array indices... */
488 const char *fmt
; /* Current rtx's format... */
490 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
492 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
493 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
497 case '0': /* Unused field. */
500 case 'i': /* An integer? */
501 XINT (rt_val
, i
) = va_arg (p
, int);
504 case 'w': /* A wide integer? */
505 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
508 case 's': /* A string? */
509 XSTR (rt_val
, i
) = va_arg (p
, char *);
512 case 'e': /* An expression? */
513 case 'u': /* An insn? Same except when printing. */
514 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
517 case 'E': /* An RTX vector? */
518 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
528 rtl_obstack
= old_obstack
;
529 attr_hash_add_rtx (hashcode
, rt_val
);
530 ATTR_PERMANENT_P (rt_val
) = 1;
535 attr_rtx (enum rtx_code code
, ...)
541 result
= attr_rtx_1 (code
, p
);
546 /* Create a new string printed with the printf line arguments into a space
547 of at most LEN bytes:
549 rtx attr_printf (len, format, [arg1, ..., argn]) */
552 attr_printf (unsigned int len
, const char *fmt
, ...)
559 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
561 vsprintf (str
, fmt
, p
);
564 return DEF_ATTR_STRING (str
);
568 attr_eq (const char *name
, const char *value
)
570 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
576 return XSTR (make_numeric_value (n
), 0);
579 /* Return a permanent (possibly shared) copy of a string STR (not assumed
580 to be null terminated) with LEN bytes. */
583 attr_string (const char *str
, int len
)
590 /* Compute the hash code. */
591 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
592 for (i
= 1; i
< len
; i
+= 2)
593 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
595 hashcode
= -hashcode
;
597 /* Search the table for the string. */
598 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
599 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
600 && !strncmp (h
->u
.str
, str
, len
))
601 return h
->u
.str
; /* <-- return if found. */
603 /* Not found; create a permanent copy and add it to the hash table. */
604 new_str
= obstack_alloc (hash_obstack
, len
+ 1);
605 memcpy (new_str
, str
, len
);
607 attr_hash_add_string (hashcode
, new_str
);
609 return new_str
; /* Return the new string. */
612 /* Check two rtx's for equality of contents,
613 taking advantage of the fact that if both are hashed
614 then they can't be equal unless they are the same object. */
617 attr_equal_p (rtx x
, rtx y
)
619 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
620 && rtx_equal_p (x
, y
)));
623 /* Copy an attribute value expression,
624 descending to all depths, but not copying any
625 permanent hashed subexpressions. */
628 attr_copy_rtx (rtx orig
)
633 const char *format_ptr
;
635 /* No need to copy a permanent object. */
636 if (ATTR_PERMANENT_P (orig
))
639 code
= GET_CODE (orig
);
657 copy
= rtx_alloc (code
);
658 PUT_MODE (copy
, GET_MODE (orig
));
659 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
660 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
661 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
663 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
665 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
667 switch (*format_ptr
++)
670 XEXP (copy
, i
) = XEXP (orig
, i
);
671 if (XEXP (orig
, i
) != NULL
)
672 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
677 XVEC (copy
, i
) = XVEC (orig
, i
);
678 if (XVEC (orig
, i
) != NULL
)
680 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
681 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
682 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
688 XINT (copy
, i
) = XINT (orig
, i
);
692 XWINT (copy
, i
) = XWINT (orig
, i
);
697 XSTR (copy
, i
) = XSTR (orig
, i
);
707 /* Given a test expression for an attribute, ensure it is validly formed.
708 IS_CONST indicates whether the expression is constant for each compiler
709 run (a constant expression may not test any particular insn).
711 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
712 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
713 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
715 Update the string address in EQ_ATTR expression to be the same used
716 in the attribute (or `alternative_name') to speed up subsequent
717 `find_attr' calls and eliminate most `strcmp' calls.
719 Return the new expression, if any. */
722 check_attr_test (rtx exp
, int is_const
, int lineno
)
724 struct attr_desc
*attr
;
725 struct attr_value
*av
;
726 const char *name_ptr
, *p
;
729 switch (GET_CODE (exp
))
732 /* Handle negation test. */
733 if (XSTR (exp
, 1)[0] == '!')
734 return check_attr_test (attr_rtx (NOT
,
735 attr_eq (XSTR (exp
, 0),
739 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
741 attr
= find_attr (&XSTR (exp
, 0), 0);
744 if (! strcmp (XSTR (exp
, 0), "alternative"))
745 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
747 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
750 if (is_const
&& ! attr
->is_const
)
751 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
754 /* Copy this just to make it permanent,
755 so expressions using it can be permanent too. */
756 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
758 /* It shouldn't be possible to simplify the value given to a
759 constant attribute, so don't expand this until it's time to
760 write the test expression. */
762 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
764 if (attr
->is_numeric
)
766 for (p
= XSTR (exp
, 1); *p
; p
++)
768 fatal ("attribute `%s' takes only numeric values",
773 for (av
= attr
->first_value
; av
; av
= av
->next
)
774 if (GET_CODE (av
->value
) == CONST_STRING
775 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
779 fatal ("unknown value `%s' for `%s' attribute",
780 XSTR (exp
, 1), XSTR (exp
, 0));
785 if (! strcmp (XSTR (exp
, 0), "alternative"))
789 name_ptr
= XSTR (exp
, 1);
790 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
791 set
|= 1 << atoi (p
);
793 return mk_attr_alt (set
);
797 /* Make an IOR tree of the possible values. */
799 name_ptr
= XSTR (exp
, 1);
800 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
802 newexp
= attr_eq (XSTR (exp
, 0), p
);
803 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
806 return check_attr_test (orexp
, is_const
, lineno
);
815 /* Either TRUE or FALSE. */
823 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
824 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
828 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
833 fatal ("RTL operator \"%s\" not valid in constant attribute test",
834 GET_RTX_NAME (GET_CODE (exp
)));
835 /* These cases can't be simplified. */
836 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
839 case LE
: case LT
: case GT
: case GE
:
840 case LEU
: case LTU
: case GTU
: case GEU
:
842 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
843 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
844 exp
= attr_rtx (GET_CODE (exp
),
845 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
846 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
847 /* These cases can't be simplified. */
848 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
854 /* These cases are valid for constant attributes, but can't be
856 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
857 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
861 fatal ("RTL operator \"%s\" not valid in attribute test",
862 GET_RTX_NAME (GET_CODE (exp
)));
868 /* Given an expression, ensure that it is validly formed and that all named
869 attribute values are valid for the given attribute. Issue a fatal error
870 if not. If no attribute is specified, assume a numeric attribute.
872 Return a perhaps modified replacement expression for the value. */
875 check_attr_value (rtx exp
, struct attr_desc
*attr
)
877 struct attr_value
*av
;
881 switch (GET_CODE (exp
))
884 if (attr
&& ! attr
->is_numeric
)
886 message_with_line (attr
->lineno
,
887 "CONST_INT not valid for non-numeric attribute %s",
893 if (INTVAL (exp
) < 0)
895 message_with_line (attr
->lineno
,
896 "negative numeric value specified for attribute %s",
904 if (! strcmp (XSTR (exp
, 0), "*"))
907 if (attr
== 0 || attr
->is_numeric
)
913 message_with_line (attr
? attr
->lineno
: 0,
914 "non-numeric value for numeric attribute %s",
915 attr
? attr
->name
: "internal");
922 for (av
= attr
->first_value
; av
; av
= av
->next
)
923 if (GET_CODE (av
->value
) == CONST_STRING
924 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
929 message_with_line (attr
->lineno
,
930 "unknown value `%s' for `%s' attribute",
931 XSTR (exp
, 0), attr
? attr
->name
: "internal");
937 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
938 attr
? attr
->is_const
: 0,
939 attr
? attr
->lineno
: 0);
940 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
941 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
949 if (attr
&& !attr
->is_numeric
)
951 message_with_line (attr
->lineno
,
952 "invalid operation `%s' for non-numeric attribute value",
953 GET_RTX_NAME (GET_CODE (exp
)));
961 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
962 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
971 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
975 if (XVECLEN (exp
, 0) % 2 != 0)
977 message_with_line (attr
->lineno
,
978 "first operand of COND must have even length");
983 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
985 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
986 attr
? attr
->is_const
: 0,
987 attr
? attr
->lineno
: 0);
988 XVECEXP (exp
, 0, i
+ 1)
989 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
992 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
997 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1000 message_with_line (attr
? attr
->lineno
: 0,
1001 "unknown attribute `%s' in ATTR",
1005 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1007 message_with_line (attr
->lineno
,
1008 "non-constant attribute `%s' referenced from `%s'",
1009 XSTR (exp
, 0), attr
->name
);
1013 && attr
->is_numeric
!= attr2
->is_numeric
)
1015 message_with_line (attr
->lineno
,
1016 "numeric attribute mismatch calling `%s' from `%s'",
1017 XSTR (exp
, 0), attr
->name
);
1024 /* A constant SYMBOL_REF is valid as a constant attribute test and
1025 is expanded later by make_canonical into a COND. In a non-constant
1026 attribute test, it is left be. */
1027 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1030 message_with_line (attr
? attr
->lineno
: 0,
1031 "invalid operation `%s' for attribute value",
1032 GET_RTX_NAME (GET_CODE (exp
)));
1040 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1041 It becomes a COND with each test being (eq_attr "alternative" "n") */
1044 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1046 int num_alt
= id
->num_alternatives
;
1050 if (XVECLEN (exp
, 1) != num_alt
)
1052 message_with_line (id
->lineno
,
1053 "bad number of entries in SET_ATTR_ALTERNATIVE");
1058 /* Make a COND with all tests but the last. Select the last value via the
1060 condexp
= rtx_alloc (COND
);
1061 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1063 for (i
= 0; i
< num_alt
- 1; i
++)
1066 p
= attr_numeral (i
);
1068 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1069 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1072 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1074 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1077 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1078 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1081 convert_set_attr (rtx exp
, struct insn_def
*id
)
1084 const char *name_ptr
;
1088 /* See how many alternative specified. */
1089 n
= n_comma_elts (XSTR (exp
, 1));
1091 return attr_rtx (SET
,
1092 attr_rtx (ATTR
, XSTR (exp
, 0)),
1093 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1095 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1096 XSTR (newexp
, 0) = XSTR (exp
, 0);
1097 XVEC (newexp
, 1) = rtvec_alloc (n
);
1099 /* Process each comma-separated name. */
1100 name_ptr
= XSTR (exp
, 1);
1102 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1103 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1105 return convert_set_attr_alternative (newexp
, id
);
1108 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1109 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1115 struct insn_def
*id
;
1116 struct attr_desc
*attr
;
1120 for (id
= defs
; id
; id
= id
->next
)
1122 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1125 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1127 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1128 switch (GET_CODE (value
))
1131 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1133 message_with_line (id
->lineno
, "bad attribute set");
1139 case SET_ATTR_ALTERNATIVE
:
1140 value
= convert_set_attr_alternative (value
, id
);
1144 value
= convert_set_attr (value
, id
);
1148 message_with_line (id
->lineno
, "invalid attribute code %s",
1149 GET_RTX_NAME (GET_CODE (value
)));
1153 if (value
== NULL_RTX
)
1156 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1158 message_with_line (id
->lineno
, "unknown attribute %s",
1159 XSTR (XEXP (value
, 0), 0));
1164 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1165 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1170 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1171 expressions by converting them into a COND. This removes cases from this
1172 program. Also, replace an attribute value of "*" with the default attribute
1176 make_canonical (struct attr_desc
*attr
, rtx exp
)
1181 switch (GET_CODE (exp
))
1184 exp
= make_numeric_value (INTVAL (exp
));
1188 if (! strcmp (XSTR (exp
, 0), "*"))
1190 if (attr
== 0 || attr
->default_val
== 0)
1191 fatal ("(attr_value \"*\") used in invalid context");
1192 exp
= attr
->default_val
->value
;
1195 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1200 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1202 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1203 This makes the COND something that won't be considered an arbitrary
1204 expression by walk_attr_value. */
1205 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1206 exp
= check_attr_value (exp
, attr
);
1210 newexp
= rtx_alloc (COND
);
1211 XVEC (newexp
, 0) = rtvec_alloc (2);
1212 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1213 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1215 XEXP (newexp
, 1) = XEXP (exp
, 2);
1218 /* Fall through to COND case since this is now a COND. */
1225 /* First, check for degenerate COND. */
1226 if (XVECLEN (exp
, 0) == 0)
1227 return make_canonical (attr
, XEXP (exp
, 1));
1228 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1230 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1232 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1233 XVECEXP (exp
, 0, i
+ 1)
1234 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1235 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1251 copy_boolean (rtx exp
)
1253 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1254 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1255 copy_boolean (XEXP (exp
, 1)));
1256 if (GET_CODE (exp
) == MATCH_OPERAND
)
1258 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1259 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1261 else if (GET_CODE (exp
) == EQ_ATTR
)
1263 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1264 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1270 /* Given a value and an attribute description, return a `struct attr_value *'
1271 that represents that value. This is either an existing structure, if the
1272 value has been previously encountered, or a newly-created structure.
1274 `insn_code' is the code of an insn whose attribute has the specified
1275 value (-2 if not processing an insn). We ensure that all insns for
1276 a given value have the same number of alternatives if the value checks
1279 static struct attr_value
*
1280 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1282 struct attr_value
*av
;
1285 value
= make_canonical (attr
, value
);
1286 if (compares_alternatives_p (value
))
1288 if (insn_code
< 0 || insn_alternatives
== NULL
)
1289 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1291 num_alt
= insn_alternatives
[insn_code
];
1294 for (av
= attr
->first_value
; av
; av
= av
->next
)
1295 if (rtx_equal_p (value
, av
->value
)
1296 && (num_alt
== 0 || av
->first_insn
== NULL
1297 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1300 av
= oballoc (sizeof (struct attr_value
));
1302 av
->next
= attr
->first_value
;
1303 attr
->first_value
= av
;
1304 av
->first_insn
= NULL
;
1306 av
->has_asm_insn
= 0;
1311 /* After all DEFINE_DELAYs have been read in, create internal attributes
1312 to generate the required routines.
1314 First, we compute the number of delay slots for each insn (as a COND of
1315 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1316 delay type is specified, we compute a similar function giving the
1317 DEFINE_DELAY ordinal for each insn.
1319 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1320 tells whether a given insn can be in that delay slot.
1322 Normal attribute filling and optimization expands these to contain the
1323 information needed to handle delay slots. */
1326 expand_delays (void)
1328 struct delay_desc
*delay
;
1334 /* First, generate data for `num_delay_slots' function. */
1336 condexp
= rtx_alloc (COND
);
1337 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1338 XEXP (condexp
, 1) = make_numeric_value (0);
1340 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1342 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1343 XVECEXP (condexp
, 0, i
+ 1)
1344 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1347 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1349 /* If more than one delay type, do the same for computing the delay type. */
1352 condexp
= rtx_alloc (COND
);
1353 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1354 XEXP (condexp
, 1) = make_numeric_value (0);
1356 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1358 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1359 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1362 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1365 /* For each delay possibility and delay slot, compute an eligibility
1366 attribute for non-annulled insns and for each type of annulled (annul
1367 if true and annul if false). */
1368 for (delay
= delays
; delay
; delay
= delay
->next
)
1370 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1372 condexp
= XVECEXP (delay
->def
, 1, i
);
1374 condexp
= false_rtx
;
1375 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1376 make_numeric_value (1), make_numeric_value (0));
1378 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1379 "*delay_%d_%d", delay
->num
, i
/ 3);
1380 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1382 if (have_annul_true
)
1384 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1385 if (condexp
== 0) condexp
= false_rtx
;
1386 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1387 make_numeric_value (1),
1388 make_numeric_value (0));
1389 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1390 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1391 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1394 if (have_annul_false
)
1396 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1397 if (condexp
== 0) condexp
= false_rtx
;
1398 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1399 make_numeric_value (1),
1400 make_numeric_value (0));
1401 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1402 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1403 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1409 /* Once all attributes and insns have been read and checked, we construct for
1410 each attribute value a list of all the insns that have that value for
1414 fill_attr (struct attr_desc
*attr
)
1416 struct attr_value
*av
;
1417 struct insn_ent
*ie
;
1418 struct insn_def
*id
;
1422 /* Don't fill constant attributes. The value is independent of
1423 any particular insn. */
1427 for (id
= defs
; id
; id
= id
->next
)
1429 /* If no value is specified for this insn for this attribute, use the
1432 if (XVEC (id
->def
, id
->vec_idx
))
1433 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1434 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1436 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1439 av
= attr
->default_val
;
1441 av
= get_attr_value (value
, attr
, id
->insn_code
);
1443 ie
= oballoc (sizeof (struct insn_ent
));
1445 insert_insn_ent (av
, ie
);
1449 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1450 test that checks relative positions of insns (uses MATCH_DUP or PC).
1451 If so, replace it with what is obtained by passing the expression to
1452 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1453 recursively on each value (including the default value). Otherwise,
1454 return the value returned by NO_ADDRESS_FN applied to EXP. */
1457 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1458 rtx (*address_fn
) (rtx
))
1463 if (GET_CODE (exp
) == COND
)
1465 /* See if any tests use addresses. */
1467 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1468 walk_attr_value (XVECEXP (exp
, 0, i
));
1471 return (*address_fn
) (exp
);
1473 /* Make a new copy of this COND, replacing each element. */
1474 newexp
= rtx_alloc (COND
);
1475 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1476 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1478 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1479 XVECEXP (newexp
, 0, i
+ 1)
1480 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1481 no_address_fn
, address_fn
);
1484 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1485 no_address_fn
, address_fn
);
1490 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1493 walk_attr_value (XEXP (exp
, 0));
1495 return (*address_fn
) (exp
);
1497 return attr_rtx (IF_THEN_ELSE
,
1498 substitute_address (XEXP (exp
, 0),
1499 no_address_fn
, address_fn
),
1500 substitute_address (XEXP (exp
, 1),
1501 no_address_fn
, address_fn
),
1502 substitute_address (XEXP (exp
, 2),
1503 no_address_fn
, address_fn
));
1506 return (*no_address_fn
) (exp
);
1509 /* Make new attributes from the `length' attribute. The following are made,
1510 each corresponding to a function called from `shorten_branches' or
1513 *insn_default_length This is the length of the insn to be returned
1514 by `get_attr_length' before `shorten_branches'
1515 has been called. In each case where the length
1516 depends on relative addresses, the largest
1517 possible is used. This routine is also used
1518 to compute the initial size of the insn.
1520 *insn_variable_length_p This returns 1 if the insn's length depends
1521 on relative addresses, zero otherwise.
1523 *insn_current_length This is only called when it is known that the
1524 insn has a variable length and returns the
1525 current length, based on relative addresses.
1529 make_length_attrs (void)
1531 static const char *new_names
[] =
1533 "*insn_default_length",
1535 "*insn_variable_length_p",
1536 "*insn_current_length"
1538 static rtx (*const no_address_fn
[]) (rtx
)
1539 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1540 static rtx (*const address_fn
[]) (rtx
)
1541 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1543 struct attr_desc
*length_attr
, *new_attr
;
1544 struct attr_value
*av
, *new_av
;
1545 struct insn_ent
*ie
, *new_ie
;
1547 /* See if length attribute is defined. If so, it must be numeric. Make
1548 it special so we don't output anything for it. */
1549 length_attr
= find_attr (&length_str
, 0);
1550 if (length_attr
== 0)
1553 if (! length_attr
->is_numeric
)
1554 fatal ("length attribute must be numeric");
1556 length_attr
->is_const
= 0;
1557 length_attr
->is_special
= 1;
1559 /* Make each new attribute, in turn. */
1560 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1562 make_internal_attr (new_names
[i
],
1563 substitute_address (length_attr
->default_val
->value
,
1564 no_address_fn
[i
], address_fn
[i
]),
1566 new_attr
= find_attr (&new_names
[i
], 0);
1567 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1568 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1570 new_av
= get_attr_value (substitute_address (av
->value
,
1573 new_attr
, ie
->def
->insn_code
);
1574 new_ie
= oballoc (sizeof (struct insn_ent
));
1575 new_ie
->def
= ie
->def
;
1576 insert_insn_ent (new_av
, new_ie
);
1581 /* Utility functions called from above routine. */
1584 identity_fn (rtx exp
)
1590 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1592 return make_numeric_value (0);
1596 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1598 return make_numeric_value (1);
1605 return make_numeric_value (max_attr_value (exp
, &unknown
));
1612 return make_numeric_value (min_attr_value (exp
, &unknown
));
1616 write_length_unit_log (void)
1618 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1619 struct attr_value
*av
;
1620 struct insn_ent
*ie
;
1621 unsigned int length_unit_log
, length_or
;
1624 if (length_attr
== 0)
1626 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1627 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1628 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1629 length_or
|= or_attr_value (av
->value
, &unknown
);
1632 length_unit_log
= 0;
1635 length_or
= ~length_or
;
1636 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1639 printf ("const int length_unit_log = %u;\n", length_unit_log
);
1642 /* Take a COND expression and see if any of the conditions in it can be
1643 simplified. If any are known true or known false for the particular insn
1644 code, the COND can be further simplified.
1646 Also call ourselves on any COND operations that are values of this COND.
1648 We do not modify EXP; rather, we make and return a new rtx. */
1651 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1654 /* We store the desired contents here,
1655 then build a new expression if they don't match EXP. */
1656 rtx defval
= XEXP (exp
, 1);
1657 rtx new_defval
= XEXP (exp
, 1);
1658 int len
= XVECLEN (exp
, 0);
1659 rtx
*tests
= XNEWVEC (rtx
, len
);
1663 /* This lets us free all storage allocated below, if appropriate. */
1664 obstack_finish (rtl_obstack
);
1666 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1668 /* See if default value needs simplification. */
1669 if (GET_CODE (defval
) == COND
)
1670 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1672 /* Simplify the subexpressions, and see what tests we can get rid of. */
1674 for (i
= 0; i
< len
; i
+= 2)
1676 rtx newtest
, newval
;
1678 /* Simplify this test. */
1679 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1682 newval
= tests
[i
+ 1];
1683 /* See if this value may need simplification. */
1684 if (GET_CODE (newval
) == COND
)
1685 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1687 /* Look for ways to delete or combine this test. */
1688 if (newtest
== true_rtx
)
1690 /* If test is true, make this value the default
1691 and discard this + any following tests. */
1693 defval
= tests
[i
+ 1];
1694 new_defval
= newval
;
1697 else if (newtest
== false_rtx
)
1699 /* If test is false, discard it and its value. */
1700 for (j
= i
; j
< len
- 2; j
++)
1701 tests
[j
] = tests
[j
+ 2];
1706 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1708 /* If this value and the value for the prev test are the same,
1712 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1713 insn_code
, insn_index
);
1715 /* Delete this test/value. */
1716 for (j
= i
; j
< len
- 2; j
++)
1717 tests
[j
] = tests
[j
+ 2];
1723 tests
[i
+ 1] = newval
;
1726 /* If the last test in a COND has the same value
1727 as the default value, that test isn't needed. */
1729 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1732 /* See if we changed anything. */
1733 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1736 for (i
= 0; i
< len
; i
++)
1737 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1745 if (GET_CODE (defval
) == COND
)
1746 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1754 rtx newexp
= rtx_alloc (COND
);
1756 XVEC (newexp
, 0) = rtvec_alloc (len
);
1757 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1758 XEXP (newexp
, 1) = new_defval
;
1765 /* Remove an insn entry from an attribute value. */
1768 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1770 struct insn_ent
*previe
;
1772 if (av
->first_insn
== ie
)
1773 av
->first_insn
= ie
->next
;
1776 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1778 previe
->next
= ie
->next
;
1782 if (ie
->def
->insn_code
== -1)
1783 av
->has_asm_insn
= 0;
1788 /* Insert an insn entry in an attribute value list. */
1791 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1793 ie
->next
= av
->first_insn
;
1794 av
->first_insn
= ie
;
1796 if (ie
->def
->insn_code
== -1)
1797 av
->has_asm_insn
= 1;
1802 /* This is a utility routine to take an expression that is a tree of either
1803 AND or IOR expressions and insert a new term. The new term will be
1804 inserted at the right side of the first node whose code does not match
1805 the root. A new node will be created with the root's code. Its left
1806 side will be the old right side and its right side will be the new
1809 If the `term' is itself a tree, all its leaves will be inserted. */
1812 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1816 /* Avoid consing in some special cases. */
1817 if (code
== AND
&& term
== true_rtx
)
1819 if (code
== AND
&& term
== false_rtx
)
1821 if (code
== AND
&& exp
== true_rtx
)
1823 if (code
== AND
&& exp
== false_rtx
)
1825 if (code
== IOR
&& term
== true_rtx
)
1827 if (code
== IOR
&& term
== false_rtx
)
1829 if (code
== IOR
&& exp
== true_rtx
)
1831 if (code
== IOR
&& exp
== false_rtx
)
1833 if (attr_equal_p (exp
, term
))
1836 if (GET_CODE (term
) == code
)
1838 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1839 insn_code
, insn_index
);
1840 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1841 insn_code
, insn_index
);
1846 if (GET_CODE (exp
) == code
)
1848 rtx
new = insert_right_side (code
, XEXP (exp
, 1),
1849 term
, insn_code
, insn_index
);
1850 if (new != XEXP (exp
, 1))
1851 /* Make a copy of this expression and call recursively. */
1852 newexp
= attr_rtx (code
, XEXP (exp
, 0), new);
1858 /* Insert the new term. */
1859 newexp
= attr_rtx (code
, exp
, term
);
1862 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1865 /* If we have an expression which AND's a bunch of
1866 (not (eq_attrq "alternative" "n"))
1867 terms, we may have covered all or all but one of the possible alternatives.
1868 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1870 This routine is passed an expression and either AND or IOR. It returns a
1871 bitmask indicating which alternatives are mentioned within EXP. */
1874 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1877 if (GET_CODE (exp
) == code
)
1878 return compute_alternative_mask (XEXP (exp
, 0), code
)
1879 | compute_alternative_mask (XEXP (exp
, 1), code
);
1881 else if (code
== AND
&& GET_CODE (exp
) == NOT
1882 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1883 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1884 string
= XSTR (XEXP (exp
, 0), 1);
1886 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1887 && XSTR (exp
, 0) == alternative_name
)
1888 string
= XSTR (exp
, 1);
1890 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1892 if (code
== AND
&& XINT (exp
, 1))
1893 return XINT (exp
, 0);
1895 if (code
== IOR
&& !XINT (exp
, 1))
1896 return XINT (exp
, 0);
1904 return 1 << (string
[0] - '0');
1905 return 1 << atoi (string
);
1908 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1909 attribute with the value represented by that bit. */
1912 make_alternative_compare (int mask
)
1914 return mk_attr_alt (mask
);
1917 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1918 of "attr" for this insn code. From that value, we can compute a test
1919 showing when the EQ_ATTR will be true. This routine performs that
1920 computation. If a test condition involves an address, we leave the EQ_ATTR
1921 intact because addresses are only valid for the `length' attribute.
1923 EXP is the EQ_ATTR expression and VALUE is the value of that attribute
1924 for the insn corresponding to INSN_CODE and INSN_INDEX. */
1927 evaluate_eq_attr (rtx exp
, rtx value
, int insn_code
, int insn_index
)
1934 switch (GET_CODE (value
))
1937 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
1948 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
1949 gcc_assert (strlen (XSTR (exp
, 0)) + strlen (XSTR (exp
, 1)) + 2
1952 strcpy (string
, XSTR (exp
, 0));
1953 strcat (string
, "_");
1954 strcat (string
, XSTR (exp
, 1));
1955 for (p
= string
; *p
; p
++)
1958 newexp
= attr_rtx (EQ
, value
,
1959 attr_rtx (SYMBOL_REF
,
1960 DEF_ATTR_STRING (string
)));
1965 /* We construct an IOR of all the cases for which the
1966 requested attribute value is present. Since we start with
1967 FALSE, if it is not present, FALSE will be returned.
1969 Each case is the AND of the NOT's of the previous conditions with the
1970 current condition; in the default case the current condition is TRUE.
1972 For each possible COND value, call ourselves recursively.
1974 The extra TRUE and FALSE expressions will be eliminated by another
1975 call to the simplification routine. */
1980 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
1982 rtx
this = simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
1983 insn_code
, insn_index
);
1985 right
= insert_right_side (AND
, andexp
, this,
1986 insn_code
, insn_index
);
1987 right
= insert_right_side (AND
, right
,
1988 evaluate_eq_attr (exp
,
1991 insn_code
, insn_index
),
1992 insn_code
, insn_index
);
1993 orexp
= insert_right_side (IOR
, orexp
, right
,
1994 insn_code
, insn_index
);
1996 /* Add this condition into the AND expression. */
1997 newexp
= attr_rtx (NOT
, this);
1998 andexp
= insert_right_side (AND
, andexp
, newexp
,
1999 insn_code
, insn_index
);
2002 /* Handle the default case. */
2003 right
= insert_right_side (AND
, andexp
,
2004 evaluate_eq_attr (exp
, XEXP (value
, 1),
2005 insn_code
, insn_index
),
2006 insn_code
, insn_index
);
2007 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2014 /* If uses an address, must return original expression. But set the
2015 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2018 walk_attr_value (newexp
);
2022 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2023 return copy_rtx_unchanging (exp
);
2030 /* This routine is called when an AND of a term with a tree of AND's is
2031 encountered. If the term or its complement is present in the tree, it
2032 can be replaced with TRUE or FALSE, respectively.
2034 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2035 be true and hence are complementary.
2037 There is one special case: If we see
2038 (and (not (eq_attr "att" "v1"))
2039 (eq_attr "att" "v2"))
2040 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2041 replace the term, not anything in the AND tree. So we pass a pointer to
2045 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2050 int left_eliminates_term
, right_eliminates_term
;
2052 if (GET_CODE (exp
) == AND
)
2054 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2055 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2056 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2058 newexp
= attr_rtx (AND
, left
, right
);
2060 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2064 else if (GET_CODE (exp
) == IOR
)
2066 /* For the IOR case, we do the same as above, except that we can
2067 only eliminate `term' if both sides of the IOR would do so. */
2069 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2070 left_eliminates_term
= (temp
== true_rtx
);
2073 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2074 right_eliminates_term
= (temp
== true_rtx
);
2076 if (left_eliminates_term
&& right_eliminates_term
)
2079 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2081 newexp
= attr_rtx (IOR
, left
, right
);
2083 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2087 /* Check for simplifications. Do some extra checking here since this
2088 routine is called so many times. */
2093 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2096 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2099 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2101 if (attr_alt_subset_p (*pterm
, exp
))
2104 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2107 if (attr_alt_subset_p (exp
, *pterm
))
2113 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2115 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2118 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2124 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2125 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2127 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2130 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2136 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2137 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2139 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2142 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2148 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2150 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2154 else if (GET_CODE (exp
) == NOT
)
2156 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2160 else if (GET_CODE (*pterm
) == NOT
)
2162 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2166 else if (attr_equal_p (exp
, *pterm
))
2172 /* Similar to `simplify_and_tree', but for IOR trees. */
2175 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2180 int left_eliminates_term
, right_eliminates_term
;
2182 if (GET_CODE (exp
) == IOR
)
2184 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2185 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2186 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2188 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2190 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2194 else if (GET_CODE (exp
) == AND
)
2196 /* For the AND case, we do the same as above, except that we can
2197 only eliminate `term' if both sides of the AND would do so. */
2199 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2200 left_eliminates_term
= (temp
== false_rtx
);
2203 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2204 right_eliminates_term
= (temp
== false_rtx
);
2206 if (left_eliminates_term
&& right_eliminates_term
)
2209 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2211 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2213 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2217 if (attr_equal_p (exp
, *pterm
))
2220 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2223 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2226 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2227 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2228 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2231 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2232 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2233 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2239 /* Compute approximate cost of the expression. Used to decide whether
2240 expression is cheap enough for inline. */
2242 attr_rtx_cost (rtx x
)
2248 code
= GET_CODE (x
);
2261 /* Alternatives don't result into function call. */
2262 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
2269 const char *fmt
= GET_RTX_FORMAT (code
);
2270 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2276 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2277 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
2280 cost
+= attr_rtx_cost (XEXP (x
, i
));
2290 /* Simplify test expression and use temporary obstack in order to avoid
2291 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2292 and avoid unnecessary copying if possible. */
2295 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2298 struct obstack
*old
;
2299 if (ATTR_IND_SIMPLIFIED_P (exp
))
2302 rtl_obstack
= temp_obstack
;
2303 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2305 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2307 return attr_copy_rtx (x
);
2310 /* Returns true if S1 is a subset of S2. */
2313 attr_alt_subset_p (rtx s1
, rtx s2
)
2315 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2318 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2321 return !(XINT (s1
, 0) & XINT (s2
, 0));
2327 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2334 /* Returns true if S1 is a subset of complement of S2. */
2337 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2339 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2342 return !(XINT (s1
, 0) & XINT (s2
, 0));
2345 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2348 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2358 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2361 attr_alt_intersection (rtx s1
, rtx s2
)
2363 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2365 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2368 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2371 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2374 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2377 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2382 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2387 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2390 attr_alt_union (rtx s1
, rtx s2
)
2392 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2394 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2397 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2400 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2403 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2406 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2412 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2416 /* Return EQ_ATTR_ALT expression representing complement of S. */
2419 attr_alt_complement (rtx s
)
2421 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2423 XINT (result
, 0) = XINT (s
, 0);
2424 XINT (result
, 1) = 1 - XINT (s
, 1);
2429 /* Return EQ_ATTR_ALT expression representing set containing elements set
2435 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2437 XINT (result
, 0) = e
;
2438 XINT (result
, 1) = 0;
2443 /* Given an expression, see if it can be simplified for a particular insn
2444 code based on the values of other attributes being tested. This can
2445 eliminate nested get_attr_... calls.
2447 Note that if an endless recursion is specified in the patterns, the
2448 optimization will loop. However, it will do so in precisely the cases where
2449 an infinite recursion loop could occur during compilation. It's better that
2453 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2456 struct attr_desc
*attr
;
2457 struct attr_value
*av
;
2458 struct insn_ent
*ie
;
2459 struct attr_value_list
*iv
;
2462 bool left_alt
, right_alt
;
2464 /* Don't re-simplify something we already simplified. */
2465 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2468 switch (GET_CODE (exp
))
2471 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2472 if (left
== false_rtx
)
2474 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2475 if (right
== false_rtx
)
2478 if (GET_CODE (left
) == EQ_ATTR_ALT
2479 && GET_CODE (right
) == EQ_ATTR_ALT
)
2481 exp
= attr_alt_intersection (left
, right
);
2482 return simplify_test_exp (exp
, insn_code
, insn_index
);
2485 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2486 present on both sides, apply the distributive law since this will
2487 yield simplifications. */
2488 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2489 && compute_alternative_mask (left
, IOR
)
2490 && compute_alternative_mask (right
, IOR
))
2492 if (GET_CODE (left
) == IOR
)
2499 newexp
= attr_rtx (IOR
,
2500 attr_rtx (AND
, left
, XEXP (right
, 0)),
2501 attr_rtx (AND
, left
, XEXP (right
, 1)));
2503 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2506 /* Try with the term on both sides. */
2507 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2508 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2509 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2511 if (left
== false_rtx
|| right
== false_rtx
)
2513 else if (left
== true_rtx
)
2517 else if (right
== true_rtx
)
2521 /* See if all or all but one of the insn's alternatives are specified
2522 in this tree. Optimize if so. */
2524 if (GET_CODE (left
) == NOT
)
2525 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2526 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2528 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2531 if (GET_CODE (right
) == NOT
)
2532 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2533 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2535 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2536 && XINT (right
, 1));
2539 && (GET_CODE (left
) == AND
2541 || GET_CODE (right
) == AND
2544 i
= compute_alternative_mask (exp
, AND
);
2545 if (i
& ~insn_alternatives
[insn_code
])
2546 fatal ("invalid alternative specified for pattern number %d",
2549 /* If all alternatives are excluded, this is false. */
2550 i
^= insn_alternatives
[insn_code
];
2553 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2555 /* If just one excluded, AND a comparison with that one to the
2556 front of the tree. The others will be eliminated by
2557 optimization. We do not want to do this if the insn has one
2558 alternative and we have tested none of them! */
2559 left
= make_alternative_compare (i
);
2560 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2561 newexp
= attr_rtx (AND
, left
, right
);
2563 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2567 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2569 newexp
= attr_rtx (AND
, left
, right
);
2570 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2575 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2576 if (left
== true_rtx
)
2578 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2579 if (right
== true_rtx
)
2582 if (GET_CODE (left
) == EQ_ATTR_ALT
2583 && GET_CODE (right
) == EQ_ATTR_ALT
)
2585 exp
= attr_alt_union (left
, right
);
2586 return simplify_test_exp (exp
, insn_code
, insn_index
);
2589 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2590 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2591 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2593 if (right
== true_rtx
|| left
== true_rtx
)
2595 else if (left
== false_rtx
)
2599 else if (right
== false_rtx
)
2604 /* Test for simple cases where the distributive law is useful. I.e.,
2605 convert (ior (and (x) (y))
2611 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2612 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2614 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2616 left
= XEXP (left
, 0);
2618 newexp
= attr_rtx (AND
, left
, right
);
2619 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2622 /* See if all or all but one of the insn's alternatives are specified
2623 in this tree. Optimize if so. */
2625 else if (insn_code
>= 0
2626 && (GET_CODE (left
) == IOR
2627 || (GET_CODE (left
) == EQ_ATTR_ALT
2629 || (GET_CODE (left
) == EQ_ATTR
2630 && XSTR (left
, 0) == alternative_name
)
2631 || GET_CODE (right
) == IOR
2632 || (GET_CODE (right
) == EQ_ATTR_ALT
2633 && !XINT (right
, 1))
2634 || (GET_CODE (right
) == EQ_ATTR
2635 && XSTR (right
, 0) == alternative_name
)))
2637 i
= compute_alternative_mask (exp
, IOR
);
2638 if (i
& ~insn_alternatives
[insn_code
])
2639 fatal ("invalid alternative specified for pattern number %d",
2642 /* If all alternatives are included, this is true. */
2643 i
^= insn_alternatives
[insn_code
];
2646 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2648 /* If just one excluded, IOR a comparison with that one to the
2649 front of the tree. The others will be eliminated by
2650 optimization. We do not want to do this if the insn has one
2651 alternative and we have tested none of them! */
2652 left
= make_alternative_compare (i
);
2653 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2654 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2656 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2660 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2662 newexp
= attr_rtx (IOR
, left
, right
);
2663 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2668 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2670 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2671 insn_code
, insn_index
);
2675 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2676 if (GET_CODE (left
) == NOT
)
2677 return XEXP (left
, 0);
2679 if (left
== false_rtx
)
2681 if (left
== true_rtx
)
2684 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2686 exp
= attr_alt_complement (left
);
2687 return simplify_test_exp (exp
, insn_code
, insn_index
);
2690 /* Try to apply De`Morgan's laws. */
2691 if (GET_CODE (left
) == IOR
)
2693 newexp
= attr_rtx (AND
,
2694 attr_rtx (NOT
, XEXP (left
, 0)),
2695 attr_rtx (NOT
, XEXP (left
, 1)));
2697 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2699 else if (GET_CODE (left
) == AND
)
2701 newexp
= attr_rtx (IOR
,
2702 attr_rtx (NOT
, XEXP (left
, 0)),
2703 attr_rtx (NOT
, XEXP (left
, 1)));
2705 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2707 else if (left
!= XEXP (exp
, 0))
2709 newexp
= attr_rtx (NOT
, left
);
2715 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2719 if (XSTR (exp
, 0) == alternative_name
)
2721 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2725 /* Look at the value for this insn code in the specified attribute.
2726 We normally can replace this comparison with the condition that
2727 would give this insn the values being tested for. */
2729 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2734 if (insn_code_values
)
2736 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2737 if (iv
->attr
== attr
)
2745 for (av
= attr
->first_value
; av
; av
= av
->next
)
2746 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2747 if (ie
->def
->insn_code
== insn_code
)
2754 x
= evaluate_eq_attr (exp
, av
->value
, insn_code
, insn_index
);
2755 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2756 if (attr_rtx_cost(x
) < 20)
2766 /* We have already simplified this expression. Simplifying it again
2767 won't buy anything unless we weren't given a valid insn code
2768 to process (i.e., we are canonicalizing something.). */
2770 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2771 return copy_rtx_unchanging (newexp
);
2776 /* Optimize the attribute lists by seeing if we can determine conditional
2777 values from the known values of other attributes. This will save subroutine
2778 calls during the compilation. */
2781 optimize_attrs (void)
2783 struct attr_desc
*attr
;
2784 struct attr_value
*av
;
2785 struct insn_ent
*ie
;
2788 struct attr_value_list
*ivbuf
;
2789 struct attr_value_list
*iv
;
2791 /* For each insn code, make a list of all the insn_ent's for it,
2792 for all values for all attributes. */
2794 if (num_insn_ents
== 0)
2797 /* Make 2 extra elements, for "code" values -2 and -1. */
2798 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2800 /* Offset the table address so we can index by -2 or -1. */
2801 insn_code_values
+= 2;
2803 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2805 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2806 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2807 for (av
= attr
->first_value
; av
; av
= av
->next
)
2808 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2813 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2814 insn_code_values
[ie
->def
->insn_code
] = iv
;
2818 /* Sanity check on num_insn_ents. */
2819 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2821 /* Process one insn code at a time. */
2822 for (i
= -2; i
< insn_code_number
; i
++)
2824 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2825 We use it to mean "already simplified for this insn". */
2826 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2827 clear_struct_flag (iv
->av
->value
);
2829 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2831 struct obstack
*old
= rtl_obstack
;
2836 if (GET_CODE (av
->value
) != COND
)
2839 rtl_obstack
= temp_obstack
;
2841 while (GET_CODE (newexp
) == COND
)
2843 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2844 ie
->def
->insn_index
);
2845 if (newexp2
== newexp
)
2851 if (newexp
!= av
->value
)
2853 newexp
= attr_copy_rtx (newexp
);
2854 remove_insn_ent (av
, ie
);
2855 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
2857 insert_insn_ent (av
, ie
);
2863 free (insn_code_values
- 2);
2864 insn_code_values
= NULL
;
2867 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2870 clear_struct_flag (rtx x
)
2877 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
2878 if (ATTR_IND_SIMPLIFIED_P (x
))
2881 code
= GET_CODE (x
);
2901 /* Compare the elements. If any pair of corresponding elements
2902 fail to match, return 0 for the whole things. */
2904 fmt
= GET_RTX_FORMAT (code
);
2905 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
2911 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
2912 clear_struct_flag (XVECEXP (x
, i
, j
));
2916 clear_struct_flag (XEXP (x
, i
));
2922 /* Create table entries for DEFINE_ATTR. */
2925 gen_attr (rtx exp
, int lineno
)
2927 struct attr_desc
*attr
;
2928 struct attr_value
*av
;
2929 const char *name_ptr
;
2932 /* Make a new attribute structure. Check for duplicate by looking at
2933 attr->default_val, since it is initialized by this routine. */
2934 attr
= find_attr (&XSTR (exp
, 0), 1);
2935 if (attr
->default_val
)
2937 message_with_line (lineno
, "duplicate definition for attribute %s",
2939 message_with_line (attr
->lineno
, "previous definition");
2943 attr
->lineno
= lineno
;
2945 if (*XSTR (exp
, 1) == '\0')
2946 attr
->is_numeric
= 1;
2949 name_ptr
= XSTR (exp
, 1);
2950 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
2952 av
= oballoc (sizeof (struct attr_value
));
2953 av
->value
= attr_rtx (CONST_STRING
, p
);
2954 av
->next
= attr
->first_value
;
2955 attr
->first_value
= av
;
2956 av
->first_insn
= NULL
;
2958 av
->has_asm_insn
= 0;
2962 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
2965 if (attr
->is_numeric
)
2967 message_with_line (lineno
,
2968 "constant attributes may not take numeric values");
2972 /* Get rid of the CONST node. It is allowed only at top-level. */
2973 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
2976 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
2978 message_with_line (lineno
,
2979 "`length' attribute must take numeric values");
2983 /* Set up the default value. */
2984 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
2985 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
2988 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
2989 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
2990 number of alternatives as this should be checked elsewhere. */
2993 count_alternatives (rtx exp
)
2998 if (GET_CODE (exp
) == MATCH_OPERAND
)
2999 return n_comma_elts (XSTR (exp
, 2));
3001 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3002 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3007 n
= count_alternatives (XEXP (exp
, i
));
3014 if (XVEC (exp
, i
) != NULL
)
3015 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3017 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3026 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3027 `alternative' attribute. */
3030 compares_alternatives_p (rtx exp
)
3035 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3038 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3039 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3044 if (compares_alternatives_p (XEXP (exp
, i
)))
3049 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3050 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3058 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3061 gen_insn (rtx exp
, int lineno
)
3063 struct insn_def
*id
;
3065 id
= oballoc (sizeof (struct insn_def
));
3069 id
->lineno
= lineno
;
3071 switch (GET_CODE (exp
))
3074 id
->insn_code
= insn_code_number
;
3075 id
->insn_index
= insn_index_number
;
3076 id
->num_alternatives
= count_alternatives (exp
);
3077 if (id
->num_alternatives
== 0)
3078 id
->num_alternatives
= 1;
3082 case DEFINE_PEEPHOLE
:
3083 id
->insn_code
= insn_code_number
;
3084 id
->insn_index
= insn_index_number
;
3085 id
->num_alternatives
= count_alternatives (exp
);
3086 if (id
->num_alternatives
== 0)
3087 id
->num_alternatives
= 1;
3091 case DEFINE_ASM_ATTRIBUTES
:
3093 id
->insn_index
= -1;
3094 id
->num_alternatives
= 1;
3096 got_define_asm_attributes
= 1;
3104 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3105 true or annul false is specified, and make a `struct delay_desc'. */
3108 gen_delay (rtx def
, int lineno
)
3110 struct delay_desc
*delay
;
3113 if (XVECLEN (def
, 1) % 3 != 0)
3115 message_with_line (lineno
,
3116 "number of elements in DEFINE_DELAY must be multiple of three");
3121 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3123 if (XVECEXP (def
, 1, i
+ 1))
3124 have_annul_true
= 1;
3125 if (XVECEXP (def
, 1, i
+ 2))
3126 have_annul_false
= 1;
3129 delay
= oballoc (sizeof (struct delay_desc
));
3131 delay
->num
= ++num_delays
;
3132 delay
->next
= delays
;
3133 delay
->lineno
= lineno
;
3137 /* Given a piece of RTX, print a C expression to test its truth value.
3138 We use AND and IOR both for logical and bit-wise operations, so
3139 interpret them as logical unless they are inside a comparison expression.
3140 The first bit of FLAGS will be nonzero in that case.
3142 Set the second bit of FLAGS to make references to attribute values use
3143 a cached local variable instead of calling a function. */
3146 write_test_expr (rtx exp
, int flags
)
3148 int comparison_operator
= 0;
3150 struct attr_desc
*attr
;
3152 /* In order not to worry about operator precedence, surround our part of
3153 the expression with parentheses. */
3156 code
= GET_CODE (exp
);
3159 /* Binary operators. */
3162 printf ("(unsigned) ");
3168 comparison_operator
= 1;
3170 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3171 case AND
: case IOR
: case XOR
:
3172 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3173 write_test_expr (XEXP (exp
, 0), flags
| comparison_operator
);
3189 printf (" >= (unsigned) ");
3192 printf (" > (unsigned) ");
3201 printf (" <= (unsigned) ");
3204 printf (" < (unsigned) ");
3247 write_test_expr (XEXP (exp
, 1), flags
| comparison_operator
);
3251 /* Special-case (not (eq_attrq "alternative" "x")) */
3252 if (! (flags
& 1) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3253 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3255 printf ("which_alternative != %s", XSTR (XEXP (exp
, 0), 1));
3259 /* Otherwise, fall through to normal unary operator. */
3261 /* Unary operators. */
3281 write_test_expr (XEXP (exp
, 0), flags
);
3286 int set
= XINT (exp
, 0), bit
= 0;
3289 fatal ("EQ_ATTR_ALT not valid inside comparison");
3292 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3294 if (!(set
& (set
- 1)))
3296 if (!(set
& 0xffff))
3319 printf ("which_alternative %s= %d",
3320 XINT (exp
, 1) ? "!" : "=", bit
);
3324 printf ("%s((1 << which_alternative) & 0x%x)",
3325 XINT (exp
, 1) ? "!" : "", set
);
3330 /* Comparison test of an attribute with a value. Most of these will
3331 have been removed by optimization. Handle "alternative"
3332 specially and give error if EQ_ATTR present inside a comparison. */
3335 fatal ("EQ_ATTR not valid inside comparison");
3337 if (XSTR (exp
, 0) == alternative_name
)
3339 printf ("which_alternative == %s", XSTR (exp
, 1));
3343 attr
= find_attr (&XSTR (exp
, 0), 0);
3346 /* Now is the time to expand the value of a constant attribute. */
3349 write_test_expr (evaluate_eq_attr (exp
, attr
->default_val
->value
,
3356 printf ("attr_%s", attr
->name
);
3358 printf ("get_attr_%s (insn)", attr
->name
);
3360 write_attr_valueq (attr
, XSTR (exp
, 1));
3364 /* Comparison test of flags for define_delays. */
3367 fatal ("ATTR_FLAG not valid inside comparison");
3368 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3371 /* See if an operand matches a predicate. */
3373 /* If only a mode is given, just ensure the mode matches the operand.
3374 If neither a mode nor predicate is given, error. */
3375 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3377 if (GET_MODE (exp
) == VOIDmode
)
3378 fatal ("null MATCH_OPERAND specified as test");
3380 printf ("GET_MODE (operands[%d]) == %smode",
3381 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3384 printf ("%s (operands[%d], %smode)",
3385 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3388 /* Constant integer. */
3390 printf (HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3393 /* A random C expression. */
3395 print_c_condition (XSTR (exp
, 0));
3398 /* The address of the branch target. */
3400 printf ("INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3401 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3405 /* The address of the current insn. We implement this actually as the
3406 address of the current insn for backward branches, but the last
3407 address of the next insn for forward branches, and both with
3408 adjustments that account for the worst-case possible stretching of
3409 intervening alignments between this insn and its destination. */
3410 printf ("insn_current_reference_address (insn)");
3414 printf ("%s", XSTR (exp
, 0));
3418 write_test_expr (XEXP (exp
, 0), flags
& 2);
3420 write_test_expr (XEXP (exp
, 1), flags
| 1);
3422 write_test_expr (XEXP (exp
, 2), flags
| 1);
3426 fatal ("bad RTX code `%s' in attribute calculation\n",
3427 GET_RTX_NAME (code
));
3433 /* Given an attribute value, return the maximum CONST_STRING argument
3434 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3437 max_attr_value (rtx exp
, int *unknownp
)
3442 switch (GET_CODE (exp
))
3445 current_max
= atoi (XSTR (exp
, 0));
3449 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3450 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3452 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3453 if (n
> current_max
)
3459 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3460 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3461 if (n
> current_max
)
3467 current_max
= INT_MAX
;
3474 /* Given an attribute value, return the minimum CONST_STRING argument
3475 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3478 min_attr_value (rtx exp
, int *unknownp
)
3483 switch (GET_CODE (exp
))
3486 current_min
= atoi (XSTR (exp
, 0));
3490 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3491 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3493 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3494 if (n
< current_min
)
3500 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3501 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3502 if (n
< current_min
)
3508 current_min
= INT_MAX
;
3515 /* Given an attribute value, return the result of ORing together all
3516 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3517 if the numeric value is not known. */
3520 or_attr_value (rtx exp
, int *unknownp
)
3525 switch (GET_CODE (exp
))
3528 current_or
= atoi (XSTR (exp
, 0));
3532 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3533 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3534 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3538 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3539 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3551 /* Scan an attribute value, possibly a conditional, and record what actions
3552 will be required to do any conditional tests in it.
3555 `must_extract' if we need to extract the insn operands
3556 `must_constrain' if we must compute `which_alternative'
3557 `address_used' if an address expression was used
3558 `length_used' if an (eq_attr "length" ...) was used
3562 walk_attr_value (rtx exp
)
3571 code
= GET_CODE (exp
);
3575 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3576 /* Since this is an arbitrary expression, it can look at anything.
3577 However, constant expressions do not depend on any particular
3579 must_extract
= must_constrain
= 1;
3587 must_extract
= must_constrain
= 1;
3591 if (XSTR (exp
, 0) == alternative_name
)
3592 must_extract
= must_constrain
= 1;
3593 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3613 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
3618 walk_attr_value (XEXP (exp
, i
));
3622 if (XVEC (exp
, i
) != NULL
)
3623 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3624 walk_attr_value (XVECEXP (exp
, i
, j
));
3629 /* Write out a function to obtain the attribute for a given INSN. */
3632 write_attr_get (struct attr_desc
*attr
)
3634 struct attr_value
*av
, *common_av
;
3636 /* Find the most used attribute value. Handle that as the `default' of the
3637 switch we will generate. */
3638 common_av
= find_most_used (attr
);
3640 /* Write out start of function, then all values with explicit `case' lines,
3641 then a `default', then the value with the most uses. */
3642 if (!attr
->is_numeric
)
3643 printf ("enum attr_%s\n", attr
->name
);
3647 /* If the attribute name starts with a star, the remainder is the name of
3648 the subroutine to use, instead of `get_attr_...'. */
3649 if (attr
->name
[0] == '*')
3650 printf ("%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
3651 else if (attr
->is_const
== 0)
3652 printf ("get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
3655 printf ("get_attr_%s (void)\n", attr
->name
);
3658 for (av
= attr
->first_value
; av
; av
= av
->next
)
3659 if (av
->num_insns
== 1)
3660 write_attr_set (attr
, 2, av
->value
, "return", ";",
3661 true_rtx
, av
->first_insn
->def
->insn_code
,
3662 av
->first_insn
->def
->insn_index
);
3663 else if (av
->num_insns
!= 0)
3664 write_attr_set (attr
, 2, av
->value
, "return", ";",
3672 printf (" switch (recog_memoized (insn))\n");
3675 for (av
= attr
->first_value
; av
; av
= av
->next
)
3676 if (av
!= common_av
)
3677 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
3679 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
3680 printf (" }\n}\n\n");
3683 /* Given an AND tree of known true terms (because we are inside an `if' with
3684 that as the condition or are in an `else' clause) and an expression,
3685 replace any known true terms with TRUE. Use `simplify_and_tree' to do
3686 the bulk of the work. */
3689 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
3693 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
3695 if (GET_CODE (known_true
) == AND
)
3697 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
3698 insn_code
, insn_index
);
3699 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
3700 insn_code
, insn_index
);
3705 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
3711 /* Write out a series of tests and assignment statements to perform tests and
3712 sets of an attribute value. We are passed an indentation amount and prefix
3713 and suffix strings to write around each attribute value (e.g., "return"
3717 write_attr_set (struct attr_desc
*attr
, int indent
, rtx value
,
3718 const char *prefix
, const char *suffix
, rtx known_true
,
3719 int insn_code
, int insn_index
)
3721 if (GET_CODE (value
) == COND
)
3723 /* Assume the default value will be the default of the COND unless we
3724 find an always true expression. */
3725 rtx default_val
= XEXP (value
, 1);
3726 rtx our_known_true
= known_true
;
3731 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
3736 testexp
= eliminate_known_true (our_known_true
,
3737 XVECEXP (value
, 0, i
),
3738 insn_code
, insn_index
);
3739 newexp
= attr_rtx (NOT
, testexp
);
3740 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
3741 insn_code
, insn_index
);
3743 /* If the test expression is always true or if the next `known_true'
3744 expression is always false, this is the last case, so break
3745 out and let this value be the `else' case. */
3746 if (testexp
== true_rtx
|| newexp
== false_rtx
)
3748 default_val
= XVECEXP (value
, 0, i
+ 1);
3752 /* Compute the expression to pass to our recursive call as being
3754 inner_true
= insert_right_side (AND
, our_known_true
,
3755 testexp
, insn_code
, insn_index
);
3757 /* If this is always false, skip it. */
3758 if (inner_true
== false_rtx
)
3761 write_indent (indent
);
3762 printf ("%sif ", first_if
? "" : "else ");
3764 write_test_expr (testexp
, 0);
3766 write_indent (indent
+ 2);
3769 write_attr_set (attr
, indent
+ 4,
3770 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
3771 inner_true
, insn_code
, insn_index
);
3772 write_indent (indent
+ 2);
3774 our_known_true
= newexp
;
3779 write_indent (indent
);
3781 write_indent (indent
+ 2);
3785 write_attr_set (attr
, first_if
? indent
: indent
+ 4, default_val
,
3786 prefix
, suffix
, our_known_true
, insn_code
, insn_index
);
3790 write_indent (indent
+ 2);
3796 write_indent (indent
);
3797 printf ("%s ", prefix
);
3798 write_attr_value (attr
, value
);
3799 printf ("%s\n", suffix
);
3803 /* Write a series of case statements for every instruction in list IE.
3804 INDENT is the amount of indentation to write before each case. */
3807 write_insn_cases (struct insn_ent
*ie
, int indent
)
3809 for (; ie
!= 0; ie
= ie
->next
)
3810 if (ie
->def
->insn_code
!= -1)
3812 write_indent (indent
);
3813 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
3814 printf ("case %d: /* define_peephole, line %d */\n",
3815 ie
->def
->insn_code
, ie
->def
->lineno
);
3817 printf ("case %d: /* %s */\n",
3818 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
3822 /* Write out the computation for one attribute value. */
3825 write_attr_case (struct attr_desc
*attr
, struct attr_value
*av
,
3826 int write_case_lines
, const char *prefix
, const char *suffix
,
3827 int indent
, rtx known_true
)
3829 if (av
->num_insns
== 0)
3832 if (av
->has_asm_insn
)
3834 write_indent (indent
);
3835 printf ("case -1:\n");
3836 write_indent (indent
+ 2);
3837 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
3838 write_indent (indent
+ 2);
3839 printf (" && asm_noperands (PATTERN (insn)) < 0)\n");
3840 write_indent (indent
+ 2);
3841 printf (" fatal_insn_not_found (insn);\n");
3844 if (write_case_lines
)
3845 write_insn_cases (av
->first_insn
, indent
);
3848 write_indent (indent
);
3849 printf ("default:\n");
3852 /* See what we have to do to output this value. */
3853 must_extract
= must_constrain
= address_used
= 0;
3854 walk_attr_value (av
->value
);
3858 write_indent (indent
+ 2);
3859 printf ("extract_constrain_insn_cached (insn);\n");
3861 else if (must_extract
)
3863 write_indent (indent
+ 2);
3864 printf ("extract_insn_cached (insn);\n");
3867 if (av
->num_insns
== 1)
3868 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3869 known_true
, av
->first_insn
->def
->insn_code
,
3870 av
->first_insn
->def
->insn_index
);
3872 write_attr_set (attr
, indent
+ 2, av
->value
, prefix
, suffix
,
3875 if (strncmp (prefix
, "return", 6))
3877 write_indent (indent
+ 2);
3878 printf ("break;\n");
3883 /* Utilities to write in various forms. */
3886 write_attr_valueq (struct attr_desc
*attr
, const char *s
)
3888 if (attr
->is_numeric
)
3894 if (num
> 9 || num
< 0)
3895 printf (" /* 0x%x */", num
);
3899 write_upcase (attr
->name
);
3906 write_attr_value (struct attr_desc
*attr
, rtx value
)
3910 switch (GET_CODE (value
))
3913 write_attr_valueq (attr
, XSTR (value
, 0));
3917 printf (HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
3921 print_c_condition (XSTR (value
, 0));
3926 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
3927 printf ("get_attr_%s (%s)", attr2
->name
,
3928 (attr2
->is_const
? "" : "insn"));
3949 write_attr_value (attr
, XEXP (value
, 0));
3953 write_attr_value (attr
, XEXP (value
, 1));
3962 write_upcase (const char *str
)
3966 /* The argument of TOUPPER should not have side effects. */
3967 putchar (TOUPPER(*str
));
3973 write_indent (int indent
)
3975 for (; indent
> 8; indent
-= 8)
3978 for (; indent
; indent
--)
3982 /* Write a subroutine that is given an insn that requires a delay slot, a
3983 delay slot ordinal, and a candidate insn. It returns nonzero if the
3984 candidate can be placed in the specified delay slot of the insn.
3986 We can write as many as three subroutines. `eligible_for_delay'
3987 handles normal delay slots, `eligible_for_annul_true' indicates that
3988 the specified insn can be annulled if the branch is true, and likewise
3989 for `eligible_for_annul_false'.
3991 KIND is a string distinguishing these three cases ("delay", "annul_true",
3992 or "annul_false"). */
3995 write_eligible_delay (const char *kind
)
3997 struct delay_desc
*delay
;
4001 struct attr_desc
*attr
;
4002 struct attr_value
*av
, *common_av
;
4005 /* Compute the maximum number of delay slots required. We use the delay
4006 ordinal times this number plus one, plus the slot number as an index into
4007 the appropriate predicate to test. */
4009 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4010 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4011 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4013 /* Write function prelude. */
4016 printf ("eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4019 printf (" rtx insn;\n");
4021 printf (" gcc_assert (slot < %d);\n", max_slots
);
4023 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4024 converts a compound instruction into a loop. */
4025 printf (" if (!INSN_P (candidate_insn))\n");
4026 printf (" return 0;\n");
4029 /* If more than one delay type, find out which type the delay insn is. */
4033 attr
= find_attr (&delay_type_str
, 0);
4035 common_av
= find_most_used (attr
);
4037 printf (" insn = delay_insn;\n");
4038 printf (" switch (recog_memoized (insn))\n");
4041 sprintf (str
, " * %d;\n break;", max_slots
);
4042 for (av
= attr
->first_value
; av
; av
= av
->next
)
4043 if (av
!= common_av
)
4044 write_attr_case (attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4046 write_attr_case (attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4049 /* Ensure matched. Otherwise, shouldn't have been called. */
4050 printf (" gcc_assert (slot >= %d);\n\n", max_slots
);
4053 /* If just one type of delay slot, write simple switch. */
4054 if (num_delays
== 1 && max_slots
== 1)
4056 printf (" insn = candidate_insn;\n");
4057 printf (" switch (recog_memoized (insn))\n");
4060 attr
= find_attr (&delay_1_0_str
, 0);
4062 common_av
= find_most_used (attr
);
4064 for (av
= attr
->first_value
; av
; av
= av
->next
)
4065 if (av
!= common_av
)
4066 write_attr_case (attr
, av
, 1, "return", ";", 4, true_rtx
);
4068 write_attr_case (attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4074 /* Write a nested CASE. The first indicates which condition we need to
4075 test, and the inner CASE tests the condition. */
4076 printf (" insn = candidate_insn;\n");
4077 printf (" switch (slot)\n");
4080 for (delay
= delays
; delay
; delay
= delay
->next
)
4081 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4083 printf (" case %d:\n",
4084 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4085 printf (" switch (recog_memoized (insn))\n");
4088 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4090 attr
= find_attr (&pstr
, 0);
4092 common_av
= find_most_used (attr
);
4094 for (av
= attr
->first_value
; av
; av
= av
->next
)
4095 if (av
!= common_av
)
4096 write_attr_case (attr
, av
, 1, "return", ";", 8, true_rtx
);
4098 write_attr_case (attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4102 printf (" default:\n");
4103 printf (" gcc_unreachable ();\n");
4110 /* This page contains miscellaneous utility routines. */
4112 /* Given a pointer to a (char *), return a malloc'ed string containing the
4113 next comma-separated element. Advance the pointer to after the string
4114 scanned, or the end-of-string. Return NULL if at end of string. */
4117 next_comma_elt (const char **pstr
)
4121 start
= scan_comma_elt (pstr
);
4126 return attr_string (start
, *pstr
- start
);
4129 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4130 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4131 replaced by a pointer to a canonical copy of the string. */
4133 static struct attr_desc
*
4134 find_attr (const char **name_p
, int create
)
4136 struct attr_desc
*attr
;
4138 const char *name
= *name_p
;
4140 /* Before we resort to using `strcmp', see if the string address matches
4141 anywhere. In most cases, it should have been canonicalized to do so. */
4142 if (name
== alternative_name
)
4145 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4146 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4147 if (name
== attr
->name
)
4150 /* Otherwise, do it the slow way. */
4151 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4152 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4154 *name_p
= attr
->name
;
4161 attr
= oballoc (sizeof (struct attr_desc
));
4162 attr
->name
= DEF_ATTR_STRING (name
);
4163 attr
->first_value
= attr
->default_val
= NULL
;
4164 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4165 attr
->next
= attrs
[index
];
4166 attrs
[index
] = attr
;
4168 *name_p
= attr
->name
;
4173 /* Create internal attribute with the given default value. */
4176 make_internal_attr (const char *name
, rtx value
, int special
)
4178 struct attr_desc
*attr
;
4180 attr
= find_attr (&name
, 1);
4181 gcc_assert (!attr
->default_val
);
4183 attr
->is_numeric
= 1;
4185 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4186 attr
->default_val
= get_attr_value (value
, attr
, -2);
4189 /* Find the most used value of an attribute. */
4191 static struct attr_value
*
4192 find_most_used (struct attr_desc
*attr
)
4194 struct attr_value
*av
;
4195 struct attr_value
*most_used
;
4201 for (av
= attr
->first_value
; av
; av
= av
->next
)
4202 if (av
->num_insns
> nuses
)
4203 nuses
= av
->num_insns
, most_used
= av
;
4208 /* Return (attr_value "n") */
4211 make_numeric_value (int n
)
4213 static rtx int_values
[20];
4217 gcc_assert (n
>= 0);
4219 if (n
< 20 && int_values
[n
])
4220 return int_values
[n
];
4222 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4223 exp
= attr_rtx (CONST_STRING
, p
);
4226 int_values
[n
] = exp
;
4232 copy_rtx_unchanging (rtx orig
)
4234 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4237 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4241 /* Determine if an insn has a constant number of delay slots, i.e., the
4242 number of delay slots is not a function of the length of the insn. */
4245 write_const_num_delay_slots (void)
4247 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4248 struct attr_value
*av
;
4252 printf ("int\nconst_num_delay_slots (rtx insn)\n");
4254 printf (" switch (recog_memoized (insn))\n");
4257 for (av
= attr
->first_value
; av
; av
= av
->next
)
4260 walk_attr_value (av
->value
);
4262 write_insn_cases (av
->first_insn
, 4);
4265 printf (" default:\n");
4266 printf (" return 1;\n");
4267 printf (" }\n}\n\n");
4271 /* Synthetic attributes used by insn-automata.c and the scheduler.
4272 These are primarily concerned with (define_insn_reservation)
4277 struct insn_reserv
*next
;
4280 int default_latency
;
4283 /* Sequence number of this insn. */
4286 /* Whether a (define_bypass) construct names this insn in its
4291 static struct insn_reserv
*all_insn_reservs
= 0;
4292 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4293 static size_t n_insn_reservs
;
4295 /* Store information from a DEFINE_INSN_RESERVATION for future
4296 attribute generation. */
4298 gen_insn_reserv (rtx def
)
4300 struct insn_reserv
*decl
= oballoc (sizeof (struct insn_reserv
));
4302 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4303 decl
->default_latency
= XINT (def
, 1);
4304 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4305 decl
->insn_num
= n_insn_reservs
;
4306 decl
->bypassed
= false;
4309 *last_insn_reserv_p
= decl
;
4310 last_insn_reserv_p
= &decl
->next
;
4314 /* Store information from a DEFINE_BYPASS for future attribute
4315 generation. The only thing we care about is the list of output
4316 insns, which will later be used to tag reservation structures with
4317 a 'bypassed' bit. */
4321 struct bypass_list
*next
;
4325 static struct bypass_list
*all_bypasses
;
4326 static size_t n_bypasses
;
4329 gen_bypass_1 (const char *s
, size_t len
)
4331 struct bypass_list
*b
;
4336 s
= attr_string (s
, len
);
4337 for (b
= all_bypasses
; b
; b
= b
->next
)
4339 return; /* already got that one */
4341 b
= oballoc (sizeof (struct bypass_list
));
4343 b
->next
= all_bypasses
;
4349 gen_bypass (rtx def
)
4351 const char *p
, *base
;
4353 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4356 gen_bypass_1 (base
, p
- base
);
4359 while (ISSPACE (*p
));
4362 gen_bypass_1 (base
, p
- base
);
4365 /* Find and mark all of the bypassed insns. */
4367 process_bypasses (void)
4369 struct bypass_list
*b
;
4370 struct insn_reserv
*r
;
4372 /* The reservation list is likely to be much longer than the bypass
4374 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4375 for (b
= all_bypasses
; b
; b
= b
->next
)
4376 if (r
->name
== b
->insn
)
4380 /* Create all of the attributes that describe automaton properties. */
4382 make_automaton_attrs (void)
4385 struct insn_reserv
*decl
;
4386 rtx code_exp
, lats_exp
, byps_exp
;
4388 if (n_insn_reservs
== 0)
4391 code_exp
= rtx_alloc (COND
);
4392 lats_exp
= rtx_alloc (COND
);
4394 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4395 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
4397 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4398 XEXP (lats_exp
, 1) = make_numeric_value (0);
4400 for (decl
= all_insn_reservs
, i
= 0;
4402 decl
= decl
->next
, i
+= 2)
4404 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
4405 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
4407 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
4408 XVECEXP (lats_exp
, 0, i
+1) = make_numeric_value (decl
->default_latency
);
4411 if (n_bypasses
== 0)
4412 byps_exp
= make_numeric_value (0);
4415 process_bypasses ();
4417 byps_exp
= rtx_alloc (COND
);
4418 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypasses
* 2);
4419 XEXP (byps_exp
, 1) = make_numeric_value (0);
4420 for (decl
= all_insn_reservs
, i
= 0;
4425 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
4426 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
4431 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
4432 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
4433 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
4437 main (int argc
, char **argv
)
4440 struct attr_desc
*attr
;
4441 struct insn_def
*id
;
4445 progname
= "genattrtab";
4447 if (init_md_reader_args (argc
, argv
) != SUCCESS_EXIT_CODE
)
4448 return (FATAL_EXIT_CODE
);
4450 obstack_init (hash_obstack
);
4451 obstack_init (temp_obstack
);
4453 /* Set up true and false rtx's */
4454 true_rtx
= rtx_alloc (CONST_INT
);
4455 XWINT (true_rtx
, 0) = 1;
4456 false_rtx
= rtx_alloc (CONST_INT
);
4457 XWINT (false_rtx
, 0) = 0;
4458 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
4459 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
4461 alternative_name
= DEF_ATTR_STRING ("alternative");
4462 length_str
= DEF_ATTR_STRING ("length");
4463 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
4464 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
4465 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
4467 printf ("/* Generated automatically by the program `genattrtab'\n\
4468 from the machine description file `md'. */\n\n");
4470 /* Read the machine description. */
4476 desc
= read_md_rtx (&lineno
, &insn_code_number
);
4480 switch (GET_CODE (desc
))
4483 case DEFINE_PEEPHOLE
:
4484 case DEFINE_ASM_ATTRIBUTES
:
4485 gen_insn (desc
, lineno
);
4489 gen_attr (desc
, lineno
);
4493 gen_delay (desc
, lineno
);
4496 case DEFINE_INSN_RESERVATION
:
4497 gen_insn_reserv (desc
);
4507 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
4508 insn_index_number
++;
4512 return FATAL_EXIT_CODE
;
4516 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
4517 if (! got_define_asm_attributes
)
4519 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
4520 XVEC (tem
, 0) = rtvec_alloc (0);
4524 /* Expand DEFINE_DELAY information into new attribute. */
4528 printf ("#include \"config.h\"\n");
4529 printf ("#include \"system.h\"\n");
4530 printf ("#include \"coretypes.h\"\n");
4531 printf ("#include \"tm.h\"\n");
4532 printf ("#include \"rtl.h\"\n");
4533 printf ("#include \"insn-attr.h\"\n");
4534 printf ("#include \"tm_p.h\"\n");
4535 printf ("#include \"insn-config.h\"\n");
4536 printf ("#include \"recog.h\"\n");
4537 printf ("#include \"regs.h\"\n");
4538 printf ("#include \"real.h\"\n");
4539 printf ("#include \"output.h\"\n");
4540 printf ("#include \"toplev.h\"\n");
4541 printf ("#include \"flags.h\"\n");
4542 printf ("#include \"function.h\"\n");
4544 printf ("#define operands recog_data.operand\n\n");
4546 /* Make `insn_alternatives'. */
4547 insn_alternatives
= oballoc (insn_code_number
* sizeof (int));
4548 for (id
= defs
; id
; id
= id
->next
)
4549 if (id
->insn_code
>= 0)
4550 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
4552 /* Make `insn_n_alternatives'. */
4553 insn_n_alternatives
= oballoc (insn_code_number
* sizeof (int));
4554 for (id
= defs
; id
; id
= id
->next
)
4555 if (id
->insn_code
>= 0)
4556 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
4558 /* Construct extra attributes for automata. */
4559 make_automaton_attrs ();
4561 /* Prepare to write out attribute subroutines by checking everything stored
4562 away and building the attribute cases. */
4566 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4567 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4568 attr
->default_val
->value
4569 = check_attr_value (attr
->default_val
->value
, attr
);
4572 return FATAL_EXIT_CODE
;
4574 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4575 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4578 /* Construct extra attributes for `length'. */
4579 make_length_attrs ();
4581 /* Perform any possible optimizations to speed up compilation. */
4584 /* Now write out all the `gen_attr_...' routines. Do these before the
4585 special routines so that they get defined before they are used. */
4587 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
4588 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
4590 if (! attr
->is_special
&& ! attr
->is_const
)
4591 write_attr_get (attr
);
4594 /* Write out delay eligibility information, if DEFINE_DELAY present.
4595 (The function to compute the number of delay slots will be written
4599 write_eligible_delay ("delay");
4600 if (have_annul_true
)
4601 write_eligible_delay ("annul_true");
4602 if (have_annul_false
)
4603 write_eligible_delay ("annul_false");
4606 /* Write out constant delay slot info. */
4607 write_const_num_delay_slots ();
4609 write_length_unit_log ();
4612 return (ferror (stdout
) != 0 ? FATAL_EXIT_CODE
: SUCCESS_EXIT_CODE
);