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, 2008, 2009, 2010, 2012
4 Free Software Foundation, Inc.
5 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
23 /* This program handles insn attributes and the DEFINE_DELAY and
24 DEFINE_INSN_RESERVATION definitions.
26 It produces a series of functions named `get_attr_...', one for each insn
27 attribute. Each of these is given the rtx for an insn and returns a member
28 of the enum for the attribute.
30 These subroutines have the form of a `switch' on the INSN_CODE (via
31 `recog_memoized'). Each case either returns a constant attribute value
32 or a value that depends on tests on other attributes, the form of
33 operands, or some random C expression (encoded with a SYMBOL_REF
36 If the attribute `alternative', or a random C expression is present,
37 `constrain_operands' is called. If either of these cases of a reference to
38 an operand is found, `extract_insn' is called.
40 The special attribute `length' is also recognized. For this operand,
41 expressions involving the address of an operand or the current insn,
42 (address (pc)), are valid. In this case, an initial pass is made to
43 set all lengths that do not depend on address. Those that do are set to
44 the maximum length. Then each insn that depends on an address is checked
45 and possibly has its length changed. The process repeats until no further
46 changed are made. The resulting lengths are saved for use by
49 A special form of DEFINE_ATTR, where the expression for default value is a
50 CONST expression, indicates an attribute that is constant for a given run
51 of the compiler. The subroutine generated for these attributes has no
52 parameters as it does not depend on any particular insn. Constant
53 attributes are typically used to specify which variety of processor is
56 Internal attributes are defined to handle DEFINE_DELAY and
57 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
59 This program works by keeping a list of possible values for each attribute.
60 These include the basic attribute choices, default values for attribute, and
61 all derived quantities.
63 As the description file is read, the definition for each insn is saved in a
64 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
65 is created for each insn and chained to the corresponding attribute value,
66 either that specified, or the default.
68 An optimization phase is then run. This simplifies expressions for each
69 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
70 indicates when the attribute has the specified value for the insn. This
71 avoids recursive calls during compilation.
73 The strategy used when processing DEFINE_DELAY definitions is to create
74 arbitrarily complex expressions and have the optimization simplify them.
76 Once optimization is complete, any required routines and definitions
79 An optimization that is not yet implemented is to hoist the constant
80 expressions entirely out of the routines and definitions that are written.
81 A way to do this is to iterate over all possible combinations of values
82 for constant attributes and generate a set of functions for that given
83 combination. An initialization function would be written that evaluates
84 the attributes and installs the corresponding set of routines and
85 definitions (each would be accessed through a pointer).
87 We use the flags in an RTX as follows:
88 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
89 independent of the insn code.
90 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
91 for the insn code currently being processed (see optimize_attrs).
92 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
95 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), unchanging))
96 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG((RTX), in_struct))
97 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG((RTX), return_val))
100 #define strcmp_check(S1, S2) ((S1) == (S2) \
102 : (gcc_assert (strcmp ((S1), (S2))), 1))
104 #define strcmp_check(S1, S2) ((S1) != (S2))
109 #include "coretypes.h"
115 #include "gensupport.h"
121 /* Flags for make_internal_attr's `special' parameter. */
123 #define ATTR_SPECIAL (1 << 0)
125 static struct obstack obstack1
, obstack2
;
126 static struct obstack
*hash_obstack
= &obstack1
;
127 static struct obstack
*temp_obstack
= &obstack2
;
129 /* enough space to reserve for printing out ints */
130 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
132 /* Define structures used to record attributes and values. */
134 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
135 encountered, we store all the relevant information into a
136 `struct insn_def'. This is done to allow attribute definitions to occur
137 anywhere in the file. */
141 struct insn_def
*next
; /* Next insn in chain. */
142 rtx def
; /* The DEFINE_... */
143 int insn_code
; /* Instruction number. */
144 int insn_index
; /* Expression number in file, for errors. */
145 int lineno
; /* Line number. */
146 int num_alternatives
; /* Number of alternatives. */
147 int vec_idx
; /* Index of attribute vector in `def'. */
150 /* Once everything has been read in, we store in each attribute value a list
151 of insn codes that have that value. Here is the structure used for the
156 struct insn_ent
*next
; /* Next in chain. */
157 struct insn_def
*def
; /* Instruction definition. */
160 /* Each value of an attribute (either constant or computed) is assigned a
161 structure which is used as the listhead of the insns that have that
166 rtx value
; /* Value of attribute. */
167 struct attr_value
*next
; /* Next attribute value in chain. */
168 struct insn_ent
*first_insn
; /* First insn with this value. */
169 int num_insns
; /* Number of insns with this value. */
170 int has_asm_insn
; /* True if this value used for `asm' insns */
173 /* Structure for each attribute. */
177 char *name
; /* Name of attribute. */
178 const char *enum_name
; /* Enum name for DEFINE_ENUM_NAME. */
179 struct attr_desc
*next
; /* Next attribute. */
180 struct attr_value
*first_value
; /* First value of this attribute. */
181 struct attr_value
*default_val
; /* Default value for this attribute. */
182 int lineno
: 24; /* Line number. */
183 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
184 unsigned is_const
: 1; /* Attribute value constant for each run. */
185 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
188 /* Structure for each DEFINE_DELAY. */
192 rtx def
; /* DEFINE_DELAY expression. */
193 struct delay_desc
*next
; /* Next DEFINE_DELAY. */
194 int num
; /* Number of DEFINE_DELAY, starting at 1. */
195 int lineno
; /* Line number. */
198 struct attr_value_list
200 struct attr_value
*av
;
202 struct attr_desc
*attr
;
203 struct attr_value_list
*next
;
206 /* Listheads of above structures. */
208 /* This one is indexed by the first character of the attribute name. */
209 #define MAX_ATTRS_INDEX 256
210 static struct attr_desc
*attrs
[MAX_ATTRS_INDEX
];
211 static struct insn_def
*defs
;
212 static struct delay_desc
*delays
;
213 struct attr_value_list
**insn_code_values
;
215 /* Other variables. */
217 static int insn_code_number
;
218 static int insn_index_number
;
219 static int got_define_asm_attributes
;
220 static int must_extract
;
221 static int must_constrain
;
222 static int address_used
;
223 static int length_used
;
224 static int num_delays
;
225 static int have_annul_true
, have_annul_false
;
226 static int num_insn_ents
;
228 /* Stores, for each insn code, the number of constraint alternatives. */
230 static int *insn_n_alternatives
;
232 /* Stores, for each insn code, a bitmap that has bits on for each possible
235 static int *insn_alternatives
;
237 /* Used to simplify expressions. */
239 static rtx true_rtx
, false_rtx
;
241 /* Used to reduce calls to `strcmp' */
243 static const char *alternative_name
;
244 static const char *length_str
;
245 static const char *delay_type_str
;
246 static const char *delay_1_0_str
;
247 static const char *num_delay_slots_str
;
249 /* Simplify an expression. Only call the routine if there is something to
251 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
252 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
253 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
255 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
257 /* Forward declarations of functions used before their definitions, only. */
258 static char *attr_string (const char *, int);
259 static char *attr_printf (unsigned int, const char *, ...)
261 static rtx
make_numeric_value (int);
262 static struct attr_desc
*find_attr (const char **, int);
263 static rtx
mk_attr_alt (int);
264 static char *next_comma_elt (const char **);
265 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
266 static rtx
copy_boolean (rtx
);
267 static int compares_alternatives_p (rtx
);
268 static void make_internal_attr (const char *, rtx
, int);
269 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
270 static void walk_attr_value (rtx
);
271 static int max_attr_value (rtx
, int*);
272 static int min_attr_value (rtx
, int*);
273 static int or_attr_value (rtx
, int*);
274 static rtx
simplify_test_exp (rtx
, int, int);
275 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
276 static rtx
copy_rtx_unchanging (rtx
);
277 static bool attr_alt_subset_p (rtx
, rtx
);
278 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
279 static void clear_struct_flag (rtx
);
280 static void write_attr_valueq (FILE *, struct attr_desc
*, const char *);
281 static struct attr_value
*find_most_used (struct attr_desc
*);
282 static void write_attr_set (FILE *, struct attr_desc
*, int, rtx
,
283 const char *, const char *, rtx
,
284 int, int, unsigned int);
285 static void write_attr_case (FILE *, struct attr_desc
*,
287 int, const char *, const char *, int, rtx
);
288 static void write_attr_value (FILE *, struct attr_desc
*, rtx
);
289 static void write_upcase (FILE *, const char *);
290 static void write_indent (FILE *, int);
291 static rtx
identity_fn (rtx
);
292 static rtx
zero_fn (rtx
);
293 static rtx
one_fn (rtx
);
294 static rtx
max_fn (rtx
);
295 static rtx
min_fn (rtx
);
297 #define oballoc(T) XOBNEW (hash_obstack, T)
298 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
300 /* This gen* file is unique, in that it writes out multiple files.
302 Before GCC 4.8, insn-attrtab.c was written out containing many large
303 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
304 a parallel build, and even made it impossible to build GCC on machines
305 with relatively small RAM space (PR other/29442). Therefore, the
306 atrribute functions/tables are now written out to three separate
307 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
308 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
309 rest goes to ATTR_FILE_NAME. */
311 static const char *attr_file_name
= NULL
;
312 static const char *dfa_file_name
= NULL
;
313 static const char *latency_file_name
= NULL
;
315 static FILE *attr_file
, *dfa_file
, *latency_file
;
317 /* Hash table for sharing RTL and strings. */
319 /* Each hash table slot is a bucket containing a chain of these structures.
320 Strings are given negative hash codes; RTL expressions are given positive
325 struct attr_hash
*next
; /* Next structure in the bucket. */
326 int hashcode
; /* Hash code of this rtx or string. */
329 char *str
; /* The string (negative hash codes) */
330 rtx rtl
; /* or the RTL recorded here. */
334 /* Now here is the hash table. When recording an RTL, it is added to
335 the slot whose index is the hash code mod the table size. Note
336 that the hash table is used for several kinds of RTL (see attr_rtx)
337 and for strings. While all these live in the same table, they are
338 completely independent, and the hash code is computed differently
341 #define RTL_HASH_SIZE 4093
342 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
344 /* Here is how primitive or already-shared RTL's hash
346 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
348 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
351 attr_hash_add_rtx (int hashcode
, rtx rtl
)
355 h
= XOBNEW (hash_obstack
, struct attr_hash
);
356 h
->hashcode
= hashcode
;
358 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
359 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
362 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
365 attr_hash_add_string (int hashcode
, char *str
)
369 h
= XOBNEW (hash_obstack
, struct attr_hash
);
370 h
->hashcode
= -hashcode
;
372 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
373 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
376 /* Generate an RTL expression, but avoid duplicates.
377 Set the ATTR_PERMANENT_P flag for these permanent objects.
379 In some cases we cannot uniquify; then we return an ordinary
380 impermanent rtx with ATTR_PERMANENT_P clear.
384 rtx attr_rtx (code, [element1, ..., elementn]) */
387 attr_rtx_1 (enum rtx_code code
, va_list p
)
389 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
392 struct obstack
*old_obstack
= rtl_obstack
;
394 /* For each of several cases, search the hash table for an existing entry.
395 Use that entry if one is found; otherwise create a new RTL and add it
398 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
400 rtx arg0
= va_arg (p
, rtx
);
402 /* A permanent object cannot point to impermanent ones. */
403 if (! ATTR_PERMANENT_P (arg0
))
405 rt_val
= rtx_alloc (code
);
406 XEXP (rt_val
, 0) = arg0
;
410 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
411 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
412 if (h
->hashcode
== hashcode
413 && GET_CODE (h
->u
.rtl
) == code
414 && XEXP (h
->u
.rtl
, 0) == arg0
)
419 rtl_obstack
= hash_obstack
;
420 rt_val
= rtx_alloc (code
);
421 XEXP (rt_val
, 0) = arg0
;
424 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
425 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
426 || GET_RTX_CLASS (code
) == RTX_COMPARE
427 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
429 rtx arg0
= va_arg (p
, rtx
);
430 rtx arg1
= va_arg (p
, rtx
);
432 /* A permanent object cannot point to impermanent ones. */
433 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
435 rt_val
= rtx_alloc (code
);
436 XEXP (rt_val
, 0) = arg0
;
437 XEXP (rt_val
, 1) = arg1
;
441 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
442 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
443 if (h
->hashcode
== hashcode
444 && GET_CODE (h
->u
.rtl
) == code
445 && XEXP (h
->u
.rtl
, 0) == arg0
446 && XEXP (h
->u
.rtl
, 1) == arg1
)
451 rtl_obstack
= hash_obstack
;
452 rt_val
= rtx_alloc (code
);
453 XEXP (rt_val
, 0) = arg0
;
454 XEXP (rt_val
, 1) = arg1
;
457 else if (code
== SYMBOL_REF
458 || (GET_RTX_LENGTH (code
) == 1
459 && GET_RTX_FORMAT (code
)[0] == 's'))
461 char *arg0
= va_arg (p
, char *);
463 arg0
= DEF_ATTR_STRING (arg0
);
465 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
466 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
467 if (h
->hashcode
== hashcode
468 && GET_CODE (h
->u
.rtl
) == code
469 && XSTR (h
->u
.rtl
, 0) == arg0
)
474 rtl_obstack
= hash_obstack
;
475 rt_val
= rtx_alloc (code
);
476 XSTR (rt_val
, 0) = arg0
;
477 if (code
== SYMBOL_REF
)
479 X0EXP (rt_val
, 1) = NULL_RTX
;
480 X0EXP (rt_val
, 2) = NULL_RTX
;
484 else if (GET_RTX_LENGTH (code
) == 2
485 && GET_RTX_FORMAT (code
)[0] == 's'
486 && GET_RTX_FORMAT (code
)[1] == 's')
488 char *arg0
= va_arg (p
, char *);
489 char *arg1
= va_arg (p
, char *);
491 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
492 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
493 if (h
->hashcode
== hashcode
494 && GET_CODE (h
->u
.rtl
) == code
495 && XSTR (h
->u
.rtl
, 0) == arg0
496 && XSTR (h
->u
.rtl
, 1) == arg1
)
501 rtl_obstack
= hash_obstack
;
502 rt_val
= rtx_alloc (code
);
503 XSTR (rt_val
, 0) = arg0
;
504 XSTR (rt_val
, 1) = arg1
;
507 else if (code
== CONST_INT
)
509 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
519 int i
; /* Array indices... */
520 const char *fmt
; /* Current rtx's format... */
522 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
524 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
525 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
529 case '0': /* Unused field. */
532 case 'i': /* An integer? */
533 XINT (rt_val
, i
) = va_arg (p
, int);
536 case 'w': /* A wide integer? */
537 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
540 case 's': /* A string? */
541 XSTR (rt_val
, i
) = va_arg (p
, char *);
544 case 'e': /* An expression? */
545 case 'u': /* An insn? Same except when printing. */
546 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
549 case 'E': /* An RTX vector? */
550 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
560 rtl_obstack
= old_obstack
;
561 attr_hash_add_rtx (hashcode
, rt_val
);
562 ATTR_PERMANENT_P (rt_val
) = 1;
567 attr_rtx (enum rtx_code code
, ...)
573 result
= attr_rtx_1 (code
, p
);
578 /* Create a new string printed with the printf line arguments into a space
579 of at most LEN bytes:
581 rtx attr_printf (len, format, [arg1, ..., argn]) */
584 attr_printf (unsigned int len
, const char *fmt
, ...)
591 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
593 vsprintf (str
, fmt
, p
);
596 return DEF_ATTR_STRING (str
);
600 attr_eq (const char *name
, const char *value
)
602 return attr_rtx (EQ_ATTR
, DEF_ATTR_STRING (name
), DEF_ATTR_STRING (value
));
608 return XSTR (make_numeric_value (n
), 0);
611 /* Return a permanent (possibly shared) copy of a string STR (not assumed
612 to be null terminated) with LEN bytes. */
615 attr_string (const char *str
, int len
)
622 /* Compute the hash code. */
623 hashcode
= (len
+ 1) * 613 + (unsigned) str
[0];
624 for (i
= 1; i
< len
; i
+= 2)
625 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
627 hashcode
= -hashcode
;
629 /* Search the table for the string. */
630 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
631 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
632 && !strncmp (h
->u
.str
, str
, len
))
633 return h
->u
.str
; /* <-- return if found. */
635 /* Not found; create a permanent copy and add it to the hash table. */
636 new_str
= XOBNEWVAR (hash_obstack
, char, len
+ 1);
637 memcpy (new_str
, str
, len
);
639 attr_hash_add_string (hashcode
, new_str
);
640 copy_md_ptr_loc (new_str
, str
);
642 return new_str
; /* Return the new string. */
645 /* Check two rtx's for equality of contents,
646 taking advantage of the fact that if both are hashed
647 then they can't be equal unless they are the same object. */
650 attr_equal_p (rtx x
, rtx y
)
652 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
653 && rtx_equal_p (x
, y
)));
656 /* Copy an attribute value expression,
657 descending to all depths, but not copying any
658 permanent hashed subexpressions. */
661 attr_copy_rtx (rtx orig
)
666 const char *format_ptr
;
668 /* No need to copy a permanent object. */
669 if (ATTR_PERMANENT_P (orig
))
672 code
= GET_CODE (orig
);
691 copy
= rtx_alloc (code
);
692 PUT_MODE (copy
, GET_MODE (orig
));
693 ATTR_IND_SIMPLIFIED_P (copy
) = ATTR_IND_SIMPLIFIED_P (orig
);
694 ATTR_CURR_SIMPLIFIED_P (copy
) = ATTR_CURR_SIMPLIFIED_P (orig
);
695 ATTR_PERMANENT_P (copy
) = ATTR_PERMANENT_P (orig
);
697 format_ptr
= GET_RTX_FORMAT (GET_CODE (copy
));
699 for (i
= 0; i
< GET_RTX_LENGTH (GET_CODE (copy
)); i
++)
701 switch (*format_ptr
++)
704 XEXP (copy
, i
) = XEXP (orig
, i
);
705 if (XEXP (orig
, i
) != NULL
)
706 XEXP (copy
, i
) = attr_copy_rtx (XEXP (orig
, i
));
711 XVEC (copy
, i
) = XVEC (orig
, i
);
712 if (XVEC (orig
, i
) != NULL
)
714 XVEC (copy
, i
) = rtvec_alloc (XVECLEN (orig
, i
));
715 for (j
= 0; j
< XVECLEN (copy
, i
); j
++)
716 XVECEXP (copy
, i
, j
) = attr_copy_rtx (XVECEXP (orig
, i
, j
));
722 XINT (copy
, i
) = XINT (orig
, i
);
726 XWINT (copy
, i
) = XWINT (orig
, i
);
731 XSTR (copy
, i
) = XSTR (orig
, i
);
741 /* Given a test expression for an attribute, ensure it is validly formed.
742 IS_CONST indicates whether the expression is constant for each compiler
743 run (a constant expression may not test any particular insn).
745 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
746 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
747 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
749 Update the string address in EQ_ATTR expression to be the same used
750 in the attribute (or `alternative_name') to speed up subsequent
751 `find_attr' calls and eliminate most `strcmp' calls.
753 Return the new expression, if any. */
756 check_attr_test (rtx exp
, int is_const
, int lineno
)
758 struct attr_desc
*attr
;
759 struct attr_value
*av
;
760 const char *name_ptr
, *p
;
763 switch (GET_CODE (exp
))
766 /* Handle negation test. */
767 if (XSTR (exp
, 1)[0] == '!')
768 return check_attr_test (attr_rtx (NOT
,
769 attr_eq (XSTR (exp
, 0),
773 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
775 attr
= find_attr (&XSTR (exp
, 0), 0);
778 if (! strcmp (XSTR (exp
, 0), "alternative"))
779 return mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
781 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp
, 0));
784 if (is_const
&& ! attr
->is_const
)
785 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR",
788 /* Copy this just to make it permanent,
789 so expressions using it can be permanent too. */
790 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
792 /* It shouldn't be possible to simplify the value given to a
793 constant attribute, so don't expand this until it's time to
794 write the test expression. */
796 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
798 if (attr
->is_numeric
)
800 for (p
= XSTR (exp
, 1); *p
; p
++)
802 fatal ("attribute `%s' takes only numeric values",
807 for (av
= attr
->first_value
; av
; av
= av
->next
)
808 if (GET_CODE (av
->value
) == CONST_STRING
809 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
813 fatal ("unknown value `%s' for `%s' attribute",
814 XSTR (exp
, 1), XSTR (exp
, 0));
819 if (! strcmp (XSTR (exp
, 0), "alternative"))
823 name_ptr
= XSTR (exp
, 1);
824 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
825 set
|= 1 << atoi (p
);
827 return mk_attr_alt (set
);
831 /* Make an IOR tree of the possible values. */
833 name_ptr
= XSTR (exp
, 1);
834 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
836 newexp
= attr_eq (XSTR (exp
, 0), p
);
837 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
840 return check_attr_test (orexp
, is_const
, lineno
);
849 /* Either TRUE or FALSE. */
857 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
858 XEXP (exp
, 1) = check_attr_test (XEXP (exp
, 1), is_const
, lineno
);
862 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0), is_const
, lineno
);
866 exp
= attr_rtx (MATCH_TEST
, XSTR (exp
, 0));
867 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
872 fatal ("RTL operator \"%s\" not valid in constant attribute test",
873 GET_RTX_NAME (GET_CODE (exp
)));
874 /* These cases can't be simplified. */
875 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
878 case LE
: case LT
: case GT
: case GE
:
879 case LEU
: case LTU
: case GTU
: case GEU
:
881 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
882 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
883 exp
= attr_rtx (GET_CODE (exp
),
884 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
885 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
886 /* These cases can't be simplified. */
887 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
893 /* These cases are valid for constant attributes, but can't be
895 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
896 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
900 fatal ("RTL operator \"%s\" not valid in attribute test",
901 GET_RTX_NAME (GET_CODE (exp
)));
907 /* Given an expression, ensure that it is validly formed and that all named
908 attribute values are valid for the given attribute. Issue a fatal error
909 if not. If no attribute is specified, assume a numeric attribute.
911 Return a perhaps modified replacement expression for the value. */
914 check_attr_value (rtx exp
, struct attr_desc
*attr
)
916 struct attr_value
*av
;
920 switch (GET_CODE (exp
))
923 if (attr
&& ! attr
->is_numeric
)
925 error_with_line (attr
->lineno
,
926 "CONST_INT not valid for non-numeric attribute %s",
931 if (INTVAL (exp
) < 0)
933 error_with_line (attr
->lineno
,
934 "negative numeric value specified for attribute %s",
941 if (! strcmp (XSTR (exp
, 0), "*"))
944 if (attr
== 0 || attr
->is_numeric
)
950 error_with_line (attr
? attr
->lineno
: 0,
951 "non-numeric value for numeric attribute %s",
952 attr
? attr
->name
: "internal");
958 for (av
= attr
->first_value
; av
; av
= av
->next
)
959 if (GET_CODE (av
->value
) == CONST_STRING
960 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
964 error_with_line (attr
->lineno
,
965 "unknown value `%s' for `%s' attribute",
966 XSTR (exp
, 0), attr
? attr
->name
: "internal");
970 XEXP (exp
, 0) = check_attr_test (XEXP (exp
, 0),
971 attr
? attr
->is_const
: 0,
972 attr
? attr
->lineno
: 0);
973 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
974 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
982 if (attr
&& !attr
->is_numeric
)
984 error_with_line (attr
->lineno
,
985 "invalid operation `%s' for non-numeric"
986 " attribute value", GET_RTX_NAME (GET_CODE (exp
)));
993 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
994 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1003 XEXP (exp
, 0) = check_attr_value (XEXP (exp
, 0), attr
);
1007 if (XVECLEN (exp
, 0) % 2 != 0)
1009 error_with_line (attr
->lineno
,
1010 "first operand of COND must have even length");
1014 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1016 XVECEXP (exp
, 0, i
) = check_attr_test (XVECEXP (exp
, 0, i
),
1017 attr
? attr
->is_const
: 0,
1018 attr
? attr
->lineno
: 0);
1019 XVECEXP (exp
, 0, i
+ 1)
1020 = check_attr_value (XVECEXP (exp
, 0, i
+ 1), attr
);
1023 XEXP (exp
, 1) = check_attr_value (XEXP (exp
, 1), attr
);
1028 struct attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
1030 error_with_line (attr
? attr
->lineno
: 0,
1031 "unknown attribute `%s' in ATTR",
1033 else if (attr
&& attr
->is_const
&& ! attr2
->is_const
)
1034 error_with_line (attr
->lineno
,
1035 "non-constant attribute `%s' referenced from `%s'",
1036 XSTR (exp
, 0), attr
->name
);
1038 && attr
->is_numeric
!= attr2
->is_numeric
)
1039 error_with_line (attr
->lineno
,
1040 "numeric attribute mismatch calling `%s' from `%s'",
1041 XSTR (exp
, 0), attr
->name
);
1046 /* A constant SYMBOL_REF is valid as a constant attribute test and
1047 is expanded later by make_canonical into a COND. In a non-constant
1048 attribute test, it is left be. */
1049 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
1052 error_with_line (attr
? attr
->lineno
: 0,
1053 "invalid operation `%s' for attribute value",
1054 GET_RTX_NAME (GET_CODE (exp
)));
1061 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
1062 It becomes a COND with each test being (eq_attr "alternative" "n") */
1065 convert_set_attr_alternative (rtx exp
, struct insn_def
*id
)
1067 int num_alt
= id
->num_alternatives
;
1071 if (XVECLEN (exp
, 1) != num_alt
)
1073 error_with_line (id
->lineno
,
1074 "bad number of entries in SET_ATTR_ALTERNATIVE");
1078 /* Make a COND with all tests but the last. Select the last value via the
1080 condexp
= rtx_alloc (COND
);
1081 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1083 for (i
= 0; i
< num_alt
- 1; i
++)
1086 p
= attr_numeral (i
);
1088 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1089 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1092 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1094 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1097 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1098 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1101 convert_set_attr (rtx exp
, struct insn_def
*id
)
1104 const char *name_ptr
;
1108 /* See how many alternative specified. */
1109 n
= n_comma_elts (XSTR (exp
, 1));
1111 return attr_rtx (SET
,
1112 attr_rtx (ATTR
, XSTR (exp
, 0)),
1113 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1115 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1116 XSTR (newexp
, 0) = XSTR (exp
, 0);
1117 XVEC (newexp
, 1) = rtvec_alloc (n
);
1119 /* Process each comma-separated name. */
1120 name_ptr
= XSTR (exp
, 1);
1122 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1123 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1125 return convert_set_attr_alternative (newexp
, id
);
1128 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1129 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1135 struct insn_def
*id
;
1136 struct attr_desc
*attr
;
1140 for (id
= defs
; id
; id
= id
->next
)
1142 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1145 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1147 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1148 switch (GET_CODE (value
))
1151 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1153 error_with_line (id
->lineno
, "bad attribute set");
1158 case SET_ATTR_ALTERNATIVE
:
1159 value
= convert_set_attr_alternative (value
, id
);
1163 value
= convert_set_attr (value
, id
);
1167 error_with_line (id
->lineno
, "invalid attribute code %s",
1168 GET_RTX_NAME (GET_CODE (value
)));
1171 if (value
== NULL_RTX
)
1174 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1176 error_with_line (id
->lineno
, "unknown attribute %s",
1177 XSTR (XEXP (value
, 0), 0));
1181 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1182 XEXP (value
, 1) = check_attr_value (XEXP (value
, 1), attr
);
1187 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1188 expressions by converting them into a COND. This removes cases from this
1189 program. Also, replace an attribute value of "*" with the default attribute
1193 make_canonical (struct attr_desc
*attr
, rtx exp
)
1198 switch (GET_CODE (exp
))
1201 exp
= make_numeric_value (INTVAL (exp
));
1205 if (! strcmp (XSTR (exp
, 0), "*"))
1207 if (attr
== 0 || attr
->default_val
== 0)
1208 fatal ("(attr_value \"*\") used in invalid context");
1209 exp
= attr
->default_val
->value
;
1212 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1217 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1219 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1220 This makes the COND something that won't be considered an arbitrary
1221 expression by walk_attr_value. */
1222 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1223 exp
= check_attr_value (exp
, attr
);
1227 newexp
= rtx_alloc (COND
);
1228 XVEC (newexp
, 0) = rtvec_alloc (2);
1229 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1230 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1232 XEXP (newexp
, 1) = XEXP (exp
, 2);
1235 /* Fall through to COND case since this is now a COND. */
1242 /* First, check for degenerate COND. */
1243 if (XVECLEN (exp
, 0) == 0)
1244 return make_canonical (attr
, XEXP (exp
, 1));
1245 defval
= XEXP (exp
, 1) = make_canonical (attr
, XEXP (exp
, 1));
1247 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1249 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1250 XVECEXP (exp
, 0, i
+ 1)
1251 = make_canonical (attr
, XVECEXP (exp
, 0, i
+ 1));
1252 if (! rtx_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1268 copy_boolean (rtx exp
)
1270 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1271 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1272 copy_boolean (XEXP (exp
, 1)));
1273 if (GET_CODE (exp
) == MATCH_OPERAND
)
1275 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1276 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1278 else if (GET_CODE (exp
) == EQ_ATTR
)
1280 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1281 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1287 /* Given a value and an attribute description, return a `struct attr_value *'
1288 that represents that value. This is either an existing structure, if the
1289 value has been previously encountered, or a newly-created structure.
1291 `insn_code' is the code of an insn whose attribute has the specified
1292 value (-2 if not processing an insn). We ensure that all insns for
1293 a given value have the same number of alternatives if the value checks
1296 static struct attr_value
*
1297 get_attr_value (rtx value
, struct attr_desc
*attr
, int insn_code
)
1299 struct attr_value
*av
;
1302 value
= make_canonical (attr
, value
);
1303 if (compares_alternatives_p (value
))
1305 if (insn_code
< 0 || insn_alternatives
== NULL
)
1306 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
1308 num_alt
= insn_alternatives
[insn_code
];
1311 for (av
= attr
->first_value
; av
; av
= av
->next
)
1312 if (rtx_equal_p (value
, av
->value
)
1313 && (num_alt
== 0 || av
->first_insn
== NULL
1314 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1317 av
= oballoc (struct attr_value
);
1319 av
->next
= attr
->first_value
;
1320 attr
->first_value
= av
;
1321 av
->first_insn
= NULL
;
1323 av
->has_asm_insn
= 0;
1328 /* After all DEFINE_DELAYs have been read in, create internal attributes
1329 to generate the required routines.
1331 First, we compute the number of delay slots for each insn (as a COND of
1332 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1333 delay type is specified, we compute a similar function giving the
1334 DEFINE_DELAY ordinal for each insn.
1336 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1337 tells whether a given insn can be in that delay slot.
1339 Normal attribute filling and optimization expands these to contain the
1340 information needed to handle delay slots. */
1343 expand_delays (void)
1345 struct delay_desc
*delay
;
1351 /* First, generate data for `num_delay_slots' function. */
1353 condexp
= rtx_alloc (COND
);
1354 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1355 XEXP (condexp
, 1) = make_numeric_value (0);
1357 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1359 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1360 XVECEXP (condexp
, 0, i
+ 1)
1361 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1364 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1366 /* If more than one delay type, do the same for computing the delay type. */
1369 condexp
= rtx_alloc (COND
);
1370 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1371 XEXP (condexp
, 1) = make_numeric_value (0);
1373 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1375 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1376 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1379 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1382 /* For each delay possibility and delay slot, compute an eligibility
1383 attribute for non-annulled insns and for each type of annulled (annul
1384 if true and annul if false). */
1385 for (delay
= delays
; delay
; delay
= delay
->next
)
1387 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1389 condexp
= XVECEXP (delay
->def
, 1, i
);
1391 condexp
= false_rtx
;
1392 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1393 make_numeric_value (1), make_numeric_value (0));
1395 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1396 "*delay_%d_%d", delay
->num
, i
/ 3);
1397 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1399 if (have_annul_true
)
1401 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1402 if (condexp
== 0) condexp
= false_rtx
;
1403 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1404 make_numeric_value (1),
1405 make_numeric_value (0));
1406 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1407 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1408 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1411 if (have_annul_false
)
1413 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1414 if (condexp
== 0) condexp
= false_rtx
;
1415 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1416 make_numeric_value (1),
1417 make_numeric_value (0));
1418 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1419 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1420 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1426 /* Once all attributes and insns have been read and checked, we construct for
1427 each attribute value a list of all the insns that have that value for
1431 fill_attr (struct attr_desc
*attr
)
1433 struct attr_value
*av
;
1434 struct insn_ent
*ie
;
1435 struct insn_def
*id
;
1439 /* Don't fill constant attributes. The value is independent of
1440 any particular insn. */
1444 for (id
= defs
; id
; id
= id
->next
)
1446 /* If no value is specified for this insn for this attribute, use the
1449 if (XVEC (id
->def
, id
->vec_idx
))
1450 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1451 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1453 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1456 av
= attr
->default_val
;
1458 av
= get_attr_value (value
, attr
, id
->insn_code
);
1460 ie
= oballoc (struct insn_ent
);
1462 insert_insn_ent (av
, ie
);
1466 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1467 test that checks relative positions of insns (uses MATCH_DUP or PC).
1468 If so, replace it with what is obtained by passing the expression to
1469 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1470 recursively on each value (including the default value). Otherwise,
1471 return the value returned by NO_ADDRESS_FN applied to EXP. */
1474 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1475 rtx (*address_fn
) (rtx
))
1480 if (GET_CODE (exp
) == COND
)
1482 /* See if any tests use addresses. */
1484 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1485 walk_attr_value (XVECEXP (exp
, 0, i
));
1488 return (*address_fn
) (exp
);
1490 /* Make a new copy of this COND, replacing each element. */
1491 newexp
= rtx_alloc (COND
);
1492 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1493 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1495 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1496 XVECEXP (newexp
, 0, i
+ 1)
1497 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1498 no_address_fn
, address_fn
);
1501 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1502 no_address_fn
, address_fn
);
1507 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1510 walk_attr_value (XEXP (exp
, 0));
1512 return (*address_fn
) (exp
);
1514 return attr_rtx (IF_THEN_ELSE
,
1515 substitute_address (XEXP (exp
, 0),
1516 no_address_fn
, address_fn
),
1517 substitute_address (XEXP (exp
, 1),
1518 no_address_fn
, address_fn
),
1519 substitute_address (XEXP (exp
, 2),
1520 no_address_fn
, address_fn
));
1523 return (*no_address_fn
) (exp
);
1526 /* Make new attributes from the `length' attribute. The following are made,
1527 each corresponding to a function called from `shorten_branches' or
1530 *insn_default_length This is the length of the insn to be returned
1531 by `get_attr_length' before `shorten_branches'
1532 has been called. In each case where the length
1533 depends on relative addresses, the largest
1534 possible is used. This routine is also used
1535 to compute the initial size of the insn.
1537 *insn_variable_length_p This returns 1 if the insn's length depends
1538 on relative addresses, zero otherwise.
1540 *insn_current_length This is only called when it is known that the
1541 insn has a variable length and returns the
1542 current length, based on relative addresses.
1546 make_length_attrs (void)
1548 static const char *new_names
[] =
1550 "*insn_default_length",
1552 "*insn_variable_length_p",
1553 "*insn_current_length"
1555 static rtx (*const no_address_fn
[]) (rtx
)
1556 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1557 static rtx (*const address_fn
[]) (rtx
)
1558 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1560 struct attr_desc
*length_attr
, *new_attr
;
1561 struct attr_value
*av
, *new_av
;
1562 struct insn_ent
*ie
, *new_ie
;
1564 /* See if length attribute is defined. If so, it must be numeric. Make
1565 it special so we don't output anything for it. */
1566 length_attr
= find_attr (&length_str
, 0);
1567 if (length_attr
== 0)
1570 if (! length_attr
->is_numeric
)
1571 fatal ("length attribute must be numeric");
1573 length_attr
->is_const
= 0;
1574 length_attr
->is_special
= 1;
1576 /* Make each new attribute, in turn. */
1577 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1579 make_internal_attr (new_names
[i
],
1580 substitute_address (length_attr
->default_val
->value
,
1581 no_address_fn
[i
], address_fn
[i
]),
1583 new_attr
= find_attr (&new_names
[i
], 0);
1584 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1585 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1587 new_av
= get_attr_value (substitute_address (av
->value
,
1590 new_attr
, ie
->def
->insn_code
);
1591 new_ie
= oballoc (struct insn_ent
);
1592 new_ie
->def
= ie
->def
;
1593 insert_insn_ent (new_av
, new_ie
);
1598 /* Utility functions called from above routine. */
1601 identity_fn (rtx exp
)
1607 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1609 return make_numeric_value (0);
1613 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1615 return make_numeric_value (1);
1622 return make_numeric_value (max_attr_value (exp
, &unknown
));
1629 return make_numeric_value (min_attr_value (exp
, &unknown
));
1633 write_length_unit_log (FILE *outf
)
1635 struct attr_desc
*length_attr
= find_attr (&length_str
, 0);
1636 struct attr_value
*av
;
1637 struct insn_ent
*ie
;
1638 unsigned int length_unit_log
, length_or
;
1641 if (length_attr
== 0)
1643 length_or
= or_attr_value (length_attr
->default_val
->value
, &unknown
);
1644 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1645 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1646 length_or
|= or_attr_value (av
->value
, &unknown
);
1649 length_unit_log
= 0;
1652 length_or
= ~length_or
;
1653 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1656 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1659 /* Compute approximate cost of the expression. Used to decide whether
1660 expression is cheap enough for inline. */
1662 attr_rtx_cost (rtx x
)
1668 code
= GET_CODE (x
);
1681 /* Alternatives don't result into function call. */
1682 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1689 const char *fmt
= GET_RTX_FORMAT (code
);
1690 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1696 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1697 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1700 cost
+= attr_rtx_cost (XEXP (x
, i
));
1710 /* Take a COND expression and see if any of the conditions in it can be
1711 simplified. If any are known true or known false for the particular insn
1712 code, the COND can be further simplified.
1714 Also call ourselves on any COND operations that are values of this COND.
1716 We do not modify EXP; rather, we make and return a new rtx. */
1719 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1722 /* We store the desired contents here,
1723 then build a new expression if they don't match EXP. */
1724 rtx defval
= XEXP (exp
, 1);
1725 rtx new_defval
= XEXP (exp
, 1);
1726 int len
= XVECLEN (exp
, 0);
1727 rtx
*tests
= XNEWVEC (rtx
, len
);
1731 /* This lets us free all storage allocated below, if appropriate. */
1732 obstack_finish (rtl_obstack
);
1734 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1736 /* See if default value needs simplification. */
1737 if (GET_CODE (defval
) == COND
)
1738 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1740 /* Simplify the subexpressions, and see what tests we can get rid of. */
1742 for (i
= 0; i
< len
; i
+= 2)
1744 rtx newtest
, newval
;
1746 /* Simplify this test. */
1747 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1750 newval
= tests
[i
+ 1];
1751 /* See if this value may need simplification. */
1752 if (GET_CODE (newval
) == COND
)
1753 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1755 /* Look for ways to delete or combine this test. */
1756 if (newtest
== true_rtx
)
1758 /* If test is true, make this value the default
1759 and discard this + any following tests. */
1761 defval
= tests
[i
+ 1];
1762 new_defval
= newval
;
1765 else if (newtest
== false_rtx
)
1767 /* If test is false, discard it and its value. */
1768 for (j
= i
; j
< len
- 2; j
++)
1769 tests
[j
] = tests
[j
+ 2];
1774 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1776 /* If this value and the value for the prev test are the same,
1780 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1781 insn_code
, insn_index
);
1783 /* Delete this test/value. */
1784 for (j
= i
; j
< len
- 2; j
++)
1785 tests
[j
] = tests
[j
+ 2];
1791 tests
[i
+ 1] = newval
;
1794 /* If the last test in a COND has the same value
1795 as the default value, that test isn't needed. */
1797 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1800 /* See if we changed anything. */
1801 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1804 for (i
= 0; i
< len
; i
++)
1805 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1813 if (GET_CODE (defval
) == COND
)
1814 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1822 rtx newexp
= rtx_alloc (COND
);
1824 XVEC (newexp
, 0) = rtvec_alloc (len
);
1825 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1826 XEXP (newexp
, 1) = new_defval
;
1833 /* Remove an insn entry from an attribute value. */
1836 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1838 struct insn_ent
*previe
;
1840 if (av
->first_insn
== ie
)
1841 av
->first_insn
= ie
->next
;
1844 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1846 previe
->next
= ie
->next
;
1850 if (ie
->def
->insn_code
== -1)
1851 av
->has_asm_insn
= 0;
1856 /* Insert an insn entry in an attribute value list. */
1859 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1861 ie
->next
= av
->first_insn
;
1862 av
->first_insn
= ie
;
1864 if (ie
->def
->insn_code
== -1)
1865 av
->has_asm_insn
= 1;
1870 /* This is a utility routine to take an expression that is a tree of either
1871 AND or IOR expressions and insert a new term. The new term will be
1872 inserted at the right side of the first node whose code does not match
1873 the root. A new node will be created with the root's code. Its left
1874 side will be the old right side and its right side will be the new
1877 If the `term' is itself a tree, all its leaves will be inserted. */
1880 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1884 /* Avoid consing in some special cases. */
1885 if (code
== AND
&& term
== true_rtx
)
1887 if (code
== AND
&& term
== false_rtx
)
1889 if (code
== AND
&& exp
== true_rtx
)
1891 if (code
== AND
&& exp
== false_rtx
)
1893 if (code
== IOR
&& term
== true_rtx
)
1895 if (code
== IOR
&& term
== false_rtx
)
1897 if (code
== IOR
&& exp
== true_rtx
)
1899 if (code
== IOR
&& exp
== false_rtx
)
1901 if (attr_equal_p (exp
, term
))
1904 if (GET_CODE (term
) == code
)
1906 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1907 insn_code
, insn_index
);
1908 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1909 insn_code
, insn_index
);
1914 if (GET_CODE (exp
) == code
)
1916 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1917 term
, insn_code
, insn_index
);
1918 if (new_rtx
!= XEXP (exp
, 1))
1919 /* Make a copy of this expression and call recursively. */
1920 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1926 /* Insert the new term. */
1927 newexp
= attr_rtx (code
, exp
, term
);
1930 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1933 /* If we have an expression which AND's a bunch of
1934 (not (eq_attrq "alternative" "n"))
1935 terms, we may have covered all or all but one of the possible alternatives.
1936 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1938 This routine is passed an expression and either AND or IOR. It returns a
1939 bitmask indicating which alternatives are mentioned within EXP. */
1942 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1945 if (GET_CODE (exp
) == code
)
1946 return compute_alternative_mask (XEXP (exp
, 0), code
)
1947 | compute_alternative_mask (XEXP (exp
, 1), code
);
1949 else if (code
== AND
&& GET_CODE (exp
) == NOT
1950 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1951 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1952 string
= XSTR (XEXP (exp
, 0), 1);
1954 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1955 && XSTR (exp
, 0) == alternative_name
)
1956 string
= XSTR (exp
, 1);
1958 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1960 if (code
== AND
&& XINT (exp
, 1))
1961 return XINT (exp
, 0);
1963 if (code
== IOR
&& !XINT (exp
, 1))
1964 return XINT (exp
, 0);
1972 return 1 << (string
[0] - '0');
1973 return 1 << atoi (string
);
1976 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1977 attribute with the value represented by that bit. */
1980 make_alternative_compare (int mask
)
1982 return mk_attr_alt (mask
);
1985 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1986 of "attr" for this insn code. From that value, we can compute a test
1987 showing when the EQ_ATTR will be true. This routine performs that
1988 computation. If a test condition involves an address, we leave the EQ_ATTR
1989 intact because addresses are only valid for the `length' attribute.
1991 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1992 it refers. VALUE is the value of that attribute for the insn
1993 corresponding to INSN_CODE and INSN_INDEX. */
1996 evaluate_eq_attr (rtx exp
, struct attr_desc
*attr
, rtx value
,
1997 int insn_code
, int insn_index
)
2004 while (GET_CODE (value
) == ATTR
)
2006 struct attr_value
*av
= NULL
;
2008 attr
= find_attr (&XSTR (value
, 0), 0);
2010 if (insn_code_values
)
2012 struct attr_value_list
*iv
;
2013 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2014 if (iv
->attr
== attr
)
2022 struct insn_ent
*ie
;
2023 for (av
= attr
->first_value
; av
; av
= av
->next
)
2024 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2025 if (ie
->def
->insn_code
== insn_code
)
2035 switch (GET_CODE (value
))
2038 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
2049 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
2050 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
2051 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
2052 for (p
= string
; *p
; p
++)
2055 newexp
= attr_rtx (EQ
, value
,
2056 attr_rtx (SYMBOL_REF
,
2057 DEF_ATTR_STRING (string
)));
2062 /* We construct an IOR of all the cases for which the
2063 requested attribute value is present. Since we start with
2064 FALSE, if it is not present, FALSE will be returned.
2066 Each case is the AND of the NOT's of the previous conditions with the
2067 current condition; in the default case the current condition is TRUE.
2069 For each possible COND value, call ourselves recursively.
2071 The extra TRUE and FALSE expressions will be eliminated by another
2072 call to the simplification routine. */
2077 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2079 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2080 insn_code
, insn_index
);
2082 right
= insert_right_side (AND
, andexp
, this_cond
,
2083 insn_code
, insn_index
);
2084 right
= insert_right_side (AND
, right
,
2085 evaluate_eq_attr (exp
, attr
,
2088 insn_code
, insn_index
),
2089 insn_code
, insn_index
);
2090 orexp
= insert_right_side (IOR
, orexp
, right
,
2091 insn_code
, insn_index
);
2093 /* Add this condition into the AND expression. */
2094 newexp
= attr_rtx (NOT
, this_cond
);
2095 andexp
= insert_right_side (AND
, andexp
, newexp
,
2096 insn_code
, insn_index
);
2099 /* Handle the default case. */
2100 right
= insert_right_side (AND
, andexp
,
2101 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2102 insn_code
, insn_index
),
2103 insn_code
, insn_index
);
2104 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2111 /* If uses an address, must return original expression. But set the
2112 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2115 walk_attr_value (newexp
);
2119 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2120 return copy_rtx_unchanging (exp
);
2127 /* This routine is called when an AND of a term with a tree of AND's is
2128 encountered. If the term or its complement is present in the tree, it
2129 can be replaced with TRUE or FALSE, respectively.
2131 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2132 be true and hence are complementary.
2134 There is one special case: If we see
2135 (and (not (eq_attr "att" "v1"))
2136 (eq_attr "att" "v2"))
2137 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2138 replace the term, not anything in the AND tree. So we pass a pointer to
2142 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2147 int left_eliminates_term
, right_eliminates_term
;
2149 if (GET_CODE (exp
) == AND
)
2151 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2152 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2153 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2155 newexp
= attr_rtx (AND
, left
, right
);
2157 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2161 else if (GET_CODE (exp
) == IOR
)
2163 /* For the IOR case, we do the same as above, except that we can
2164 only eliminate `term' if both sides of the IOR would do so. */
2166 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2167 left_eliminates_term
= (temp
== true_rtx
);
2170 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2171 right_eliminates_term
= (temp
== true_rtx
);
2173 if (left_eliminates_term
&& right_eliminates_term
)
2176 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2178 newexp
= attr_rtx (IOR
, left
, right
);
2180 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2184 /* Check for simplifications. Do some extra checking here since this
2185 routine is called so many times. */
2190 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2193 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2196 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2198 if (attr_alt_subset_p (*pterm
, exp
))
2201 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2204 if (attr_alt_subset_p (exp
, *pterm
))
2210 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2212 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2215 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2221 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2222 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2224 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2227 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2233 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2234 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2236 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2239 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2245 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2247 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2251 else if (GET_CODE (exp
) == NOT
)
2253 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2257 else if (GET_CODE (*pterm
) == NOT
)
2259 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2263 else if (attr_equal_p (exp
, *pterm
))
2269 /* Similar to `simplify_and_tree', but for IOR trees. */
2272 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2277 int left_eliminates_term
, right_eliminates_term
;
2279 if (GET_CODE (exp
) == IOR
)
2281 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2282 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2283 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2285 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2287 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2291 else if (GET_CODE (exp
) == AND
)
2293 /* For the AND case, we do the same as above, except that we can
2294 only eliminate `term' if both sides of the AND would do so. */
2296 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2297 left_eliminates_term
= (temp
== false_rtx
);
2300 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2301 right_eliminates_term
= (temp
== false_rtx
);
2303 if (left_eliminates_term
&& right_eliminates_term
)
2306 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2308 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2310 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2314 if (attr_equal_p (exp
, *pterm
))
2317 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2320 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2323 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2324 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2325 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2328 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2329 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2330 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2336 /* Simplify test expression and use temporary obstack in order to avoid
2337 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2338 and avoid unnecessary copying if possible. */
2341 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2344 struct obstack
*old
;
2345 if (ATTR_IND_SIMPLIFIED_P (exp
))
2348 rtl_obstack
= temp_obstack
;
2349 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2351 if (x
== exp
|| rtl_obstack
== temp_obstack
)
2353 return attr_copy_rtx (x
);
2356 /* Returns true if S1 is a subset of S2. */
2359 attr_alt_subset_p (rtx s1
, rtx s2
)
2361 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2364 return !(XINT (s1
, 0) &~ XINT (s2
, 0));
2367 return !(XINT (s1
, 0) & XINT (s2
, 0));
2373 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2380 /* Returns true if S1 is a subset of complement of S2. */
2383 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2385 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2388 return !(XINT (s1
, 0) & XINT (s2
, 0));
2391 return !(XINT (s1
, 0) & ~XINT (s2
, 0));
2394 return !(XINT (s2
, 0) &~ XINT (s1
, 0));
2404 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2407 attr_alt_intersection (rtx s1
, rtx s2
)
2409 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2411 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2414 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2417 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2420 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2423 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2428 XINT (result
, 1) = XINT (s1
, 1) & XINT (s2
, 1);
2433 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2436 attr_alt_union (rtx s1
, rtx s2
)
2438 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2440 switch ((XINT (s1
, 1) << 1) | XINT (s2
, 1))
2443 XINT (result
, 0) = XINT (s1
, 0) | XINT (s2
, 0);
2446 XINT (result
, 0) = XINT (s2
, 0) & ~XINT (s1
, 0);
2449 XINT (result
, 0) = XINT (s1
, 0) & ~XINT (s2
, 0);
2452 XINT (result
, 0) = XINT (s1
, 0) & XINT (s2
, 0);
2458 XINT (result
, 1) = XINT (s1
, 1) | XINT (s2
, 1);
2462 /* Return EQ_ATTR_ALT expression representing complement of S. */
2465 attr_alt_complement (rtx s
)
2467 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2469 XINT (result
, 0) = XINT (s
, 0);
2470 XINT (result
, 1) = 1 - XINT (s
, 1);
2475 /* Return EQ_ATTR_ALT expression representing set containing elements set
2481 rtx result
= rtx_alloc (EQ_ATTR_ALT
);
2483 XINT (result
, 0) = e
;
2484 XINT (result
, 1) = 0;
2489 /* Given an expression, see if it can be simplified for a particular insn
2490 code based on the values of other attributes being tested. This can
2491 eliminate nested get_attr_... calls.
2493 Note that if an endless recursion is specified in the patterns, the
2494 optimization will loop. However, it will do so in precisely the cases where
2495 an infinite recursion loop could occur during compilation. It's better that
2499 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2502 struct attr_desc
*attr
;
2503 struct attr_value
*av
;
2504 struct insn_ent
*ie
;
2505 struct attr_value_list
*iv
;
2508 bool left_alt
, right_alt
;
2510 /* Don't re-simplify something we already simplified. */
2511 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2514 switch (GET_CODE (exp
))
2517 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2518 if (left
== false_rtx
)
2520 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2521 if (right
== false_rtx
)
2524 if (GET_CODE (left
) == EQ_ATTR_ALT
2525 && GET_CODE (right
) == EQ_ATTR_ALT
)
2527 exp
= attr_alt_intersection (left
, right
);
2528 return simplify_test_exp (exp
, insn_code
, insn_index
);
2531 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2532 present on both sides, apply the distributive law since this will
2533 yield simplifications. */
2534 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2535 && compute_alternative_mask (left
, IOR
)
2536 && compute_alternative_mask (right
, IOR
))
2538 if (GET_CODE (left
) == IOR
)
2545 newexp
= attr_rtx (IOR
,
2546 attr_rtx (AND
, left
, XEXP (right
, 0)),
2547 attr_rtx (AND
, left
, XEXP (right
, 1)));
2549 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2552 /* Try with the term on both sides. */
2553 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2554 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2555 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2557 if (left
== false_rtx
|| right
== false_rtx
)
2559 else if (left
== true_rtx
)
2563 else if (right
== true_rtx
)
2567 /* See if all or all but one of the insn's alternatives are specified
2568 in this tree. Optimize if so. */
2570 if (GET_CODE (left
) == NOT
)
2571 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2572 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2574 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2577 if (GET_CODE (right
) == NOT
)
2578 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2579 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2581 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2582 && XINT (right
, 1));
2585 && (GET_CODE (left
) == AND
2587 || GET_CODE (right
) == AND
2590 i
= compute_alternative_mask (exp
, AND
);
2591 if (i
& ~insn_alternatives
[insn_code
])
2592 fatal ("invalid alternative specified for pattern number %d",
2595 /* If all alternatives are excluded, this is false. */
2596 i
^= insn_alternatives
[insn_code
];
2599 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2601 /* If just one excluded, AND a comparison with that one to the
2602 front of the tree. The others will be eliminated by
2603 optimization. We do not want to do this if the insn has one
2604 alternative and we have tested none of them! */
2605 left
= make_alternative_compare (i
);
2606 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2607 newexp
= attr_rtx (AND
, left
, right
);
2609 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2613 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2615 newexp
= attr_rtx (AND
, left
, right
);
2616 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2621 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2622 if (left
== true_rtx
)
2624 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2625 if (right
== true_rtx
)
2628 if (GET_CODE (left
) == EQ_ATTR_ALT
2629 && GET_CODE (right
) == EQ_ATTR_ALT
)
2631 exp
= attr_alt_union (left
, right
);
2632 return simplify_test_exp (exp
, insn_code
, insn_index
);
2635 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2636 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2637 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2639 if (right
== true_rtx
|| left
== true_rtx
)
2641 else if (left
== false_rtx
)
2645 else if (right
== false_rtx
)
2650 /* Test for simple cases where the distributive law is useful. I.e.,
2651 convert (ior (and (x) (y))
2657 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2658 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2660 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2662 left
= XEXP (left
, 0);
2664 newexp
= attr_rtx (AND
, left
, right
);
2665 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2669 convert (ior (and (y) (x))
2671 to (and (ior (y) (z))
2673 Note that we want the common term to stay at the end.
2676 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2677 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2679 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2682 right
= XEXP (right
, 1);
2683 newexp
= attr_rtx (AND
, left
, right
);
2684 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2687 /* See if all or all but one of the insn's alternatives are specified
2688 in this tree. Optimize if so. */
2690 else if (insn_code
>= 0
2691 && (GET_CODE (left
) == IOR
2692 || (GET_CODE (left
) == EQ_ATTR_ALT
2694 || (GET_CODE (left
) == EQ_ATTR
2695 && XSTR (left
, 0) == alternative_name
)
2696 || GET_CODE (right
) == IOR
2697 || (GET_CODE (right
) == EQ_ATTR_ALT
2698 && !XINT (right
, 1))
2699 || (GET_CODE (right
) == EQ_ATTR
2700 && XSTR (right
, 0) == alternative_name
)))
2702 i
= compute_alternative_mask (exp
, IOR
);
2703 if (i
& ~insn_alternatives
[insn_code
])
2704 fatal ("invalid alternative specified for pattern number %d",
2707 /* If all alternatives are included, this is true. */
2708 i
^= insn_alternatives
[insn_code
];
2711 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2713 /* If just one excluded, IOR a comparison with that one to the
2714 front of the tree. The others will be eliminated by
2715 optimization. We do not want to do this if the insn has one
2716 alternative and we have tested none of them! */
2717 left
= make_alternative_compare (i
);
2718 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2719 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2721 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2725 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2727 newexp
= attr_rtx (IOR
, left
, right
);
2728 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2733 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2735 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2736 insn_code
, insn_index
);
2740 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2741 if (GET_CODE (left
) == NOT
)
2742 return XEXP (left
, 0);
2744 if (left
== false_rtx
)
2746 if (left
== true_rtx
)
2749 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2751 exp
= attr_alt_complement (left
);
2752 return simplify_test_exp (exp
, insn_code
, insn_index
);
2755 /* Try to apply De`Morgan's laws. */
2756 if (GET_CODE (left
) == IOR
)
2758 newexp
= attr_rtx (AND
,
2759 attr_rtx (NOT
, XEXP (left
, 0)),
2760 attr_rtx (NOT
, XEXP (left
, 1)));
2762 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2764 else if (GET_CODE (left
) == AND
)
2766 newexp
= attr_rtx (IOR
,
2767 attr_rtx (NOT
, XEXP (left
, 0)),
2768 attr_rtx (NOT
, XEXP (left
, 1)));
2770 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2772 else if (left
!= XEXP (exp
, 0))
2774 newexp
= attr_rtx (NOT
, left
);
2780 return XINT (exp
, 1) ? true_rtx
: false_rtx
;
2784 if (XSTR (exp
, 0) == alternative_name
)
2786 newexp
= mk_attr_alt (1 << atoi (XSTR (exp
, 1)));
2790 /* Look at the value for this insn code in the specified attribute.
2791 We normally can replace this comparison with the condition that
2792 would give this insn the values being tested for. */
2794 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2799 if (insn_code_values
)
2801 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2802 if (iv
->attr
== attr
)
2810 for (av
= attr
->first_value
; av
; av
= av
->next
)
2811 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2812 if (ie
->def
->insn_code
== insn_code
)
2819 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2820 insn_code
, insn_index
);
2821 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2822 if (attr_rtx_cost(x
) < 7)
2832 /* We have already simplified this expression. Simplifying it again
2833 won't buy anything unless we weren't given a valid insn code
2834 to process (i.e., we are canonicalizing something.). */
2836 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2837 return copy_rtx_unchanging (newexp
);
2842 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2843 otherwise return 0. */
2846 tests_attr_p (rtx p
, struct attr_desc
*attr
)
2851 if (GET_CODE (p
) == EQ_ATTR
)
2853 if (XSTR (p
, 0) != attr
->name
)
2858 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2859 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2860 for (i
= 0; i
< ie
; i
++)
2865 if (tests_attr_p (XEXP (p
, i
), attr
))
2870 je
= XVECLEN (p
, i
);
2871 for (j
= 0; j
< je
; ++j
)
2872 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2881 /* Calculate a topological sorting of all attributes so that
2882 all attributes only depend on attributes in front of it.
2883 Place the result in *RET (which is a pointer to an array of
2884 attr_desc pointers), and return the size of that array. */
2887 get_attr_order (struct attr_desc
***ret
)
2891 struct attr_desc
*attr
;
2892 struct attr_desc
**all
, **sorted
;
2894 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2895 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2897 all
= XNEWVEC (struct attr_desc
*, num
);
2898 sorted
= XNEWVEC (struct attr_desc
*, num
);
2899 handled
= XCNEWVEC (char, num
);
2901 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2902 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2906 for (i
= 0; i
< num
; i
++)
2907 if (all
[i
]->is_const
)
2908 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2910 /* We have only few attributes hence we can live with the inner
2911 loop being O(n^2), unlike the normal fast variants of topological
2915 for (i
= 0; i
< num
; i
++)
2918 /* Let's see if I depends on anything interesting. */
2920 for (k
= 0; k
< num
; k
++)
2923 struct attr_value
*av
;
2924 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2925 if (av
->num_insns
!= 0)
2926 if (tests_attr_p (av
->value
, all
[k
]))
2930 /* Something in I depends on K. */
2935 /* Nothing in I depended on anything intersting, so
2938 sorted
[j
++] = all
[i
];
2944 for (j
= 0; j
< num
; j
++)
2946 struct attr_desc
*attr2
;
2947 struct attr_value
*av
;
2950 fprintf (stderr
, "%s depends on: ", attr
->name
);
2951 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2952 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2953 if (!attr2
->is_const
)
2954 for (av
= attr
->first_value
; av
; av
= av
->next
)
2955 if (av
->num_insns
!= 0)
2956 if (tests_attr_p (av
->value
, attr2
))
2958 fprintf (stderr
, "%s, ", attr2
->name
);
2961 fprintf (stderr
, "\n");
2969 /* Optimize the attribute lists by seeing if we can determine conditional
2970 values from the known values of other attributes. This will save subroutine
2971 calls during the compilation. */
2974 optimize_attrs (void)
2976 struct attr_desc
*attr
;
2977 struct attr_value
*av
;
2978 struct insn_ent
*ie
;
2981 struct attr_value_list
*ivbuf
;
2982 struct attr_value_list
*iv
;
2983 struct attr_desc
**topsort
;
2986 /* For each insn code, make a list of all the insn_ent's for it,
2987 for all values for all attributes. */
2989 if (num_insn_ents
== 0)
2992 /* Make 2 extra elements, for "code" values -2 and -1. */
2993 insn_code_values
= XCNEWVEC (struct attr_value_list
*, insn_code_number
+ 2);
2995 /* Offset the table address so we can index by -2 or -1. */
2996 insn_code_values
+= 2;
2998 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
3000 /* Create the chain of insn*attr values such that we see dependend
3001 attributes after their dependencies. As we use a stack via the
3002 next pointers start from the end of the topological order. */
3003 topnum
= get_attr_order (&topsort
);
3004 for (i
= topnum
- 1; i
>= 0; i
--)
3005 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
3006 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
3008 iv
->attr
= topsort
[i
];
3011 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
3012 insn_code_values
[ie
->def
->insn_code
] = iv
;
3017 /* Sanity check on num_insn_ents. */
3018 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
3020 /* Process one insn code at a time. */
3021 for (i
= -2; i
< insn_code_number
; i
++)
3023 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
3024 We use it to mean "already simplified for this insn". */
3025 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3026 clear_struct_flag (iv
->av
->value
);
3028 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
3030 struct obstack
*old
= rtl_obstack
;
3035 if (GET_CODE (av
->value
) != COND
)
3038 rtl_obstack
= temp_obstack
;
3040 while (GET_CODE (newexp
) == COND
)
3042 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
3043 ie
->def
->insn_index
);
3044 if (newexp2
== newexp
)
3050 /* If we created a new value for this instruction, and it's
3051 cheaper than the old value, and overall cheap, use that
3052 one as specific value for the current instruction.
3053 The last test is to avoid exploding the get_attr_ function
3054 sizes for no much gain. */
3055 if (newexp
!= av
->value
3056 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
3057 && attr_rtx_cost (newexp
) < 26
3060 newexp
= attr_copy_rtx (newexp
);
3061 remove_insn_ent (av
, ie
);
3062 av
= get_attr_value (newexp
, attr
, ie
->def
->insn_code
);
3064 insert_insn_ent (av
, ie
);
3070 free (insn_code_values
- 2);
3071 insn_code_values
= NULL
;
3074 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
3077 clear_struct_flag (rtx x
)
3084 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3085 if (ATTR_IND_SIMPLIFIED_P (x
))
3088 code
= GET_CODE (x
);
3109 /* Compare the elements. If any pair of corresponding elements
3110 fail to match, return 0 for the whole things. */
3112 fmt
= GET_RTX_FORMAT (code
);
3113 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3119 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3120 clear_struct_flag (XVECEXP (x
, i
, j
));
3124 clear_struct_flag (XEXP (x
, i
));
3130 /* Add attribute value NAME to the beginning of ATTR's list. */
3133 add_attr_value (struct attr_desc
*attr
, const char *name
)
3135 struct attr_value
*av
;
3137 av
= oballoc (struct attr_value
);
3138 av
->value
= attr_rtx (CONST_STRING
, name
);
3139 av
->next
= attr
->first_value
;
3140 attr
->first_value
= av
;
3141 av
->first_insn
= NULL
;
3143 av
->has_asm_insn
= 0;
3146 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3149 gen_attr (rtx exp
, int lineno
)
3151 struct enum_type
*et
;
3152 struct enum_value
*ev
;
3153 struct attr_desc
*attr
;
3154 const char *name_ptr
;
3157 /* Make a new attribute structure. Check for duplicate by looking at
3158 attr->default_val, since it is initialized by this routine. */
3159 attr
= find_attr (&XSTR (exp
, 0), 1);
3160 if (attr
->default_val
)
3162 error_with_line (lineno
, "duplicate definition for attribute %s",
3164 message_with_line (attr
->lineno
, "previous definition");
3167 attr
->lineno
= lineno
;
3169 if (GET_CODE (exp
) == DEFINE_ENUM_ATTR
)
3171 attr
->enum_name
= XSTR (exp
, 1);
3172 et
= lookup_enum_type (XSTR (exp
, 1));
3173 if (!et
|| !et
->md_p
)
3174 error_with_line (lineno
, "No define_enum called `%s' defined",
3177 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3178 add_attr_value (attr
, ev
->name
);
3180 else if (*XSTR (exp
, 1) == '\0')
3181 attr
->is_numeric
= 1;
3184 name_ptr
= XSTR (exp
, 1);
3185 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3186 add_attr_value (attr
, p
);
3189 if (GET_CODE (XEXP (exp
, 2)) == CONST
)
3192 if (attr
->is_numeric
)
3193 error_with_line (lineno
,
3194 "constant attributes may not take numeric values");
3196 /* Get rid of the CONST node. It is allowed only at top-level. */
3197 XEXP (exp
, 2) = XEXP (XEXP (exp
, 2), 0);
3200 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3201 error_with_line (lineno
, "`length' attribute must take numeric values");
3203 /* Set up the default value. */
3204 XEXP (exp
, 2) = check_attr_value (XEXP (exp
, 2), attr
);
3205 attr
->default_val
= get_attr_value (XEXP (exp
, 2), attr
, -2);
3208 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3209 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3210 number of alternatives as this should be checked elsewhere. */
3213 count_alternatives (rtx exp
)
3218 if (GET_CODE (exp
) == MATCH_OPERAND
)
3219 return n_comma_elts (XSTR (exp
, 2));
3221 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3222 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3227 n
= count_alternatives (XEXP (exp
, i
));
3234 if (XVEC (exp
, i
) != NULL
)
3235 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3237 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3246 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3247 `alternative' attribute. */
3250 compares_alternatives_p (rtx exp
)
3255 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3258 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3259 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3264 if (compares_alternatives_p (XEXP (exp
, i
)))
3269 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3270 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3278 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3281 gen_insn (rtx exp
, int lineno
)
3283 struct insn_def
*id
;
3285 id
= oballoc (struct insn_def
);
3289 id
->lineno
= lineno
;
3291 switch (GET_CODE (exp
))
3294 id
->insn_code
= insn_code_number
;
3295 id
->insn_index
= insn_index_number
;
3296 id
->num_alternatives
= count_alternatives (exp
);
3297 if (id
->num_alternatives
== 0)
3298 id
->num_alternatives
= 1;
3302 case DEFINE_PEEPHOLE
:
3303 id
->insn_code
= insn_code_number
;
3304 id
->insn_index
= insn_index_number
;
3305 id
->num_alternatives
= count_alternatives (exp
);
3306 if (id
->num_alternatives
== 0)
3307 id
->num_alternatives
= 1;
3311 case DEFINE_ASM_ATTRIBUTES
:
3313 id
->insn_index
= -1;
3314 id
->num_alternatives
= 1;
3316 got_define_asm_attributes
= 1;
3324 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3325 true or annul false is specified, and make a `struct delay_desc'. */
3328 gen_delay (rtx def
, int lineno
)
3330 struct delay_desc
*delay
;
3333 if (XVECLEN (def
, 1) % 3 != 0)
3335 error_with_line (lineno
,
3336 "number of elements in DEFINE_DELAY must"
3337 " be multiple of three");
3341 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3343 if (XVECEXP (def
, 1, i
+ 1))
3344 have_annul_true
= 1;
3345 if (XVECEXP (def
, 1, i
+ 2))
3346 have_annul_false
= 1;
3349 delay
= oballoc (struct delay_desc
);
3351 delay
->num
= ++num_delays
;
3352 delay
->next
= delays
;
3353 delay
->lineno
= lineno
;
3357 /* Names of attributes that could be possibly cached. */
3358 static const char *cached_attrs
[32];
3359 /* Number of such attributes. */
3360 static int cached_attr_count
;
3361 /* Bitmasks of possibly cached attributes. */
3362 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3363 static unsigned int attrs_to_cache
;
3364 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3366 /* Finds non-const attributes that could be possibly cached.
3367 When create is TRUE, fills in cached_attrs array.
3368 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3372 find_attrs_to_cache (rtx exp
, bool create
)
3376 struct attr_desc
*attr
;
3381 switch (GET_CODE (exp
))
3384 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3385 find_attrs_to_cache (XEXP (exp
, 0), create
);
3389 name
= XSTR (exp
, 0);
3390 if (name
== alternative_name
)
3392 for (i
= 0; i
< cached_attr_count
; i
++)
3393 if (name
== cached_attrs
[i
])
3395 if ((attrs_seen_once
& (1U << i
)) != 0)
3396 attrs_seen_more_than_once
|= (1U << i
);
3398 attrs_seen_once
|= (1U << i
);
3403 attr
= find_attr (&name
, 0);
3407 if (cached_attr_count
== 32)
3409 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3410 attrs_seen_once
|= (1U << cached_attr_count
);
3411 cached_attr_count
++;
3416 find_attrs_to_cache (XEXP (exp
, 0), create
);
3417 find_attrs_to_cache (XEXP (exp
, 1), create
);
3421 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3422 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3430 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3431 We use AND and IOR both for logical and bit-wise operations, so
3432 interpret them as logical unless they are inside a comparison expression. */
3434 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3435 #define FLG_BITWISE 1
3436 /* Set if cached attribute will be known initialized in else block after
3437 this condition. This is true for LHS of toplevel && and || and
3438 even for RHS of ||, but not for RHS of &&. */
3440 /* Set if cached attribute will be known initialized in then block after
3441 this condition. This is true for LHS of toplevel && and || and
3442 even for RHS of &&, but not for RHS of ||. */
3443 #define FLG_INSIDE 4
3444 /* Cleared when an operand of &&. */
3445 #define FLG_OUTSIDE_AND 8
3448 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
)
3450 int comparison_operator
= 0;
3452 struct attr_desc
*attr
;
3454 /* In order not to worry about operator precedence, surround our part of
3455 the expression with parentheses. */
3457 fprintf (outf
, "(");
3458 code
= GET_CODE (exp
);
3461 /* Binary operators. */
3464 fprintf (outf
, "(unsigned) ");
3470 comparison_operator
= FLG_BITWISE
;
3472 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3473 case AND
: case IOR
: case XOR
:
3474 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3475 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3477 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3478 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3479 flags
| comparison_operator
);
3484 flags
&= ~FLG_OUTSIDE_AND
;
3485 if (GET_CODE (XEXP (exp
, 0)) == code
3486 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3487 || (GET_CODE (XEXP (exp
, 0)) == NOT
3488 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3490 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3492 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3497 fprintf (outf
, " == ");
3500 fprintf (outf
, " != ");
3503 fprintf (outf
, " >= ");
3506 fprintf (outf
, " > ");
3509 fprintf (outf
, " >= (unsigned) ");
3512 fprintf (outf
, " > (unsigned) ");
3515 fprintf (outf
, " <= ");
3518 fprintf (outf
, " < ");
3521 fprintf (outf
, " <= (unsigned) ");
3524 fprintf (outf
, " < (unsigned) ");
3527 fprintf (outf
, " + ");
3530 fprintf (outf
, " - ");
3533 fprintf (outf
, " * ");
3536 fprintf (outf
, " / ");
3539 fprintf (outf
, " %% ");
3542 if (flags
& FLG_BITWISE
)
3543 fprintf (outf
, " & ");
3545 fprintf (outf
, " && ");
3548 if (flags
& FLG_BITWISE
)
3549 fprintf (outf
, " | ");
3551 fprintf (outf
, " || ");
3554 fprintf (outf
, " ^ ");
3557 fprintf (outf
, " << ");
3561 fprintf (outf
, " >> ");
3569 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3570 cached_x is only known to be initialized in then block. */
3571 flags
&= ~FLG_AFTER
;
3573 else if (code
== IOR
)
3575 if (flags
& FLG_OUTSIDE_AND
)
3576 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3577 cached_x is only known to be initialized in else block
3578 and else if conditions. */
3579 flags
&= ~FLG_INSIDE
;
3581 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3583 cached_x is not know to be initialized anywhere. */
3584 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3586 if ((code
== AND
|| code
== IOR
)
3587 && (GET_CODE (XEXP (exp
, 1)) == code
3588 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3589 || (GET_CODE (XEXP (exp
, 1)) == NOT
3590 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3592 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
);
3594 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3595 flags
| comparison_operator
);
3599 /* Special-case (not (eq_attrq "alternative" "x")) */
3600 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3602 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3604 fprintf (outf
, "which_alternative != %s",
3605 XSTR (XEXP (exp
, 0), 1));
3609 fprintf (outf
, "! ");
3611 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3615 /* Otherwise, fall through to normal unary operator. */
3617 /* Unary operators. */
3622 if (flags
& FLG_BITWISE
)
3623 fprintf (outf
, "~ ");
3625 fprintf (outf
, "! ");
3628 fprintf (outf
, "abs ");
3631 fprintf (outf
, "-");
3637 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3638 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3643 int set
= XINT (exp
, 0), bit
= 0;
3645 if (flags
& FLG_BITWISE
)
3646 fatal ("EQ_ATTR_ALT not valid inside comparison");
3649 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3651 if (!(set
& (set
- 1)))
3653 if (!(set
& 0xffff))
3676 fprintf (outf
, "which_alternative %s= %d",
3677 XINT (exp
, 1) ? "!" : "=", bit
);
3681 fprintf (outf
, "%s((1 << which_alternative) & %#x)",
3682 XINT (exp
, 1) ? "!" : "", set
);
3687 /* Comparison test of an attribute with a value. Most of these will
3688 have been removed by optimization. Handle "alternative"
3689 specially and give error if EQ_ATTR present inside a comparison. */
3691 if (flags
& FLG_BITWISE
)
3692 fatal ("EQ_ATTR not valid inside comparison");
3694 if (XSTR (exp
, 0) == alternative_name
)
3696 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3700 attr
= find_attr (&XSTR (exp
, 0), 0);
3703 /* Now is the time to expand the value of a constant attribute. */
3706 write_test_expr (outf
,
3707 evaluate_eq_attr (exp
, attr
,
3708 attr
->default_val
->value
,
3715 for (i
= 0; i
< cached_attr_count
; i
++)
3716 if (attr
->name
== cached_attrs
[i
])
3718 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3719 fprintf (outf
, "cached_%s", attr
->name
);
3720 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3722 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3723 attr
->name
, attr
->name
);
3724 if (flags
& FLG_AFTER
)
3725 attrs_cached_after
|= (1U << i
);
3726 if (flags
& FLG_INSIDE
)
3727 attrs_cached_inside
|= (1U << i
);
3728 attrs_cached
|= (1U << i
);
3731 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3732 fprintf (outf
, " == ");
3733 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3737 /* Comparison test of flags for define_delays. */
3739 if (flags
& FLG_BITWISE
)
3740 fatal ("ATTR_FLAG not valid inside comparison");
3741 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3744 /* See if an operand matches a predicate. */
3746 /* If only a mode is given, just ensure the mode matches the operand.
3747 If neither a mode nor predicate is given, error. */
3748 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3750 if (GET_MODE (exp
) == VOIDmode
)
3751 fatal ("null MATCH_OPERAND specified as test");
3753 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3754 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3757 fprintf (outf
, "%s (operands[%d], %smode)",
3758 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3761 /* Constant integer. */
3763 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3767 fprint_c_condition (outf
, XSTR (exp
, 0));
3768 if (flags
& FLG_BITWISE
)
3769 fprintf (outf
, " != 0");
3772 /* A random C expression. */
3774 fprint_c_condition (outf
, XSTR (exp
, 0));
3777 /* The address of the branch target. */
3780 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3781 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3785 /* The address of the current insn. We implement this actually as the
3786 address of the current insn for backward branches, but the last
3787 address of the next insn for forward branches, and both with
3788 adjustments that account for the worst-case possible stretching of
3789 intervening alignments between this insn and its destination. */
3790 fprintf (outf
, "insn_current_reference_address (insn)");
3794 fprintf (outf
, "%s", XSTR (exp
, 0));
3798 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3799 fprintf (outf
, " ? ");
3800 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3801 fprintf (outf
, " : ");
3802 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3806 fatal ("bad RTX code `%s' in attribute calculation\n",
3807 GET_RTX_NAME (code
));
3810 fprintf (outf
, ")");
3811 return attrs_cached
;
3814 /* Given an attribute value, return the maximum CONST_STRING argument
3815 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */
3818 max_attr_value (rtx exp
, int *unknownp
)
3823 switch (GET_CODE (exp
))
3826 current_max
= atoi (XSTR (exp
, 0));
3830 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3831 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3833 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3834 if (n
> current_max
)
3840 current_max
= max_attr_value (XEXP (exp
, 1), unknownp
);
3841 n
= max_attr_value (XEXP (exp
, 2), unknownp
);
3842 if (n
> current_max
)
3848 current_max
= INT_MAX
;
3855 /* Given an attribute value, return the minimum CONST_STRING argument
3856 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */
3859 min_attr_value (rtx exp
, int *unknownp
)
3864 switch (GET_CODE (exp
))
3867 current_min
= atoi (XSTR (exp
, 0));
3871 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3872 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3874 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3875 if (n
< current_min
)
3881 current_min
= min_attr_value (XEXP (exp
, 1), unknownp
);
3882 n
= min_attr_value (XEXP (exp
, 2), unknownp
);
3883 if (n
< current_min
)
3889 current_min
= INT_MAX
;
3896 /* Given an attribute value, return the result of ORing together all
3897 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1
3898 if the numeric value is not known. */
3901 or_attr_value (rtx exp
, int *unknownp
)
3906 switch (GET_CODE (exp
))
3909 current_or
= atoi (XSTR (exp
, 0));
3913 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3914 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3915 current_or
|= or_attr_value (XVECEXP (exp
, 0, i
+ 1), unknownp
);
3919 current_or
= or_attr_value (XEXP (exp
, 1), unknownp
);
3920 current_or
|= or_attr_value (XEXP (exp
, 2), unknownp
);
3932 /* Scan an attribute value, possibly a conditional, and record what actions
3933 will be required to do any conditional tests in it.
3936 `must_extract' if we need to extract the insn operands
3937 `must_constrain' if we must compute `which_alternative'
3938 `address_used' if an address expression was used
3939 `length_used' if an (eq_attr "length" ...) was used
3943 walk_attr_value (rtx exp
)
3952 code
= GET_CODE (exp
);
3956 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3957 /* Since this is an arbitrary expression, it can look at anything.
3958 However, constant expressions do not depend on any particular
3960 must_extract
= must_constrain
= 1;
3969 must_extract
= must_constrain
= 1;
3973 if (XSTR (exp
, 0) == alternative_name
)
3974 must_extract
= must_constrain
= 1;
3975 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
3995 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
4000 walk_attr_value (XEXP (exp
, i
));
4004 if (XVEC (exp
, i
) != NULL
)
4005 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4006 walk_attr_value (XVECEXP (exp
, i
, j
));
4011 /* Write out a function to obtain the attribute for a given INSN. */
4014 write_attr_get (FILE *outf
, struct attr_desc
*attr
)
4016 struct attr_value
*av
, *common_av
;
4019 /* Find the most used attribute value. Handle that as the `default' of the
4020 switch we will generate. */
4021 common_av
= find_most_used (attr
);
4023 /* Write out start of function, then all values with explicit `case' lines,
4024 then a `default', then the value with the most uses. */
4025 if (attr
->enum_name
)
4026 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4027 else if (!attr
->is_numeric
)
4028 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4030 fprintf (outf
, "int\n");
4032 /* If the attribute name starts with a star, the remainder is the name of
4033 the subroutine to use, instead of `get_attr_...'. */
4034 if (attr
->name
[0] == '*')
4035 fprintf (outf
, "%s (rtx insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4036 else if (attr
->is_const
== 0)
4037 fprintf (outf
, "get_attr_%s (rtx insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4040 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4041 fprintf (outf
, "{\n");
4043 for (av
= attr
->first_value
; av
; av
= av
->next
)
4044 if (av
->num_insns
== 1)
4045 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4046 true_rtx
, av
->first_insn
->def
->insn_code
,
4047 av
->first_insn
->def
->insn_index
, 0);
4048 else if (av
->num_insns
!= 0)
4049 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4050 true_rtx
, -2, 0, 0);
4052 fprintf (outf
, "}\n\n");
4056 fprintf (outf
, "{\n");
4058 /* Find attributes that are worth caching in the conditions. */
4059 cached_attr_count
= 0;
4060 attrs_seen_more_than_once
= 0;
4061 for (av
= attr
->first_value
; av
; av
= av
->next
)
4063 attrs_seen_once
= 0;
4064 find_attrs_to_cache (av
->value
, true);
4066 /* Remove those that aren't worth caching from the array. */
4067 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4068 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4070 const char *name
= cached_attrs
[i
];
4071 struct attr_desc
*cached_attr
;
4073 cached_attrs
[j
] = name
;
4074 cached_attr
= find_attr (&name
, 0);
4075 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4076 if (cached_attr
->enum_name
)
4077 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4078 else if (!cached_attr
->is_numeric
)
4079 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4081 fprintf (outf
, " int");
4082 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4085 cached_attr_count
= j
;
4086 if (cached_attr_count
)
4087 fprintf (outf
, "\n");
4089 fprintf (outf
, " switch (recog_memoized (insn))\n");
4090 fprintf (outf
, " {\n");
4092 for (av
= attr
->first_value
; av
; av
= av
->next
)
4093 if (av
!= common_av
)
4094 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4096 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4097 fprintf (outf
, " }\n}\n\n");
4098 cached_attr_count
= 0;
4101 /* Given an AND tree of known true terms (because we are inside an `if' with
4102 that as the condition or are in an `else' clause) and an expression,
4103 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4104 the bulk of the work. */
4107 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4111 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4113 if (GET_CODE (known_true
) == AND
)
4115 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4116 insn_code
, insn_index
);
4117 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4118 insn_code
, insn_index
);
4123 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4129 /* Write out a series of tests and assignment statements to perform tests and
4130 sets of an attribute value. We are passed an indentation amount and prefix
4131 and suffix strings to write around each attribute value (e.g., "return"
4135 write_attr_set (FILE *outf
, struct attr_desc
*attr
, int indent
, rtx value
,
4136 const char *prefix
, const char *suffix
, rtx known_true
,
4137 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4139 if (GET_CODE (value
) == COND
)
4141 /* Assume the default value will be the default of the COND unless we
4142 find an always true expression. */
4143 rtx default_val
= XEXP (value
, 1);
4144 rtx our_known_true
= known_true
;
4149 if (cached_attr_count
)
4151 attrs_seen_once
= 0;
4152 attrs_seen_more_than_once
= 0;
4153 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4154 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4155 attrs_to_cache
|= attrs_seen_more_than_once
;
4158 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4163 /* Reset our_known_true after some time to not accumulate
4164 too much cruft (slowing down genattrtab). */
4166 our_known_true
= known_true
;
4167 testexp
= eliminate_known_true (our_known_true
,
4168 XVECEXP (value
, 0, i
),
4169 insn_code
, insn_index
);
4170 newexp
= attr_rtx (NOT
, testexp
);
4171 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4172 insn_code
, insn_index
);
4174 /* If the test expression is always true or if the next `known_true'
4175 expression is always false, this is the last case, so break
4176 out and let this value be the `else' case. */
4177 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4179 default_val
= XVECEXP (value
, 0, i
+ 1);
4183 /* Compute the expression to pass to our recursive call as being
4185 inner_true
= insert_right_side (AND
, our_known_true
,
4186 testexp
, insn_code
, insn_index
);
4188 /* If this is always false, skip it. */
4189 if (inner_true
== false_rtx
)
4192 attrs_cached_inside
= attrs_cached
;
4193 attrs_cached_after
= attrs_cached
;
4194 write_indent (outf
, indent
);
4195 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4197 write_test_expr (outf
, testexp
, attrs_cached
,
4198 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4199 attrs_cached
= attrs_cached_after
;
4200 fprintf (outf
, "\n");
4201 write_indent (outf
, indent
+ 2);
4202 fprintf (outf
, "{\n");
4204 write_attr_set (outf
, attr
, indent
+ 4,
4205 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4206 inner_true
, insn_code
, insn_index
,
4207 attrs_cached_inside
);
4208 write_indent (outf
, indent
+ 2);
4209 fprintf (outf
, "}\n");
4210 our_known_true
= newexp
;
4215 write_indent (outf
, indent
);
4216 fprintf (outf
, "else\n");
4217 write_indent (outf
, indent
+ 2);
4218 fprintf (outf
, "{\n");
4221 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4222 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4227 write_indent (outf
, indent
+ 2);
4228 fprintf (outf
, "}\n");
4233 write_indent (outf
, indent
);
4234 fprintf (outf
, "%s ", prefix
);
4235 write_attr_value (outf
, attr
, value
);
4236 fprintf (outf
, "%s\n", suffix
);
4240 /* Write a series of case statements for every instruction in list IE.
4241 INDENT is the amount of indentation to write before each case. */
4244 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4246 for (; ie
!= 0; ie
= ie
->next
)
4247 if (ie
->def
->insn_code
!= -1)
4249 write_indent (outf
, indent
);
4250 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4251 fprintf (outf
, "case %d: /* define_peephole, line %d */\n",
4252 ie
->def
->insn_code
, ie
->def
->lineno
);
4254 fprintf (outf
, "case %d: /* %s */\n",
4255 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4259 /* Write out the computation for one attribute value. */
4262 write_attr_case (FILE *outf
, struct attr_desc
*attr
, struct attr_value
*av
,
4263 int write_case_lines
, const char *prefix
, const char *suffix
,
4264 int indent
, rtx known_true
)
4266 if (av
->num_insns
== 0)
4269 if (av
->has_asm_insn
)
4271 write_indent (outf
, indent
);
4272 fprintf (outf
, "case -1:\n");
4273 write_indent (outf
, indent
+ 2);
4274 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4275 write_indent (outf
, indent
+ 2);
4276 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4277 write_indent (outf
, indent
+ 2);
4278 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4281 if (write_case_lines
)
4282 write_insn_cases (outf
, av
->first_insn
, indent
);
4285 write_indent (outf
, indent
);
4286 fprintf (outf
, "default:\n");
4289 /* See what we have to do to output this value. */
4290 must_extract
= must_constrain
= address_used
= 0;
4291 walk_attr_value (av
->value
);
4295 write_indent (outf
, indent
+ 2);
4296 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4298 else if (must_extract
)
4300 write_indent (outf
, indent
+ 2);
4301 fprintf (outf
, "extract_insn_cached (insn);\n");
4305 if (av
->num_insns
== 1)
4306 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4307 known_true
, av
->first_insn
->def
->insn_code
,
4308 av
->first_insn
->def
->insn_index
, 0);
4310 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4311 known_true
, -2, 0, 0);
4313 if (strncmp (prefix
, "return", 6))
4315 write_indent (outf
, indent
+ 2);
4316 fprintf (outf
, "break;\n");
4318 fprintf (outf
, "\n");
4321 /* Utilities to write in various forms. */
4324 write_attr_valueq (FILE *outf
, struct attr_desc
*attr
, const char *s
)
4326 if (attr
->is_numeric
)
4330 fprintf (outf
, "%d", num
);
4332 if (num
> 9 || num
< 0)
4333 fprintf (outf
, " /* %#x */", num
);
4337 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4338 fprintf (outf
, "_");
4339 write_upcase (outf
, s
);
4344 write_attr_value (FILE *outf
, struct attr_desc
*attr
, rtx value
)
4348 switch (GET_CODE (value
))
4351 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4355 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4359 fprint_c_condition (outf
, XSTR (value
, 0));
4364 struct attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4365 if (attr
->enum_name
)
4366 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4367 else if (!attr
->is_numeric
)
4368 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4369 else if (!attr2
->is_numeric
)
4370 fprintf (outf
, "(int)");
4372 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4373 (attr2
->is_const
? "" : "insn"));
4394 write_attr_value (outf
, attr
, XEXP (value
, 0));
4398 write_attr_value (outf
, attr
, XEXP (value
, 1));
4407 write_upcase (FILE *outf
, const char *str
)
4411 /* The argument of TOUPPER should not have side effects. */
4412 fputc (TOUPPER(*str
), outf
);
4418 write_indent (FILE *outf
, int indent
)
4420 for (; indent
> 8; indent
-= 8)
4421 fprintf (outf
, "\t");
4423 for (; indent
; indent
--)
4424 fprintf (outf
, " ");
4427 /* Write a subroutine that is given an insn that requires a delay slot, a
4428 delay slot ordinal, and a candidate insn. It returns nonzero if the
4429 candidate can be placed in the specified delay slot of the insn.
4431 We can write as many as three subroutines. `eligible_for_delay'
4432 handles normal delay slots, `eligible_for_annul_true' indicates that
4433 the specified insn can be annulled if the branch is true, and likewise
4434 for `eligible_for_annul_false'.
4436 KIND is a string distinguishing these three cases ("delay", "annul_true",
4437 or "annul_false"). */
4440 write_eligible_delay (FILE *outf
, const char *kind
)
4442 struct delay_desc
*delay
;
4446 struct attr_desc
*attr
;
4447 struct attr_value
*av
, *common_av
;
4450 /* Compute the maximum number of delay slots required. We use the delay
4451 ordinal times this number plus one, plus the slot number as an index into
4452 the appropriate predicate to test. */
4454 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4455 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4456 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4458 /* Write function prelude. */
4460 fprintf (outf
, "int\n");
4461 fprintf (outf
, "eligible_for_%s (rtx delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4462 " rtx candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4464 fprintf (outf
, "{\n");
4465 fprintf (outf
, " rtx insn;\n");
4466 fprintf (outf
, "\n");
4467 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4468 fprintf (outf
, "\n");
4469 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4470 converts a compound instruction into a loop. */
4471 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4472 fprintf (outf
, " return 0;\n");
4473 fprintf (outf
, "\n");
4475 /* If more than one delay type, find out which type the delay insn is. */
4479 attr
= find_attr (&delay_type_str
, 0);
4481 common_av
= find_most_used (attr
);
4483 fprintf (outf
, " insn = delay_insn;\n");
4484 fprintf (outf
, " switch (recog_memoized (insn))\n");
4485 fprintf (outf
, " {\n");
4487 sprintf (str
, " * %d;\n break;", max_slots
);
4488 for (av
= attr
->first_value
; av
; av
= av
->next
)
4489 if (av
!= common_av
)
4490 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4492 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4493 fprintf (outf
, " }\n\n");
4495 /* Ensure matched. Otherwise, shouldn't have been called. */
4496 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4499 /* If just one type of delay slot, write simple switch. */
4500 if (num_delays
== 1 && max_slots
== 1)
4502 fprintf (outf
, " insn = candidate_insn;\n");
4503 fprintf (outf
, " switch (recog_memoized (insn))\n");
4504 fprintf (outf
, " {\n");
4506 attr
= find_attr (&delay_1_0_str
, 0);
4508 common_av
= find_most_used (attr
);
4510 for (av
= attr
->first_value
; av
; av
= av
->next
)
4511 if (av
!= common_av
)
4512 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4514 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4515 fprintf (outf
, " }\n");
4520 /* Write a nested CASE. The first indicates which condition we need to
4521 test, and the inner CASE tests the condition. */
4522 fprintf (outf
, " insn = candidate_insn;\n");
4523 fprintf (outf
, " switch (slot)\n");
4524 fprintf (outf
, " {\n");
4526 for (delay
= delays
; delay
; delay
= delay
->next
)
4527 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4529 fprintf (outf
, " case %d:\n",
4530 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4531 fprintf (outf
, " switch (recog_memoized (insn))\n");
4532 fprintf (outf
, "\t{\n");
4534 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4536 attr
= find_attr (&pstr
, 0);
4538 common_av
= find_most_used (attr
);
4540 for (av
= attr
->first_value
; av
; av
= av
->next
)
4541 if (av
!= common_av
)
4542 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4544 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4545 fprintf (outf
, " }\n");
4548 fprintf (outf
, " default:\n");
4549 fprintf (outf
, " gcc_unreachable ();\n");
4550 fprintf (outf
, " }\n");
4553 fprintf (outf
, "}\n\n");
4556 /* This page contains miscellaneous utility routines. */
4558 /* Given a pointer to a (char *), return a malloc'ed string containing the
4559 next comma-separated element. Advance the pointer to after the string
4560 scanned, or the end-of-string. Return NULL if at end of string. */
4563 next_comma_elt (const char **pstr
)
4567 start
= scan_comma_elt (pstr
);
4572 return attr_string (start
, *pstr
- start
);
4575 /* Return a `struct attr_desc' pointer for a given named attribute. If CREATE
4576 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4577 replaced by a pointer to a canonical copy of the string. */
4579 static struct attr_desc
*
4580 find_attr (const char **name_p
, int create
)
4582 struct attr_desc
*attr
;
4584 const char *name
= *name_p
;
4586 /* Before we resort to using `strcmp', see if the string address matches
4587 anywhere. In most cases, it should have been canonicalized to do so. */
4588 if (name
== alternative_name
)
4591 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4592 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4593 if (name
== attr
->name
)
4596 /* Otherwise, do it the slow way. */
4597 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4598 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4600 *name_p
= attr
->name
;
4607 attr
= oballoc (struct attr_desc
);
4608 attr
->name
= DEF_ATTR_STRING (name
);
4609 attr
->enum_name
= 0;
4610 attr
->first_value
= attr
->default_val
= NULL
;
4611 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4612 attr
->next
= attrs
[index
];
4613 attrs
[index
] = attr
;
4615 *name_p
= attr
->name
;
4620 /* Create internal attribute with the given default value. */
4623 make_internal_attr (const char *name
, rtx value
, int special
)
4625 struct attr_desc
*attr
;
4627 attr
= find_attr (&name
, 1);
4628 gcc_assert (!attr
->default_val
);
4630 attr
->is_numeric
= 1;
4632 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4633 attr
->default_val
= get_attr_value (value
, attr
, -2);
4636 /* Find the most used value of an attribute. */
4638 static struct attr_value
*
4639 find_most_used (struct attr_desc
*attr
)
4641 struct attr_value
*av
;
4642 struct attr_value
*most_used
;
4648 for (av
= attr
->first_value
; av
; av
= av
->next
)
4649 if (av
->num_insns
> nuses
)
4650 nuses
= av
->num_insns
, most_used
= av
;
4655 /* Return (attr_value "n") */
4658 make_numeric_value (int n
)
4660 static rtx int_values
[20];
4664 gcc_assert (n
>= 0);
4666 if (n
< 20 && int_values
[n
])
4667 return int_values
[n
];
4669 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4670 exp
= attr_rtx (CONST_STRING
, p
);
4673 int_values
[n
] = exp
;
4679 copy_rtx_unchanging (rtx orig
)
4681 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4684 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4688 /* Determine if an insn has a constant number of delay slots, i.e., the
4689 number of delay slots is not a function of the length of the insn. */
4692 write_const_num_delay_slots (FILE *outf
)
4694 struct attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4695 struct attr_value
*av
;
4699 fprintf (outf
, "int\nconst_num_delay_slots (rtx insn)\n");
4700 fprintf (outf
, "{\n");
4701 fprintf (outf
, " switch (recog_memoized (insn))\n");
4702 fprintf (outf
, " {\n");
4704 for (av
= attr
->first_value
; av
; av
= av
->next
)
4707 walk_attr_value (av
->value
);
4709 write_insn_cases (outf
, av
->first_insn
, 4);
4712 fprintf (outf
, " default:\n");
4713 fprintf (outf
, " return 1;\n");
4714 fprintf (outf
, " }\n}\n\n");
4718 /* Synthetic attributes used by insn-automata.c and the scheduler.
4719 These are primarily concerned with (define_insn_reservation)
4724 struct insn_reserv
*next
;
4727 int default_latency
;
4730 /* Sequence number of this insn. */
4733 /* Whether a (define_bypass) construct names this insn in its
4738 static struct insn_reserv
*all_insn_reservs
= 0;
4739 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4740 static size_t n_insn_reservs
;
4742 /* Store information from a DEFINE_INSN_RESERVATION for future
4743 attribute generation. */
4745 gen_insn_reserv (rtx def
)
4747 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4749 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4750 decl
->default_latency
= XINT (def
, 1);
4751 decl
->condexp
= check_attr_test (XEXP (def
, 2), 0, 0);
4752 decl
->insn_num
= n_insn_reservs
;
4753 decl
->bypassed
= false;
4756 *last_insn_reserv_p
= decl
;
4757 last_insn_reserv_p
= &decl
->next
;
4761 /* Store information from a DEFINE_BYPASS for future attribute
4762 generation. The only thing we care about is the list of output
4763 insns, which will later be used to tag reservation structures with
4764 a 'bypassed' bit. */
4768 struct bypass_list
*next
;
4769 const char *pattern
;
4772 static struct bypass_list
*all_bypasses
;
4773 static size_t n_bypasses
;
4776 gen_bypass_1 (const char *s
, size_t len
)
4778 struct bypass_list
*b
;
4783 s
= attr_string (s
, len
);
4784 for (b
= all_bypasses
; b
; b
= b
->next
)
4785 if (s
== b
->pattern
)
4786 return; /* already got that one */
4788 b
= oballoc (struct bypass_list
);
4790 b
->next
= all_bypasses
;
4796 gen_bypass (rtx def
)
4798 const char *p
, *base
;
4800 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4803 gen_bypass_1 (base
, p
- base
);
4806 while (ISSPACE (*p
));
4809 gen_bypass_1 (base
, p
- base
);
4812 /* Find and mark all of the bypassed insns. */
4814 process_bypasses (void)
4816 struct bypass_list
*b
;
4817 struct insn_reserv
*r
;
4819 /* The reservation list is likely to be much longer than the bypass
4821 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4822 for (b
= all_bypasses
; b
; b
= b
->next
)
4823 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4827 /* Check that attribute NAME is used in define_insn_reservation condition
4828 EXP. Return true if it is. */
4830 check_tune_attr (const char *name
, rtx exp
)
4832 switch (GET_CODE (exp
))
4835 if (check_tune_attr (name
, XEXP (exp
, 0)))
4837 return check_tune_attr (name
, XEXP (exp
, 1));
4840 return (check_tune_attr (name
, XEXP (exp
, 0))
4841 && check_tune_attr (name
, XEXP (exp
, 1)));
4844 return XSTR (exp
, 0) == name
;
4851 /* Try to find a const attribute (usually cpu or tune) that is used
4852 in all define_insn_reservation conditions. */
4853 static struct attr_desc
*
4854 find_tune_attr (rtx exp
)
4856 struct attr_desc
*attr
;
4858 switch (GET_CODE (exp
))
4862 attr
= find_tune_attr (XEXP (exp
, 0));
4865 return find_tune_attr (XEXP (exp
, 1));
4868 if (XSTR (exp
, 0) == alternative_name
)
4871 attr
= find_attr (&XSTR (exp
, 0), 0);
4874 if (attr
->is_const
&& !attr
->is_special
)
4876 struct insn_reserv
*decl
;
4878 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4879 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4890 /* Create all of the attributes that describe automaton properties.
4891 Write the DFA and latency function prototypes to the files that
4892 need to have them, and write the init_sched_attrs(). */
4895 make_automaton_attrs (void)
4898 struct insn_reserv
*decl
;
4899 rtx code_exp
, lats_exp
, byps_exp
;
4900 struct attr_desc
*tune_attr
;
4902 if (n_insn_reservs
== 0)
4905 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4906 if (tune_attr
!= NULL
)
4908 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4909 struct attr_value
*val
;
4912 gcc_assert (tune_attr
->is_const
4913 && !tune_attr
->is_special
4914 && !tune_attr
->is_numeric
);
4916 /* Write the prototypes for all DFA functions. */
4917 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4919 if (val
== tune_attr
->default_val
)
4921 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4923 "extern int internal_dfa_insn_code_%s (rtx);\n",
4924 XSTR (val
->value
, 0));
4926 fprintf (dfa_file
, "\n");
4928 /* Write the prototypes for all latency functions. */
4929 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4931 if (val
== tune_attr
->default_val
)
4933 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4934 fprintf (latency_file
,
4935 "extern int insn_default_latency_%s (rtx);\n",
4936 XSTR (val
->value
, 0));
4938 fprintf (latency_file
, "\n");
4940 /* Write the prototypes for all automaton functions. */
4941 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4943 if (val
== tune_attr
->default_val
)
4945 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
4947 "extern int internal_dfa_insn_code_%s (rtx);\n"
4948 "extern int insn_default_latency_%s (rtx);\n",
4949 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
4951 fprintf (attr_file
, "\n");
4952 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx);\n");
4953 fprintf (attr_file
, "int (*insn_default_latency) (rtx);\n");
4954 fprintf (attr_file
, "\n");
4955 fprintf (attr_file
, "void\n");
4956 fprintf (attr_file
, "init_sched_attrs (void)\n");
4957 fprintf (attr_file
, "{\n");
4959 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
4963 rtx test
= attr_rtx (EQ_ATTR
, tune_attr
->name
, XSTR (val
->value
, 0));
4965 if (val
== tune_attr
->default_val
)
4967 for (decl
= all_insn_reservs
, i
= 0;
4973 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
4974 if (condexp
== false_rtx
)
4976 if (condexp
== true_rtx
)
4978 condexps
[i
] = condexp
;
4979 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
4980 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
4984 code_exp
= rtx_alloc (COND
);
4985 lats_exp
= rtx_alloc (COND
);
4988 XVEC (code_exp
, 0) = rtvec_alloc (j
);
4989 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
4993 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
4994 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
4998 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
4999 XEXP (lats_exp
, 1) = make_numeric_value (0);
5006 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
5007 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
5009 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
5010 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5013 name
= XNEWVEC (char,
5014 sizeof ("*internal_dfa_insn_code_")
5015 + strlen (XSTR (val
->value
, 0)));
5016 strcpy (name
, "*internal_dfa_insn_code_");
5017 strcat (name
, XSTR (val
->value
, 0));
5018 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5019 strcpy (name
, "*insn_default_latency_");
5020 strcat (name
, XSTR (val
->value
, 0));
5021 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5026 fprintf (attr_file
, " if (");
5030 fprintf (attr_file
, " else if (");
5031 write_test_expr (attr_file
, test
, 0, 0);
5032 fprintf (attr_file
, ")\n");
5033 fprintf (attr_file
, " {\n");
5034 fprintf (attr_file
, " internal_dfa_insn_code\n");
5035 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5036 XSTR (val
->value
, 0));
5037 fprintf (attr_file
, " insn_default_latency\n");
5038 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5039 XSTR (val
->value
, 0));
5040 fprintf (attr_file
, " }\n");
5043 fprintf (attr_file
, " else\n");
5044 fprintf (attr_file
, " gcc_unreachable ();\n");
5045 fprintf (attr_file
, "}\n");
5046 fprintf (attr_file
, "\n");
5048 XDELETEVEC (condexps
);
5052 code_exp
= rtx_alloc (COND
);
5053 lats_exp
= rtx_alloc (COND
);
5055 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5056 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5058 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5059 XEXP (lats_exp
, 1) = make_numeric_value (0);
5061 for (decl
= all_insn_reservs
, i
= 0;
5063 decl
= decl
->next
, i
+= 2)
5065 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5066 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5068 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5069 XVECEXP (lats_exp
, 0, i
+1)
5070 = make_numeric_value (decl
->default_latency
);
5072 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5073 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5076 if (n_bypasses
== 0)
5077 byps_exp
= make_numeric_value (0);
5080 process_bypasses ();
5082 byps_exp
= rtx_alloc (COND
);
5083 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypasses
* 2);
5084 XEXP (byps_exp
, 1) = make_numeric_value (0);
5085 for (decl
= all_insn_reservs
, i
= 0;
5090 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5091 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5096 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5100 write_header (FILE *outf
)
5102 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5103 " from the machine description file `md'. */\n\n");
5105 fprintf (outf
, "#include \"config.h\"\n");
5106 fprintf (outf
, "#include \"system.h\"\n");
5107 fprintf (outf
, "#include \"coretypes.h\"\n");
5108 fprintf (outf
, "#include \"tm.h\"\n");
5109 fprintf (outf
, "#include \"rtl.h\"\n");
5110 fprintf (outf
, "#include \"insn-attr.h\"\n");
5111 fprintf (outf
, "#include \"tm_p.h\"\n");
5112 fprintf (outf
, "#include \"insn-config.h\"\n");
5113 fprintf (outf
, "#include \"recog.h\"\n");
5114 fprintf (outf
, "#include \"regs.h\"\n");
5115 fprintf (outf
, "#include \"real.h\"\n");
5116 fprintf (outf
, "#include \"output.h\"\n");
5117 fprintf (outf
, "#include \"toplev.h\"\n");
5118 fprintf (outf
, "#include \"flags.h\"\n");
5119 fprintf (outf
, "#include \"function.h\"\n");
5120 fprintf (outf
, "\n");
5121 fprintf (outf
, "#define operands recog_data.operand\n\n");
5125 open_outfile (const char *file_name
)
5128 outf
= fopen (file_name
, "w");
5130 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5131 write_header (outf
);
5136 handle_arg (const char *arg
)
5141 attr_file_name
= &arg
[2];
5144 dfa_file_name
= &arg
[2];
5147 latency_file_name
= &arg
[2];
5155 main (int argc
, char **argv
)
5158 struct attr_desc
*attr
;
5159 struct insn_def
*id
;
5163 progname
= "genattrtab";
5165 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5166 return FATAL_EXIT_CODE
;
5168 attr_file
= open_outfile (attr_file_name
);
5169 dfa_file
= open_outfile (dfa_file_name
);
5170 latency_file
= open_outfile (latency_file_name
);
5172 obstack_init (hash_obstack
);
5173 obstack_init (temp_obstack
);
5175 /* Set up true and false rtx's */
5176 true_rtx
= rtx_alloc (CONST_INT
);
5177 XWINT (true_rtx
, 0) = 1;
5178 false_rtx
= rtx_alloc (CONST_INT
);
5179 XWINT (false_rtx
, 0) = 0;
5180 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5181 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5183 alternative_name
= DEF_ATTR_STRING ("alternative");
5184 length_str
= DEF_ATTR_STRING ("length");
5185 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5186 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5187 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5189 /* Read the machine description. */
5195 desc
= read_md_rtx (&lineno
, &insn_code_number
);
5199 switch (GET_CODE (desc
))
5202 case DEFINE_PEEPHOLE
:
5203 case DEFINE_ASM_ATTRIBUTES
:
5204 gen_insn (desc
, lineno
);
5208 case DEFINE_ENUM_ATTR
:
5209 gen_attr (desc
, lineno
);
5213 gen_delay (desc
, lineno
);
5216 case DEFINE_INSN_RESERVATION
:
5217 gen_insn_reserv (desc
);
5227 if (GET_CODE (desc
) != DEFINE_ASM_ATTRIBUTES
)
5228 insn_index_number
++;
5232 return FATAL_EXIT_CODE
;
5236 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5237 if (! got_define_asm_attributes
)
5239 tem
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5240 XVEC (tem
, 0) = rtvec_alloc (0);
5244 /* Expand DEFINE_DELAY information into new attribute. */
5248 /* Make `insn_alternatives'. */
5249 insn_alternatives
= oballocvec (int, insn_code_number
);
5250 for (id
= defs
; id
; id
= id
->next
)
5251 if (id
->insn_code
>= 0)
5252 insn_alternatives
[id
->insn_code
] = (1 << id
->num_alternatives
) - 1;
5254 /* Make `insn_n_alternatives'. */
5255 insn_n_alternatives
= oballocvec (int, insn_code_number
);
5256 for (id
= defs
; id
; id
= id
->next
)
5257 if (id
->insn_code
>= 0)
5258 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5260 /* Construct extra attributes for automata. */
5261 make_automaton_attrs ();
5263 /* Prepare to write out attribute subroutines by checking everything stored
5264 away and building the attribute cases. */
5268 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5269 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5270 attr
->default_val
->value
5271 = check_attr_value (attr
->default_val
->value
, attr
);
5274 return FATAL_EXIT_CODE
;
5276 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5277 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5280 /* Construct extra attributes for `length'. */
5281 make_length_attrs ();
5283 /* Perform any possible optimizations to speed up compilation. */
5286 /* Now write out all the `gen_attr_...' routines. Do these before the
5287 special routines so that they get defined before they are used. */
5289 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5290 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5294 #define IS_ATTR_GROUP(X) (!strncmp(attr->name,X,strlen(X)))
5295 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5297 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5298 outf
= latency_file
;
5301 #undef IS_ATTR_GROUP
5303 if (! attr
->is_special
&& ! attr
->is_const
)
5304 write_attr_get (outf
, attr
);
5307 /* Write out delay eligibility information, if DEFINE_DELAY present.
5308 (The function to compute the number of delay slots will be written
5312 write_eligible_delay (attr_file
, "delay");
5313 if (have_annul_true
)
5314 write_eligible_delay (attr_file
, "annul_true");
5315 if (have_annul_false
)
5316 write_eligible_delay (attr_file
, "annul_false");
5319 /* Write out constant delay slot info. */
5320 write_const_num_delay_slots (attr_file
);
5322 write_length_unit_log (attr_file
);
5324 if (fclose (attr_file
) != 0)
5325 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5326 if (fclose (dfa_file
) != 0)
5327 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5328 if (fclose (latency_file
) != 0)
5329 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5331 return SUCCESS_EXIT_CODE
;