1 /* Generate code from machine description to compute values of attributes.
2 Copyright (C) 1991-2020 Free Software Foundation, Inc.
3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This program handles insn attributes and the DEFINE_DELAY and
22 DEFINE_INSN_RESERVATION definitions.
24 It produces a series of functions named `get_attr_...', one for each insn
25 attribute. Each of these is given the rtx for an insn and returns a member
26 of the enum for the attribute.
28 These subroutines have the form of a `switch' on the INSN_CODE (via
29 `recog_memoized'). Each case either returns a constant attribute value
30 or a value that depends on tests on other attributes, the form of
31 operands, or some random C expression (encoded with a SYMBOL_REF
34 If the attribute `alternative', or a random C expression is present,
35 `constrain_operands' is called. If either of these cases of a reference to
36 an operand is found, `extract_insn' is called.
38 The special attribute `length' is also recognized. For this operand,
39 expressions involving the address of an operand or the current insn,
40 (address (pc)), are valid. In this case, an initial pass is made to
41 set all lengths that do not depend on address. Those that do are set to
42 the maximum length. Then each insn that depends on an address is checked
43 and possibly has its length changed. The process repeats until no further
44 changed are made. The resulting lengths are saved for use by
47 A special form of DEFINE_ATTR, where the expression for default value is a
48 CONST expression, indicates an attribute that is constant for a given run
49 of the compiler. The subroutine generated for these attributes has no
50 parameters as it does not depend on any particular insn. Constant
51 attributes are typically used to specify which variety of processor is
54 Internal attributes are defined to handle DEFINE_DELAY and
55 DEFINE_INSN_RESERVATION. Special routines are output for these cases.
57 This program works by keeping a list of possible values for each attribute.
58 These include the basic attribute choices, default values for attribute, and
59 all derived quantities.
61 As the description file is read, the definition for each insn is saved in a
62 `struct insn_def'. When the file reading is complete, a `struct insn_ent'
63 is created for each insn and chained to the corresponding attribute value,
64 either that specified, or the default.
66 An optimization phase is then run. This simplifies expressions for each
67 insn. EQ_ATTR tests are resolved, whenever possible, to a test that
68 indicates when the attribute has the specified value for the insn. This
69 avoids recursive calls during compilation.
71 The strategy used when processing DEFINE_DELAY definitions is to create
72 arbitrarily complex expressions and have the optimization simplify them.
74 Once optimization is complete, any required routines and definitions
77 An optimization that is not yet implemented is to hoist the constant
78 expressions entirely out of the routines and definitions that are written.
79 A way to do this is to iterate over all possible combinations of values
80 for constant attributes and generate a set of functions for that given
81 combination. An initialization function would be written that evaluates
82 the attributes and installs the corresponding set of routines and
83 definitions (each would be accessed through a pointer).
85 We use the flags in an RTX as follows:
86 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified
87 independent of the insn code.
88 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified
89 for the insn code currently being processed (see optimize_attrs).
90 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique
93 #define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), unchanging))
94 #define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), in_struct))
95 #define ATTR_PERMANENT_P(RTX) (RTX_FLAG ((RTX), return_val))
98 #define strcmp_check(S1, S2) ((S1) == (S2) \
100 : (gcc_assert (strcmp ((S1), (S2))), 1))
102 #define strcmp_check(S1, S2) ((S1) != (S2))
107 #include "coretypes.h"
113 #include "gensupport.h"
118 /* Flags for make_internal_attr's `special' parameter. */
120 #define ATTR_SPECIAL (1 << 0)
122 static struct obstack obstack1
, obstack2
;
123 static struct obstack
*hash_obstack
= &obstack1
;
124 static struct obstack
*temp_obstack
= &obstack2
;
126 /* enough space to reserve for printing out ints */
127 #define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3)
129 /* Define structures used to record attributes and values. */
131 /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
132 encountered, we store all the relevant information into a
133 `struct insn_def'. This is done to allow attribute definitions to occur
134 anywhere in the file. */
139 class insn_def
*next
; /* Next insn in chain. */
140 rtx def
; /* The DEFINE_... */
141 int insn_code
; /* Instruction number. */
142 int insn_index
; /* Expression number in file, for errors. */
143 file_location loc
; /* Where in the .md files it occurs. */
144 int num_alternatives
; /* Number of alternatives. */
145 int vec_idx
; /* Index of attribute vector in `def'. */
148 /* Once everything has been read in, we store in each attribute value a list
149 of insn codes that have that value. Here is the structure used for the
154 struct insn_ent
*next
; /* Next in chain. */
155 class insn_def
*def
; /* Instruction definition. */
158 /* Each value of an attribute (either constant or computed) is assigned a
159 structure which is used as the listhead of the insns that have that
164 rtx value
; /* Value of attribute. */
165 struct attr_value
*next
; /* Next attribute value in chain. */
166 struct insn_ent
*first_insn
; /* First insn with this value. */
167 int num_insns
; /* Number of insns with this value. */
168 int has_asm_insn
; /* True if this value used for `asm' insns */
171 /* Structure for each attribute. */
176 char *name
; /* Name of attribute. */
177 const char *enum_name
; /* Enum name for DEFINE_ENUM_NAME. */
178 class attr_desc
*next
; /* Next attribute. */
179 struct attr_value
*first_value
; /* First value of this attribute. */
180 struct attr_value
*default_val
; /* Default value for this attribute. */
181 file_location loc
; /* Where in the .md files it occurs. */
182 unsigned is_numeric
: 1; /* Values of this attribute are numeric. */
183 unsigned is_const
: 1; /* Attribute value constant for each run. */
184 unsigned is_special
: 1; /* Don't call `write_attr_set'. */
187 /* Structure for each DEFINE_DELAY. */
192 rtx def
; /* DEFINE_DELAY expression. */
193 class delay_desc
*next
; /* Next DEFINE_DELAY. */
194 file_location loc
; /* Where in the .md files it occurs. */
195 int num
; /* Number of DEFINE_DELAY, starting at 1. */
198 struct attr_value_list
200 struct attr_value
*av
;
202 class 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 class attr_desc
*attrs
[MAX_ATTRS_INDEX
];
211 static class insn_def
*defs
;
212 static class delay_desc
*delays
;
213 struct attr_value_list
**insn_code_values
;
215 /* Other variables. */
217 static int insn_index_number
;
218 static int got_define_asm_attributes
;
219 static int must_extract
;
220 static int must_constrain
;
221 static int address_used
;
222 static int length_used
;
223 static int num_delays
;
224 static int have_annul_true
, have_annul_false
;
225 static int num_insn_ents
;
227 /* Stores, for each insn code, the number of constraint alternatives. */
229 static int *insn_n_alternatives
;
231 /* Stores, for each insn code, a bitmap that has bits on for each possible
234 /* Keep this in sync with recog.h. */
235 typedef uint64_t alternative_mask
;
236 static alternative_mask
*insn_alternatives
;
238 /* Used to simplify expressions. */
240 static rtx true_rtx
, false_rtx
;
242 /* Used to reduce calls to `strcmp' */
244 static const char *alternative_name
;
245 static const char *length_str
;
246 static const char *delay_type_str
;
247 static const char *delay_1_0_str
;
248 static const char *num_delay_slots_str
;
250 /* Simplify an expression. Only call the routine if there is something to
252 #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \
253 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \
254 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
256 #define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S)))
258 /* Forward declarations of functions used before their definitions, only. */
259 static char *attr_string (const char *, int);
260 static char *attr_printf (unsigned int, const char *, ...)
262 static rtx
make_numeric_value (int);
263 static class attr_desc
*find_attr (const char **, int);
264 static rtx
mk_attr_alt (alternative_mask
);
265 static char *next_comma_elt (const char **);
266 static rtx
insert_right_side (enum rtx_code
, rtx
, rtx
, int, int);
267 static rtx
copy_boolean (rtx
);
268 static int compares_alternatives_p (rtx
);
269 static void make_internal_attr (const char *, rtx
, int);
270 static void insert_insn_ent (struct attr_value
*, struct insn_ent
*);
271 static void walk_attr_value (rtx
);
272 static int max_attr_value (rtx
);
273 static int min_attr_value (rtx
);
274 static unsigned int attr_value_alignment (rtx
);
275 static rtx
simplify_test_exp (rtx
, int, int);
276 static rtx
simplify_test_exp_in_temp (rtx
, int, int);
277 static rtx
copy_rtx_unchanging (rtx
);
278 static bool attr_alt_subset_p (rtx
, rtx
);
279 static bool attr_alt_subset_of_compl_p (rtx
, rtx
);
280 static void clear_struct_flag (rtx
);
281 static void write_attr_valueq (FILE *, class attr_desc
*, const char *);
282 static struct attr_value
*find_most_used (class attr_desc
*);
283 static void write_attr_set (FILE *, class attr_desc
*, int, rtx
,
284 const char *, const char *, rtx
,
285 int, int, unsigned int);
286 static void write_attr_case (FILE *, class attr_desc
*,
288 int, const char *, const char *, int, rtx
);
289 static void write_attr_value (FILE *, class attr_desc
*, rtx
);
290 static void write_upcase (FILE *, const char *);
291 static void write_indent (FILE *, int);
292 static rtx
identity_fn (rtx
);
293 static rtx
zero_fn (rtx
);
294 static rtx
one_fn (rtx
);
295 static rtx
max_fn (rtx
);
296 static rtx
min_fn (rtx
);
298 #define oballoc(T) XOBNEW (hash_obstack, T)
299 #define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N))
301 /* This gen* file is unique, in that it writes out multiple files.
303 Before GCC 4.8, insn-attrtab.c was written out containing many large
304 functions and tables. This made insn-attrtab.c _the_ bottle-neck in
305 a parallel build, and even made it impossible to build GCC on machines
306 with relatively small RAM space (PR other/29442). Therefore, the
307 atrribute functions/tables are now written out to three separate
308 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME,
309 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the
310 rest goes to ATTR_FILE_NAME. */
312 static const char *attr_file_name
= NULL
;
313 static const char *dfa_file_name
= NULL
;
314 static const char *latency_file_name
= NULL
;
316 static FILE *attr_file
, *dfa_file
, *latency_file
;
318 /* Hash table for sharing RTL and strings. */
320 /* Each hash table slot is a bucket containing a chain of these structures.
321 Strings are given negative hash codes; RTL expressions are given positive
326 struct attr_hash
*next
; /* Next structure in the bucket. */
327 unsigned int hashcode
; /* Hash code of this rtx or string. */
330 char *str
; /* The string (negative hash codes) */
331 rtx rtl
; /* or the RTL recorded here. */
335 /* Now here is the hash table. When recording an RTL, it is added to
336 the slot whose index is the hash code mod the table size. Note
337 that the hash table is used for several kinds of RTL (see attr_rtx)
338 and for strings. While all these live in the same table, they are
339 completely independent, and the hash code is computed differently
342 #define RTL_HASH_SIZE 4093
343 static struct attr_hash
*attr_hash_table
[RTL_HASH_SIZE
];
345 /* Here is how primitive or already-shared RTL's hash
347 #define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777)
349 /* Add an entry to the hash table for RTL with hash code HASHCODE. */
352 attr_hash_add_rtx (unsigned int hashcode
, rtx rtl
)
356 h
= XOBNEW (hash_obstack
, struct attr_hash
);
357 h
->hashcode
= hashcode
;
359 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
360 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
363 /* Add an entry to the hash table for STRING with hash code HASHCODE. */
366 attr_hash_add_string (unsigned int hashcode
, char *str
)
370 h
= XOBNEW (hash_obstack
, struct attr_hash
);
371 h
->hashcode
= -hashcode
;
373 h
->next
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
];
374 attr_hash_table
[hashcode
% RTL_HASH_SIZE
] = h
;
377 /* Generate an RTL expression, but avoid duplicates.
378 Set the ATTR_PERMANENT_P flag for these permanent objects.
380 In some cases we cannot uniquify; then we return an ordinary
381 impermanent rtx with ATTR_PERMANENT_P clear.
385 rtx attr_rtx (code, [element1, ..., elementn]) */
388 attr_rtx_1 (enum rtx_code code
, va_list p
)
390 rtx rt_val
= NULL_RTX
;/* RTX to return to caller... */
391 unsigned int hashcode
;
393 struct obstack
*old_obstack
= rtl_obstack
;
396 /* For each of several cases, search the hash table for an existing entry.
397 Use that entry if one is found; otherwise create a new RTL and add it
400 if (GET_RTX_CLASS (code
) == RTX_UNARY
)
402 rtx arg0
= va_arg (p
, rtx
);
404 if (! ATTR_PERMANENT_P (arg0
))
407 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
408 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
409 if (h
->hashcode
== hashcode
410 && GET_CODE (h
->u
.rtl
) == code
411 && XEXP (h
->u
.rtl
, 0) == arg0
)
416 rtl_obstack
= hash_obstack
;
417 rt_val
= rtx_alloc (code
);
418 XEXP (rt_val
, 0) = arg0
;
421 else if (GET_RTX_CLASS (code
) == RTX_BIN_ARITH
422 || GET_RTX_CLASS (code
) == RTX_COMM_ARITH
423 || GET_RTX_CLASS (code
) == RTX_COMPARE
424 || GET_RTX_CLASS (code
) == RTX_COMM_COMPARE
)
426 rtx arg0
= va_arg (p
, rtx
);
427 rtx arg1
= va_arg (p
, rtx
);
429 if (! ATTR_PERMANENT_P (arg0
) || ! ATTR_PERMANENT_P (arg1
))
432 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
433 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
434 if (h
->hashcode
== hashcode
435 && GET_CODE (h
->u
.rtl
) == code
436 && XEXP (h
->u
.rtl
, 0) == arg0
437 && XEXP (h
->u
.rtl
, 1) == arg1
)
439 ATTR_CURR_SIMPLIFIED_P (h
->u
.rtl
) = 0;
445 rtl_obstack
= hash_obstack
;
446 rt_val
= rtx_alloc (code
);
447 XEXP (rt_val
, 0) = arg0
;
448 XEXP (rt_val
, 1) = arg1
;
451 else if (code
== SYMBOL_REF
452 || (GET_RTX_LENGTH (code
) == 1
453 && GET_RTX_FORMAT (code
)[0] == 's'))
455 char *arg0
= va_arg (p
, char *);
457 arg0
= DEF_ATTR_STRING (arg0
);
459 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
));
460 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
461 if (h
->hashcode
== hashcode
462 && GET_CODE (h
->u
.rtl
) == code
463 && XSTR (h
->u
.rtl
, 0) == arg0
)
468 rtl_obstack
= hash_obstack
;
469 rt_val
= rtx_alloc (code
);
470 XSTR (rt_val
, 0) = arg0
;
471 if (code
== SYMBOL_REF
)
472 X0EXP (rt_val
, 1) = NULL_RTX
;
475 else if (GET_RTX_LENGTH (code
) == 2
476 && GET_RTX_FORMAT (code
)[0] == 's'
477 && GET_RTX_FORMAT (code
)[1] == 's')
479 char *arg0
= va_arg (p
, char *);
480 char *arg1
= va_arg (p
, char *);
482 arg0
= DEF_ATTR_STRING (arg0
);
483 arg1
= DEF_ATTR_STRING (arg1
);
485 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
486 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
487 if (h
->hashcode
== hashcode
488 && GET_CODE (h
->u
.rtl
) == code
489 && XSTR (h
->u
.rtl
, 0) == arg0
490 && XSTR (h
->u
.rtl
, 1) == arg1
)
495 rtl_obstack
= hash_obstack
;
496 rt_val
= rtx_alloc (code
);
497 XSTR (rt_val
, 0) = arg0
;
498 XSTR (rt_val
, 1) = arg1
;
501 else if (GET_RTX_LENGTH (code
) == 2
502 && GET_RTX_FORMAT (code
)[0] == 'w'
503 && GET_RTX_FORMAT (code
)[1] == 'w')
505 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
506 HOST_WIDE_INT arg1
= va_arg (p
, HOST_WIDE_INT
);
508 hashcode
= ((HOST_WIDE_INT
) code
+ RTL_HASH (arg0
) + RTL_HASH (arg1
));
509 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
510 if (h
->hashcode
== hashcode
511 && GET_CODE (h
->u
.rtl
) == code
512 && XWINT (h
->u
.rtl
, 0) == arg0
513 && XWINT (h
->u
.rtl
, 1) == arg1
)
518 rtl_obstack
= hash_obstack
;
519 rt_val
= rtx_alloc (code
);
520 XWINT (rt_val
, 0) = arg0
;
521 XWINT (rt_val
, 1) = arg1
;
524 else if (code
== CONST_INT
)
526 HOST_WIDE_INT arg0
= va_arg (p
, HOST_WIDE_INT
);
536 int i
; /* Array indices... */
537 const char *fmt
; /* Current rtx's format... */
539 rt_val
= rtx_alloc (code
); /* Allocate the storage space. */
541 fmt
= GET_RTX_FORMAT (code
); /* Find the right format... */
542 for (i
= 0; i
< GET_RTX_LENGTH (code
); i
++)
546 case '0': /* Unused field. */
549 case 'i': /* An integer? */
550 XINT (rt_val
, i
) = va_arg (p
, int);
553 case 'w': /* A wide integer? */
554 XWINT (rt_val
, i
) = va_arg (p
, HOST_WIDE_INT
);
557 case 's': /* A string? */
558 XSTR (rt_val
, i
) = va_arg (p
, char *);
561 case 'e': /* An expression? */
562 case 'u': /* An insn? Same except when printing. */
563 XEXP (rt_val
, i
) = va_arg (p
, rtx
);
566 case 'E': /* An RTX vector? */
567 XVEC (rt_val
, i
) = va_arg (p
, rtvec
);
571 /* Don't need to handle 'p' for attributes. */
578 rtl_obstack
= old_obstack
;
579 attr_hash_add_rtx (hashcode
, rt_val
);
580 ATTR_PERMANENT_P (rt_val
) = permanent_p
;
585 attr_rtx (enum rtx_code code
, ...)
591 result
= attr_rtx_1 (code
, p
);
596 /* Create a new string printed with the printf line arguments into a space
597 of at most LEN bytes:
599 rtx attr_printf (len, format, [arg1, ..., argn]) */
602 attr_printf (unsigned int len
, const char *fmt
, ...)
609 gcc_assert (len
< sizeof str
); /* Leave room for \0. */
611 vsprintf (str
, fmt
, p
);
614 return DEF_ATTR_STRING (str
);
618 attr_eq (const char *name
, const char *value
)
620 return attr_rtx (EQ_ATTR
, name
, value
);
626 return XSTR (make_numeric_value (n
), 0);
629 /* Return a permanent (possibly shared) copy of a string STR (not assumed
630 to be null terminated) with LEN bytes. */
633 attr_string (const char *str
, int len
)
636 unsigned int hashcode
;
640 /* Compute the hash code. */
641 hashcode
= (len
+ 1) * 613U + (unsigned) str
[0];
642 for (i
= 1; i
< len
; i
+= 2)
643 hashcode
= ((hashcode
* 613) + (unsigned) str
[i
]);
644 if ((int) hashcode
< 0)
645 hashcode
= -hashcode
;
647 /* Search the table for the string. */
648 for (h
= attr_hash_table
[hashcode
% RTL_HASH_SIZE
]; h
; h
= h
->next
)
649 if (h
->hashcode
== -hashcode
&& h
->u
.str
[0] == str
[0]
650 && !strncmp (h
->u
.str
, str
, len
))
651 return h
->u
.str
; /* <-- return if found. */
653 /* Not found; create a permanent copy and add it to the hash table. */
654 new_str
= XOBNEWVAR (hash_obstack
, char, len
+ 1);
655 memcpy (new_str
, str
, len
);
657 attr_hash_add_string (hashcode
, new_str
);
658 rtx_reader_ptr
->copy_md_ptr_loc (new_str
, str
);
660 return new_str
; /* Return the new string. */
663 /* Check two rtx's for equality of contents,
664 taking advantage of the fact that if both are hashed
665 then they can't be equal unless they are the same object. */
668 attr_equal_p (rtx x
, rtx y
)
670 return (x
== y
|| (! (ATTR_PERMANENT_P (x
) && ATTR_PERMANENT_P (y
))
671 && rtx_equal_p (x
, y
)));
674 /* Given a test expression EXP for attribute ATTR, ensure it is validly
675 formed. LOC is the location of the .md construct that contains EXP.
677 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
678 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter
679 test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
681 Update the string address in EQ_ATTR expression to be the same used
682 in the attribute (or `alternative_name') to speed up subsequent
683 `find_attr' calls and eliminate most `strcmp' calls.
685 Return the new expression, if any. */
688 check_attr_test (file_location loc
, rtx exp
, attr_desc
*attr
)
690 struct attr_value
*av
;
691 const char *name_ptr
, *p
;
694 switch (GET_CODE (exp
))
697 /* Handle negation test. */
698 if (XSTR (exp
, 1)[0] == '!')
699 return check_attr_test (loc
,
701 attr_eq (XSTR (exp
, 0),
705 else if (n_comma_elts (XSTR (exp
, 1)) == 1)
707 attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
710 if (! strcmp (XSTR (exp
, 0), "alternative"))
711 return mk_attr_alt (((alternative_mask
) 1)
712 << atoi (XSTR (exp
, 1)));
714 fatal_at (loc
, "unknown attribute `%s' in definition of"
715 " attribute `%s'", XSTR (exp
, 0), attr
->name
);
718 if (attr
->is_const
&& ! attr2
->is_const
)
719 fatal_at (loc
, "constant attribute `%s' cannot test non-constant"
720 " attribute `%s'", attr
->name
, attr2
->name
);
722 /* Copy this just to make it permanent,
723 so expressions using it can be permanent too. */
724 exp
= attr_eq (XSTR (exp
, 0), XSTR (exp
, 1));
726 /* It shouldn't be possible to simplify the value given to a
727 constant attribute, so don't expand this until it's time to
728 write the test expression. */
730 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
732 if (attr2
->is_numeric
)
734 for (p
= XSTR (exp
, 1); *p
; p
++)
736 fatal_at (loc
, "attribute `%s' takes only numeric values",
741 for (av
= attr2
->first_value
; av
; av
= av
->next
)
742 if (GET_CODE (av
->value
) == CONST_STRING
743 && ! strcmp (XSTR (exp
, 1), XSTR (av
->value
, 0)))
747 fatal_at (loc
, "unknown value `%s' for attribute `%s'",
748 XSTR (exp
, 1), attr2
->name
);
753 if (! strcmp (XSTR (exp
, 0), "alternative"))
757 name_ptr
= XSTR (exp
, 1);
758 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
759 set
|= ((alternative_mask
) 1) << atoi (p
);
761 return mk_attr_alt (set
);
765 /* Make an IOR tree of the possible values. */
767 name_ptr
= XSTR (exp
, 1);
768 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
770 newexp
= attr_eq (XSTR (exp
, 0), p
);
771 orexp
= insert_right_side (IOR
, orexp
, newexp
, -2, -2);
774 return check_attr_test (loc
, orexp
, attr
);
783 /* Either TRUE or FALSE. */
791 XEXP (exp
, 0) = check_attr_test (loc
, XEXP (exp
, 0), attr
);
792 XEXP (exp
, 1) = check_attr_test (loc
, XEXP (exp
, 1), attr
);
796 XEXP (exp
, 0) = check_attr_test (loc
, XEXP (exp
, 0), attr
);
800 exp
= attr_rtx (MATCH_TEST
, XSTR (exp
, 0));
801 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
806 fatal_at (loc
, "invalid operator `%s' in definition of constant"
807 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp
)),
809 /* These cases can't be simplified. */
810 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
813 case LE
: case LT
: case GT
: case GE
:
814 case LEU
: case LTU
: case GTU
: case GEU
:
816 if (GET_CODE (XEXP (exp
, 0)) == SYMBOL_REF
817 && GET_CODE (XEXP (exp
, 1)) == SYMBOL_REF
)
818 exp
= attr_rtx (GET_CODE (exp
),
819 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 0), 0)),
820 attr_rtx (SYMBOL_REF
, XSTR (XEXP (exp
, 1), 0)));
821 /* These cases can't be simplified. */
822 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
828 /* These cases are valid for constant attributes, but can't be
830 exp
= attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
831 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
836 fatal_at (loc
, "invalid operator `%s' in definition of attribute"
837 " `%s'", GET_RTX_NAME (GET_CODE (exp
)), attr
->name
);
843 /* Given an expression EXP, ensure that it is validly formed and that
844 all named attribute values are valid for ATTR. Issue an error if not.
845 LOC is the location of the .md construct that contains EXP.
847 Return a perhaps modified replacement expression for the value. */
850 check_attr_value (file_location loc
, rtx exp
, class attr_desc
*attr
)
852 struct attr_value
*av
;
856 switch (GET_CODE (exp
))
859 if (!attr
->is_numeric
)
862 "CONST_INT not valid for non-numeric attribute `%s'",
867 if (INTVAL (exp
) < 0)
870 "negative numeric value specified for attribute `%s'",
877 if (! strcmp (XSTR (exp
, 0), "*"))
880 if (attr
->is_numeric
)
887 "non-numeric value specified for numeric"
888 " attribute `%s'", attr
->name
);
894 for (av
= attr
->first_value
; av
; av
= av
->next
)
895 if (GET_CODE (av
->value
) == CONST_STRING
896 && ! strcmp (XSTR (av
->value
, 0), XSTR (exp
, 0)))
900 error_at (loc
, "unknown value `%s' for attribute `%s'",
901 XSTR (exp
, 0), attr
->name
);
905 XEXP (exp
, 0) = check_attr_test (loc
, XEXP (exp
, 0), attr
);
906 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
907 XEXP (exp
, 2) = check_attr_value (loc
, XEXP (exp
, 2), attr
);
915 if (!attr
->is_numeric
)
917 error_at (loc
, "invalid operation `%s' for non-numeric"
918 " attribute `%s'", GET_RTX_NAME (GET_CODE (exp
)),
926 XEXP (exp
, 0) = check_attr_value (loc
, XEXP (exp
, 0), attr
);
927 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
936 XEXP (exp
, 0) = check_attr_value (loc
, XEXP (exp
, 0), attr
);
940 if (XVECLEN (exp
, 0) % 2 != 0)
942 error_at (loc
, "first operand of COND must have even length");
946 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
948 XVECEXP (exp
, 0, i
) = check_attr_test (attr
->loc
,
951 XVECEXP (exp
, 0, i
+ 1)
952 = check_attr_value (loc
, XVECEXP (exp
, 0, i
+ 1), attr
);
955 XEXP (exp
, 1) = check_attr_value (loc
, XEXP (exp
, 1), attr
);
960 class attr_desc
*attr2
= find_attr (&XSTR (exp
, 0), 0);
962 error_at (loc
, "unknown attribute `%s' in ATTR",
964 else if (attr
->is_const
&& ! attr2
->is_const
)
966 "constant attribute `%s' cannot refer to non-constant"
967 " attribute `%s'", attr
->name
, attr2
->name
);
968 else if (attr
->is_numeric
!= attr2
->is_numeric
)
970 "numeric attribute mismatch calling `%s' from `%s'",
971 attr2
->name
, attr
->name
);
976 /* A constant SYMBOL_REF is valid as a constant attribute test and
977 is expanded later by make_canonical into a COND. In a non-constant
978 attribute test, it is left be. */
979 return attr_rtx (SYMBOL_REF
, XSTR (exp
, 0));
982 error_at (loc
, "invalid operator `%s' in definition of attribute `%s'",
983 GET_RTX_NAME (GET_CODE (exp
)), attr
->name
);
990 /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
991 It becomes a COND with each test being (eq_attr "alternative" "n") */
994 convert_set_attr_alternative (rtx exp
, class insn_def
*id
)
996 int num_alt
= id
->num_alternatives
;
1000 if (XVECLEN (exp
, 1) != num_alt
)
1002 error_at (id
->loc
, "bad number of entries in SET_ATTR_ALTERNATIVE,"
1003 " was %d expected %d", XVECLEN (exp
, 1), num_alt
);
1007 /* Make a COND with all tests but the last. Select the last value via the
1009 condexp
= rtx_alloc (COND
);
1010 XVEC (condexp
, 0) = rtvec_alloc ((num_alt
- 1) * 2);
1012 for (i
= 0; i
< num_alt
- 1; i
++)
1015 p
= attr_numeral (i
);
1017 XVECEXP (condexp
, 0, 2 * i
) = attr_eq (alternative_name
, p
);
1018 XVECEXP (condexp
, 0, 2 * i
+ 1) = XVECEXP (exp
, 1, i
);
1021 XEXP (condexp
, 1) = XVECEXP (exp
, 1, i
);
1023 return attr_rtx (SET
, attr_rtx (ATTR
, XSTR (exp
, 0)), condexp
);
1026 /* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated
1027 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */
1030 convert_set_attr (rtx exp
, class insn_def
*id
)
1033 const char *name_ptr
;
1037 /* See how many alternative specified. */
1038 n
= n_comma_elts (XSTR (exp
, 1));
1040 return attr_rtx (SET
,
1041 attr_rtx (ATTR
, XSTR (exp
, 0)),
1042 attr_rtx (CONST_STRING
, XSTR (exp
, 1)));
1044 newexp
= rtx_alloc (SET_ATTR_ALTERNATIVE
);
1045 XSTR (newexp
, 0) = XSTR (exp
, 0);
1046 XVEC (newexp
, 1) = rtvec_alloc (n
);
1048 /* Process each comma-separated name. */
1049 name_ptr
= XSTR (exp
, 1);
1051 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
1052 XVECEXP (newexp
, 1, n
++) = attr_rtx (CONST_STRING
, p
);
1054 return convert_set_attr_alternative (newexp
, id
);
1057 /* Scan all definitions, checking for validity. Also, convert any SET_ATTR
1058 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
1065 class attr_desc
*attr
;
1069 for (id
= defs
; id
; id
= id
->next
)
1071 if (XVEC (id
->def
, id
->vec_idx
) == NULL
)
1074 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1076 value
= XVECEXP (id
->def
, id
->vec_idx
, i
);
1077 switch (GET_CODE (value
))
1080 if (GET_CODE (XEXP (value
, 0)) != ATTR
)
1082 error_at (id
->loc
, "bad attribute set");
1087 case SET_ATTR_ALTERNATIVE
:
1088 value
= convert_set_attr_alternative (value
, id
);
1092 value
= convert_set_attr (value
, id
);
1096 error_at (id
->loc
, "invalid attribute code %s",
1097 GET_RTX_NAME (GET_CODE (value
)));
1100 if (value
== NULL_RTX
)
1103 if ((attr
= find_attr (&XSTR (XEXP (value
, 0), 0), 0)) == NULL
)
1105 error_at (id
->loc
, "unknown attribute %s",
1106 XSTR (XEXP (value
, 0), 0));
1110 XVECEXP (id
->def
, id
->vec_idx
, i
) = value
;
1111 XEXP (value
, 1) = check_attr_value (id
->loc
, XEXP (value
, 1), attr
);
1116 /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
1117 expressions by converting them into a COND. This removes cases from this
1118 program. Also, replace an attribute value of "*" with the default attribute
1119 value. LOC is the location to use for error reporting. */
1122 make_canonical (file_location loc
, class attr_desc
*attr
, rtx exp
)
1127 switch (GET_CODE (exp
))
1130 exp
= make_numeric_value (INTVAL (exp
));
1134 if (! strcmp (XSTR (exp
, 0), "*"))
1136 if (attr
->default_val
== 0)
1137 fatal_at (loc
, "(attr_value \"*\") used in invalid context");
1138 exp
= attr
->default_val
->value
;
1141 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1146 if (!attr
->is_const
|| ATTR_IND_SIMPLIFIED_P (exp
))
1148 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging.
1149 This makes the COND something that won't be considered an arbitrary
1150 expression by walk_attr_value. */
1151 ATTR_IND_SIMPLIFIED_P (exp
) = 1;
1152 exp
= check_attr_value (loc
, exp
, attr
);
1156 newexp
= rtx_alloc (COND
);
1157 XVEC (newexp
, 0) = rtvec_alloc (2);
1158 XVECEXP (newexp
, 0, 0) = XEXP (exp
, 0);
1159 XVECEXP (newexp
, 0, 1) = XEXP (exp
, 1);
1161 XEXP (newexp
, 1) = XEXP (exp
, 2);
1164 /* Fall through to COND case since this is now a COND. */
1172 /* First, check for degenerate COND. */
1173 if (XVECLEN (exp
, 0) == 0)
1174 return make_canonical (loc
, attr
, XEXP (exp
, 1));
1175 defval
= XEXP (exp
, 1) = make_canonical (loc
, attr
, XEXP (exp
, 1));
1177 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1179 XVECEXP (exp
, 0, i
) = copy_boolean (XVECEXP (exp
, 0, i
));
1180 XVECEXP (exp
, 0, i
+ 1)
1181 = make_canonical (loc
, attr
, XVECEXP (exp
, 0, i
+ 1));
1182 if (! attr_equal_p (XVECEXP (exp
, 0, i
+ 1), defval
))
1198 copy_boolean (rtx exp
)
1200 if (GET_CODE (exp
) == AND
|| GET_CODE (exp
) == IOR
)
1201 return attr_rtx (GET_CODE (exp
), copy_boolean (XEXP (exp
, 0)),
1202 copy_boolean (XEXP (exp
, 1)));
1203 else if (GET_CODE (exp
) == NOT
)
1204 return attr_rtx (NOT
, copy_boolean (XEXP (exp
, 0)));
1205 if (GET_CODE (exp
) == MATCH_OPERAND
)
1207 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1208 XSTR (exp
, 2) = DEF_ATTR_STRING (XSTR (exp
, 2));
1210 else if (GET_CODE (exp
) == EQ_ATTR
)
1212 XSTR (exp
, 0) = DEF_ATTR_STRING (XSTR (exp
, 0));
1213 XSTR (exp
, 1) = DEF_ATTR_STRING (XSTR (exp
, 1));
1219 /* Given a value and an attribute description, return a `struct attr_value *'
1220 that represents that value. This is either an existing structure, if the
1221 value has been previously encountered, or a newly-created structure.
1223 `insn_code' is the code of an insn whose attribute has the specified
1224 value (-2 if not processing an insn). We ensure that all insns for
1225 a given value have the same number of alternatives if the value checks
1226 alternatives. LOC is the location to use for error reporting. */
1228 static struct attr_value
*
1229 get_attr_value (file_location loc
, rtx value
, class attr_desc
*attr
,
1232 struct attr_value
*av
;
1233 alternative_mask num_alt
= 0;
1235 value
= make_canonical (loc
, attr
, value
);
1236 if (compares_alternatives_p (value
))
1238 if (insn_code
< 0 || insn_alternatives
== NULL
)
1239 fatal_at (loc
, "(eq_attr \"alternatives\" ...) used in non-insn"
1242 num_alt
= insn_alternatives
[insn_code
];
1245 for (av
= attr
->first_value
; av
; av
= av
->next
)
1246 if (attr_equal_p (value
, av
->value
)
1247 && (num_alt
== 0 || av
->first_insn
== NULL
1248 || insn_alternatives
[av
->first_insn
->def
->insn_code
]))
1251 av
= oballoc (struct attr_value
);
1253 av
->next
= attr
->first_value
;
1254 attr
->first_value
= av
;
1255 av
->first_insn
= NULL
;
1257 av
->has_asm_insn
= 0;
1262 /* After all DEFINE_DELAYs have been read in, create internal attributes
1263 to generate the required routines.
1265 First, we compute the number of delay slots for each insn (as a COND of
1266 each of the test expressions in DEFINE_DELAYs). Then, if more than one
1267 delay type is specified, we compute a similar function giving the
1268 DEFINE_DELAY ordinal for each insn.
1270 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
1271 tells whether a given insn can be in that delay slot.
1273 Normal attribute filling and optimization expands these to contain the
1274 information needed to handle delay slots. */
1277 expand_delays (void)
1279 class delay_desc
*delay
;
1285 /* First, generate data for `num_delay_slots' function. */
1287 condexp
= rtx_alloc (COND
);
1288 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1289 XEXP (condexp
, 1) = make_numeric_value (0);
1291 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1293 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1294 XVECEXP (condexp
, 0, i
+ 1)
1295 = make_numeric_value (XVECLEN (delay
->def
, 1) / 3);
1298 make_internal_attr (num_delay_slots_str
, condexp
, ATTR_NONE
);
1300 /* If more than one delay type, do the same for computing the delay type. */
1303 condexp
= rtx_alloc (COND
);
1304 XVEC (condexp
, 0) = rtvec_alloc (num_delays
* 2);
1305 XEXP (condexp
, 1) = make_numeric_value (0);
1307 for (i
= 0, delay
= delays
; delay
; i
+= 2, delay
= delay
->next
)
1309 XVECEXP (condexp
, 0, i
) = XEXP (delay
->def
, 0);
1310 XVECEXP (condexp
, 0, i
+ 1) = make_numeric_value (delay
->num
);
1313 make_internal_attr (delay_type_str
, condexp
, ATTR_SPECIAL
);
1316 /* For each delay possibility and delay slot, compute an eligibility
1317 attribute for non-annulled insns and for each type of annulled (annul
1318 if true and annul if false). */
1319 for (delay
= delays
; delay
; delay
= delay
->next
)
1321 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
1323 condexp
= XVECEXP (delay
->def
, 1, i
);
1325 condexp
= false_rtx
;
1326 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1327 make_numeric_value (1), make_numeric_value (0));
1329 p
= attr_printf (sizeof "*delay__" + MAX_DIGITS
* 2,
1330 "*delay_%d_%d", delay
->num
, i
/ 3);
1331 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1333 if (have_annul_true
)
1335 condexp
= XVECEXP (delay
->def
, 1, i
+ 1);
1336 if (condexp
== 0) condexp
= false_rtx
;
1337 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1338 make_numeric_value (1),
1339 make_numeric_value (0));
1340 p
= attr_printf (sizeof "*annul_true__" + MAX_DIGITS
* 2,
1341 "*annul_true_%d_%d", delay
->num
, i
/ 3);
1342 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1345 if (have_annul_false
)
1347 condexp
= XVECEXP (delay
->def
, 1, i
+ 2);
1348 if (condexp
== 0) condexp
= false_rtx
;
1349 newexp
= attr_rtx (IF_THEN_ELSE
, condexp
,
1350 make_numeric_value (1),
1351 make_numeric_value (0));
1352 p
= attr_printf (sizeof "*annul_false__" + MAX_DIGITS
* 2,
1353 "*annul_false_%d_%d", delay
->num
, i
/ 3);
1354 make_internal_attr (p
, newexp
, ATTR_SPECIAL
);
1360 /* Once all attributes and insns have been read and checked, we construct for
1361 each attribute value a list of all the insns that have that value for
1365 fill_attr (class attr_desc
*attr
)
1367 struct attr_value
*av
;
1368 struct insn_ent
*ie
;
1373 /* Don't fill constant attributes. The value is independent of
1374 any particular insn. */
1378 for (id
= defs
; id
; id
= id
->next
)
1380 /* If no value is specified for this insn for this attribute, use the
1383 if (XVEC (id
->def
, id
->vec_idx
))
1384 for (i
= 0; i
< XVECLEN (id
->def
, id
->vec_idx
); i
++)
1385 if (! strcmp_check (XSTR (XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 0), 0),
1387 value
= XEXP (XVECEXP (id
->def
, id
->vec_idx
, i
), 1);
1390 av
= attr
->default_val
;
1392 av
= get_attr_value (id
->loc
, value
, attr
, id
->insn_code
);
1394 ie
= oballoc (struct insn_ent
);
1396 insert_insn_ent (av
, ie
);
1400 /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
1401 test that checks relative positions of insns (uses MATCH_DUP or PC).
1402 If so, replace it with what is obtained by passing the expression to
1403 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine
1404 recursively on each value (including the default value). Otherwise,
1405 return the value returned by NO_ADDRESS_FN applied to EXP. */
1408 substitute_address (rtx exp
, rtx (*no_address_fn
) (rtx
),
1409 rtx (*address_fn
) (rtx
))
1414 if (GET_CODE (exp
) == COND
)
1416 /* See if any tests use addresses. */
1418 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1419 walk_attr_value (XVECEXP (exp
, 0, i
));
1422 return (*address_fn
) (exp
);
1424 /* Make a new copy of this COND, replacing each element. */
1425 newexp
= rtx_alloc (COND
);
1426 XVEC (newexp
, 0) = rtvec_alloc (XVECLEN (exp
, 0));
1427 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
1429 XVECEXP (newexp
, 0, i
) = XVECEXP (exp
, 0, i
);
1430 XVECEXP (newexp
, 0, i
+ 1)
1431 = substitute_address (XVECEXP (exp
, 0, i
+ 1),
1432 no_address_fn
, address_fn
);
1435 XEXP (newexp
, 1) = substitute_address (XEXP (exp
, 1),
1436 no_address_fn
, address_fn
);
1441 else if (GET_CODE (exp
) == IF_THEN_ELSE
)
1444 walk_attr_value (XEXP (exp
, 0));
1446 return (*address_fn
) (exp
);
1448 return attr_rtx (IF_THEN_ELSE
,
1449 substitute_address (XEXP (exp
, 0),
1450 no_address_fn
, address_fn
),
1451 substitute_address (XEXP (exp
, 1),
1452 no_address_fn
, address_fn
),
1453 substitute_address (XEXP (exp
, 2),
1454 no_address_fn
, address_fn
));
1457 return (*no_address_fn
) (exp
);
1460 /* Make new attributes from the `length' attribute. The following are made,
1461 each corresponding to a function called from `shorten_branches' or
1464 *insn_default_length This is the length of the insn to be returned
1465 by `get_attr_length' before `shorten_branches'
1466 has been called. In each case where the length
1467 depends on relative addresses, the largest
1468 possible is used. This routine is also used
1469 to compute the initial size of the insn.
1471 *insn_variable_length_p This returns 1 if the insn's length depends
1472 on relative addresses, zero otherwise.
1474 *insn_current_length This is only called when it is known that the
1475 insn has a variable length and returns the
1476 current length, based on relative addresses.
1480 make_length_attrs (void)
1482 static const char *new_names
[] =
1484 "*insn_default_length",
1486 "*insn_variable_length_p",
1487 "*insn_current_length"
1489 static rtx (*const no_address_fn
[]) (rtx
)
1490 = {identity_fn
,identity_fn
, zero_fn
, zero_fn
};
1491 static rtx (*const address_fn
[]) (rtx
)
1492 = {max_fn
, min_fn
, one_fn
, identity_fn
};
1494 class attr_desc
*length_attr
, *new_attr
;
1495 struct attr_value
*av
, *new_av
;
1496 struct insn_ent
*ie
, *new_ie
;
1498 /* See if length attribute is defined. If so, it must be numeric. Make
1499 it special so we don't output anything for it. */
1500 length_attr
= find_attr (&length_str
, 0);
1501 if (length_attr
== 0)
1504 if (! length_attr
->is_numeric
)
1505 fatal_at (length_attr
->loc
, "length attribute must be numeric");
1507 length_attr
->is_const
= 0;
1508 length_attr
->is_special
= 1;
1510 /* Make each new attribute, in turn. */
1511 for (i
= 0; i
< ARRAY_SIZE (new_names
); i
++)
1513 make_internal_attr (new_names
[i
],
1514 substitute_address (length_attr
->default_val
->value
,
1515 no_address_fn
[i
], address_fn
[i
]),
1517 new_attr
= find_attr (&new_names
[i
], 0);
1518 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1519 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1521 new_av
= get_attr_value (ie
->def
->loc
,
1522 substitute_address (av
->value
,
1525 new_attr
, ie
->def
->insn_code
);
1526 new_ie
= oballoc (struct insn_ent
);
1527 new_ie
->def
= ie
->def
;
1528 insert_insn_ent (new_av
, new_ie
);
1533 /* Utility functions called from above routine. */
1536 identity_fn (rtx exp
)
1542 zero_fn (rtx exp ATTRIBUTE_UNUSED
)
1544 return make_numeric_value (0);
1548 one_fn (rtx exp ATTRIBUTE_UNUSED
)
1550 return make_numeric_value (1);
1556 return make_numeric_value (max_attr_value (exp
));
1562 return make_numeric_value (min_attr_value (exp
));
1566 write_length_unit_log (FILE *outf
)
1568 class attr_desc
*length_attr
= find_attr (&length_str
, 0);
1569 struct attr_value
*av
;
1570 struct insn_ent
*ie
;
1571 unsigned int length_unit_log
, length_or
;
1575 length_or
= attr_value_alignment (length_attr
->default_val
->value
);
1576 for (av
= length_attr
->first_value
; av
; av
= av
->next
)
1577 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1578 length_or
|= attr_value_alignment (av
->value
);
1580 length_or
= ~length_or
;
1581 for (length_unit_log
= 0; length_or
& 1; length_or
>>= 1)
1585 length_unit_log
= 0;
1587 fprintf (outf
, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log
);
1590 /* Compute approximate cost of the expression. Used to decide whether
1591 expression is cheap enough for inline. */
1593 attr_rtx_cost (rtx x
)
1599 code
= GET_CODE (x
);
1612 /* Alternatives don't result into function call. */
1613 if (!strcmp_check (XSTR (x
, 0), alternative_name
))
1620 const char *fmt
= GET_RTX_FORMAT (code
);
1621 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
1627 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
1628 cost
+= attr_rtx_cost (XVECEXP (x
, i
, j
));
1631 cost
+= attr_rtx_cost (XEXP (x
, i
));
1641 /* Take a COND expression and see if any of the conditions in it can be
1642 simplified. If any are known true or known false for the particular insn
1643 code, the COND can be further simplified.
1645 Also call ourselves on any COND operations that are values of this COND.
1647 We do not modify EXP; rather, we make and return a new rtx. */
1650 simplify_cond (rtx exp
, int insn_code
, int insn_index
)
1653 /* We store the desired contents here,
1654 then build a new expression if they don't match EXP. */
1655 rtx defval
= XEXP (exp
, 1);
1656 rtx new_defval
= XEXP (exp
, 1);
1657 int len
= XVECLEN (exp
, 0);
1658 rtx
*tests
= XNEWVEC (rtx
, len
);
1662 /* This lets us free all storage allocated below, if appropriate. */
1663 obstack_finish (rtl_obstack
);
1665 memcpy (tests
, XVEC (exp
, 0)->elem
, len
* sizeof (rtx
));
1667 /* See if default value needs simplification. */
1668 if (GET_CODE (defval
) == COND
)
1669 new_defval
= simplify_cond (defval
, insn_code
, insn_index
);
1671 /* Simplify the subexpressions, and see what tests we can get rid of. */
1673 for (i
= 0; i
< len
; i
+= 2)
1675 rtx newtest
, newval
;
1677 /* Simplify this test. */
1678 newtest
= simplify_test_exp_in_temp (tests
[i
], insn_code
, insn_index
);
1681 newval
= tests
[i
+ 1];
1682 /* See if this value may need simplification. */
1683 if (GET_CODE (newval
) == COND
)
1684 newval
= simplify_cond (newval
, insn_code
, insn_index
);
1686 /* Look for ways to delete or combine this test. */
1687 if (newtest
== true_rtx
)
1689 /* If test is true, make this value the default
1690 and discard this + any following tests. */
1692 defval
= tests
[i
+ 1];
1693 new_defval
= newval
;
1696 else if (newtest
== false_rtx
)
1698 /* If test is false, discard it and its value. */
1699 for (j
= i
; j
< len
- 2; j
++)
1700 tests
[j
] = tests
[j
+ 2];
1705 else if (i
> 0 && attr_equal_p (newval
, tests
[i
- 1]))
1707 /* If this value and the value for the prev test are the same,
1711 = insert_right_side (IOR
, tests
[i
- 2], newtest
,
1712 insn_code
, insn_index
);
1714 /* Delete this test/value. */
1715 for (j
= i
; j
< len
- 2; j
++)
1716 tests
[j
] = tests
[j
+ 2];
1722 tests
[i
+ 1] = newval
;
1725 /* If the last test in a COND has the same value
1726 as the default value, that test isn't needed. */
1728 while (len
> 0 && attr_equal_p (tests
[len
- 1], new_defval
))
1731 /* See if we changed anything. */
1732 if (len
!= XVECLEN (exp
, 0) || new_defval
!= XEXP (exp
, 1))
1735 for (i
= 0; i
< len
; i
++)
1736 if (! attr_equal_p (tests
[i
], XVECEXP (exp
, 0, i
)))
1744 if (GET_CODE (defval
) == COND
)
1745 ret
= simplify_cond (defval
, insn_code
, insn_index
);
1753 rtx newexp
= rtx_alloc (COND
);
1755 XVEC (newexp
, 0) = rtvec_alloc (len
);
1756 memcpy (XVEC (newexp
, 0)->elem
, tests
, len
* sizeof (rtx
));
1757 XEXP (newexp
, 1) = new_defval
;
1764 /* Remove an insn entry from an attribute value. */
1767 remove_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1769 struct insn_ent
*previe
;
1771 if (av
->first_insn
== ie
)
1772 av
->first_insn
= ie
->next
;
1775 for (previe
= av
->first_insn
; previe
->next
!= ie
; previe
= previe
->next
)
1777 previe
->next
= ie
->next
;
1781 if (ie
->def
->insn_code
== -1)
1782 av
->has_asm_insn
= 0;
1787 /* Insert an insn entry in an attribute value list. */
1790 insert_insn_ent (struct attr_value
*av
, struct insn_ent
*ie
)
1792 ie
->next
= av
->first_insn
;
1793 av
->first_insn
= ie
;
1795 if (ie
->def
->insn_code
== -1)
1796 av
->has_asm_insn
= 1;
1801 /* This is a utility routine to take an expression that is a tree of either
1802 AND or IOR expressions and insert a new term. The new term will be
1803 inserted at the right side of the first node whose code does not match
1804 the root. A new node will be created with the root's code. Its left
1805 side will be the old right side and its right side will be the new
1808 If the `term' is itself a tree, all its leaves will be inserted. */
1811 insert_right_side (enum rtx_code code
, rtx exp
, rtx term
, int insn_code
, int insn_index
)
1815 /* Avoid consing in some special cases. */
1816 if (code
== AND
&& term
== true_rtx
)
1818 if (code
== AND
&& term
== false_rtx
)
1820 if (code
== AND
&& exp
== true_rtx
)
1822 if (code
== AND
&& exp
== false_rtx
)
1824 if (code
== IOR
&& term
== true_rtx
)
1826 if (code
== IOR
&& term
== false_rtx
)
1828 if (code
== IOR
&& exp
== true_rtx
)
1830 if (code
== IOR
&& exp
== false_rtx
)
1832 if (attr_equal_p (exp
, term
))
1835 if (GET_CODE (term
) == code
)
1837 exp
= insert_right_side (code
, exp
, XEXP (term
, 0),
1838 insn_code
, insn_index
);
1839 exp
= insert_right_side (code
, exp
, XEXP (term
, 1),
1840 insn_code
, insn_index
);
1845 if (GET_CODE (exp
) == code
)
1847 rtx new_rtx
= insert_right_side (code
, XEXP (exp
, 1),
1848 term
, insn_code
, insn_index
);
1849 if (new_rtx
!= XEXP (exp
, 1))
1850 /* Make a copy of this expression and call recursively. */
1851 newexp
= attr_rtx (code
, XEXP (exp
, 0), new_rtx
);
1857 /* Insert the new term. */
1858 newexp
= attr_rtx (code
, exp
, term
);
1861 return simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
1864 /* If we have an expression which AND's a bunch of
1865 (not (eq_attrq "alternative" "n"))
1866 terms, we may have covered all or all but one of the possible alternatives.
1867 If so, we can optimize. Similarly for IOR's of EQ_ATTR.
1869 This routine is passed an expression and either AND or IOR. It returns a
1870 bitmask indicating which alternatives are mentioned within EXP. */
1872 static alternative_mask
1873 compute_alternative_mask (rtx exp
, enum rtx_code code
)
1876 if (GET_CODE (exp
) == code
)
1877 return compute_alternative_mask (XEXP (exp
, 0), code
)
1878 | compute_alternative_mask (XEXP (exp
, 1), code
);
1880 else if (code
== AND
&& GET_CODE (exp
) == NOT
1881 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
1882 && XSTR (XEXP (exp
, 0), 0) == alternative_name
)
1883 string
= XSTR (XEXP (exp
, 0), 1);
1885 else if (code
== IOR
&& GET_CODE (exp
) == EQ_ATTR
1886 && XSTR (exp
, 0) == alternative_name
)
1887 string
= XSTR (exp
, 1);
1889 else if (GET_CODE (exp
) == EQ_ATTR_ALT
)
1891 if (code
== AND
&& XWINT (exp
, 1))
1892 return XWINT (exp
, 0);
1894 if (code
== IOR
&& !XWINT (exp
, 1))
1895 return XWINT (exp
, 0);
1903 return ((alternative_mask
) 1) << (string
[0] - '0');
1904 return ((alternative_mask
) 1) << atoi (string
);
1907 /* Given I, a single-bit mask, return RTX to compare the `alternative'
1908 attribute with the value represented by that bit. */
1911 make_alternative_compare (alternative_mask mask
)
1913 return mk_attr_alt (mask
);
1916 /* If we are processing an (eq_attr "attr" "value") test, we find the value
1917 of "attr" for this insn code. From that value, we can compute a test
1918 showing when the EQ_ATTR will be true. This routine performs that
1919 computation. If a test condition involves an address, we leave the EQ_ATTR
1920 intact because addresses are only valid for the `length' attribute.
1922 EXP is the EQ_ATTR expression and ATTR is the attribute to which
1923 it refers. VALUE is the value of that attribute for the insn
1924 corresponding to INSN_CODE and INSN_INDEX. */
1927 evaluate_eq_attr (rtx exp
, class attr_desc
*attr
, rtx value
,
1928 int insn_code
, int insn_index
)
1935 while (GET_CODE (value
) == ATTR
)
1937 struct attr_value
*av
= NULL
;
1939 attr
= find_attr (&XSTR (value
, 0), 0);
1941 if (insn_code_values
)
1943 struct attr_value_list
*iv
;
1944 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
1945 if (iv
->attr
== attr
)
1953 struct insn_ent
*ie
;
1954 for (av
= attr
->first_value
; av
; av
= av
->next
)
1955 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
1956 if (ie
->def
->insn_code
== insn_code
)
1966 switch (GET_CODE (value
))
1969 if (! strcmp_check (XSTR (value
, 0), XSTR (exp
, 1)))
1980 gcc_assert (GET_CODE (exp
) == EQ_ATTR
);
1981 prefix
= attr
->enum_name
? attr
->enum_name
: attr
->name
;
1982 string
= ACONCAT ((prefix
, "_", XSTR (exp
, 1), NULL
));
1983 for (p
= string
; *p
; p
++)
1986 newexp
= attr_rtx (EQ
, value
,
1987 attr_rtx (SYMBOL_REF
,
1988 DEF_ATTR_STRING (string
)));
1993 /* We construct an IOR of all the cases for which the
1994 requested attribute value is present. Since we start with
1995 FALSE, if it is not present, FALSE will be returned.
1997 Each case is the AND of the NOT's of the previous conditions with the
1998 current condition; in the default case the current condition is TRUE.
2000 For each possible COND value, call ourselves recursively.
2002 The extra TRUE and FALSE expressions will be eliminated by another
2003 call to the simplification routine. */
2008 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
2010 rtx this_cond
= simplify_test_exp_in_temp (XVECEXP (value
, 0, i
),
2011 insn_code
, insn_index
);
2013 right
= insert_right_side (AND
, andexp
, this_cond
,
2014 insn_code
, insn_index
);
2015 right
= insert_right_side (AND
, right
,
2016 evaluate_eq_attr (exp
, attr
,
2019 insn_code
, insn_index
),
2020 insn_code
, insn_index
);
2021 orexp
= insert_right_side (IOR
, orexp
, right
,
2022 insn_code
, insn_index
);
2024 /* Add this condition into the AND expression. */
2025 newexp
= attr_rtx (NOT
, this_cond
);
2026 andexp
= insert_right_side (AND
, andexp
, newexp
,
2027 insn_code
, insn_index
);
2030 /* Handle the default case. */
2031 right
= insert_right_side (AND
, andexp
,
2032 evaluate_eq_attr (exp
, attr
, XEXP (value
, 1),
2033 insn_code
, insn_index
),
2034 insn_code
, insn_index
);
2035 newexp
= insert_right_side (IOR
, orexp
, right
, insn_code
, insn_index
);
2042 /* If uses an address, must return original expression. But set the
2043 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */
2046 walk_attr_value (newexp
);
2050 if (! ATTR_IND_SIMPLIFIED_P (exp
))
2051 return copy_rtx_unchanging (exp
);
2058 /* This routine is called when an AND of a term with a tree of AND's is
2059 encountered. If the term or its complement is present in the tree, it
2060 can be replaced with TRUE or FALSE, respectively.
2062 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
2063 be true and hence are complementary.
2065 There is one special case: If we see
2066 (and (not (eq_attr "att" "v1"))
2067 (eq_attr "att" "v2"))
2068 this can be replaced by (eq_attr "att" "v2"). To do this we need to
2069 replace the term, not anything in the AND tree. So we pass a pointer to
2073 simplify_and_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2078 int left_eliminates_term
, right_eliminates_term
;
2080 if (GET_CODE (exp
) == AND
)
2082 left
= simplify_and_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2083 right
= simplify_and_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2084 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2086 newexp
= attr_rtx (AND
, left
, right
);
2088 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2092 else if (GET_CODE (exp
) == IOR
)
2094 /* For the IOR case, we do the same as above, except that we can
2095 only eliminate `term' if both sides of the IOR would do so. */
2097 left
= simplify_and_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2098 left_eliminates_term
= (temp
== true_rtx
);
2101 right
= simplify_and_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2102 right_eliminates_term
= (temp
== true_rtx
);
2104 if (left_eliminates_term
&& right_eliminates_term
)
2107 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2109 newexp
= attr_rtx (IOR
, left
, right
);
2111 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2115 /* Check for simplifications. Do some extra checking here since this
2116 routine is called so many times. */
2121 else if (GET_CODE (exp
) == NOT
&& XEXP (exp
, 0) == *pterm
)
2124 else if (GET_CODE (*pterm
) == NOT
&& exp
== XEXP (*pterm
, 0))
2127 else if (GET_CODE (exp
) == EQ_ATTR_ALT
&& GET_CODE (*pterm
) == EQ_ATTR_ALT
)
2129 if (attr_alt_subset_p (*pterm
, exp
))
2132 if (attr_alt_subset_of_compl_p (*pterm
, exp
))
2135 if (attr_alt_subset_p (exp
, *pterm
))
2141 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == EQ_ATTR
)
2143 if (XSTR (exp
, 0) != XSTR (*pterm
, 0))
2146 if (! strcmp_check (XSTR (exp
, 1), XSTR (*pterm
, 1)))
2152 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2153 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
2155 if (XSTR (*pterm
, 0) != XSTR (XEXP (exp
, 0), 0))
2158 if (! strcmp_check (XSTR (*pterm
, 1), XSTR (XEXP (exp
, 0), 1)))
2164 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2165 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
)
2167 if (XSTR (exp
, 0) != XSTR (XEXP (*pterm
, 0), 0))
2170 if (! strcmp_check (XSTR (exp
, 1), XSTR (XEXP (*pterm
, 0), 1)))
2176 else if (GET_CODE (exp
) == NOT
&& GET_CODE (*pterm
) == NOT
)
2178 if (attr_equal_p (XEXP (exp
, 0), XEXP (*pterm
, 0)))
2182 else if (GET_CODE (exp
) == NOT
)
2184 if (attr_equal_p (XEXP (exp
, 0), *pterm
))
2188 else if (GET_CODE (*pterm
) == NOT
)
2190 if (attr_equal_p (XEXP (*pterm
, 0), exp
))
2194 else if (attr_equal_p (exp
, *pterm
))
2200 /* Similar to `simplify_and_tree', but for IOR trees. */
2203 simplify_or_tree (rtx exp
, rtx
*pterm
, int insn_code
, int insn_index
)
2208 int left_eliminates_term
, right_eliminates_term
;
2210 if (GET_CODE (exp
) == IOR
)
2212 left
= simplify_or_tree (XEXP (exp
, 0), pterm
, insn_code
, insn_index
);
2213 right
= simplify_or_tree (XEXP (exp
, 1), pterm
, insn_code
, insn_index
);
2214 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2216 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2218 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2222 else if (GET_CODE (exp
) == AND
)
2224 /* For the AND case, we do the same as above, except that we can
2225 only eliminate `term' if both sides of the AND would do so. */
2227 left
= simplify_or_tree (XEXP (exp
, 0), &temp
, insn_code
, insn_index
);
2228 left_eliminates_term
= (temp
== false_rtx
);
2231 right
= simplify_or_tree (XEXP (exp
, 1), &temp
, insn_code
, insn_index
);
2232 right_eliminates_term
= (temp
== false_rtx
);
2234 if (left_eliminates_term
&& right_eliminates_term
)
2237 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2239 newexp
= attr_rtx (GET_CODE (exp
), left
, right
);
2241 exp
= simplify_test_exp_in_temp (newexp
, insn_code
, insn_index
);
2245 if (attr_equal_p (exp
, *pterm
))
2248 else if (GET_CODE (exp
) == NOT
&& attr_equal_p (XEXP (exp
, 0), *pterm
))
2251 else if (GET_CODE (*pterm
) == NOT
&& attr_equal_p (XEXP (*pterm
, 0), exp
))
2254 else if (GET_CODE (*pterm
) == EQ_ATTR
&& GET_CODE (exp
) == NOT
2255 && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
2256 && XSTR (*pterm
, 0) == XSTR (XEXP (exp
, 0), 0))
2259 else if (GET_CODE (exp
) == EQ_ATTR
&& GET_CODE (*pterm
) == NOT
2260 && GET_CODE (XEXP (*pterm
, 0)) == EQ_ATTR
2261 && XSTR (exp
, 0) == XSTR (XEXP (*pterm
, 0), 0))
2267 /* Simplify test expression and use temporary obstack in order to avoid
2268 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications
2269 and avoid unnecessary copying if possible. */
2272 simplify_test_exp_in_temp (rtx exp
, int insn_code
, int insn_index
)
2275 struct obstack
*old
;
2276 if (ATTR_IND_SIMPLIFIED_P (exp
))
2279 rtl_obstack
= temp_obstack
;
2280 x
= simplify_test_exp (exp
, insn_code
, insn_index
);
2285 /* Returns true if S1 is a subset of S2. */
2288 attr_alt_subset_p (rtx s1
, rtx s2
)
2290 switch ((XWINT (s1
, 1) << 1) | XWINT (s2
, 1))
2293 return !(XWINT (s1
, 0) &~ XWINT (s2
, 0));
2296 return !(XWINT (s1
, 0) & XWINT (s2
, 0));
2302 return !(XWINT (s2
, 0) &~ XWINT (s1
, 0));
2309 /* Returns true if S1 is a subset of complement of S2. */
2312 attr_alt_subset_of_compl_p (rtx s1
, rtx s2
)
2314 switch ((XWINT (s1
, 1) << 1) | XWINT (s2
, 1))
2317 return !(XWINT (s1
, 0) & XWINT (s2
, 0));
2320 return !(XWINT (s1
, 0) & ~XWINT (s2
, 0));
2323 return !(XWINT (s2
, 0) &~ XWINT (s1
, 0));
2333 /* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */
2336 attr_alt_intersection (rtx s1
, rtx s2
)
2338 alternative_mask result
;
2340 switch ((XWINT (s1
, 1) << 1) | XWINT (s2
, 1))
2343 result
= XWINT (s1
, 0) & XWINT (s2
, 0);
2346 result
= XWINT (s1
, 0) & ~XWINT (s2
, 0);
2349 result
= XWINT (s2
, 0) & ~XWINT (s1
, 0);
2352 result
= XWINT (s1
, 0) | XWINT (s2
, 0);
2358 return attr_rtx (EQ_ATTR_ALT
, result
, XWINT (s1
, 1) & XWINT (s2
, 1));
2361 /* Return EQ_ATTR_ALT expression representing union of S1 and S2. */
2364 attr_alt_union (rtx s1
, rtx s2
)
2366 alternative_mask result
;
2368 switch ((XWINT (s1
, 1) << 1) | XWINT (s2
, 1))
2371 result
= XWINT (s1
, 0) | XWINT (s2
, 0);
2374 result
= XWINT (s2
, 0) & ~XWINT (s1
, 0);
2377 result
= XWINT (s1
, 0) & ~XWINT (s2
, 0);
2380 result
= XWINT (s1
, 0) & XWINT (s2
, 0);
2386 return attr_rtx (EQ_ATTR_ALT
, result
, XWINT (s1
, 1) | XWINT (s2
, 1));
2389 /* Return EQ_ATTR_ALT expression representing complement of S. */
2392 attr_alt_complement (rtx s
)
2394 return attr_rtx (EQ_ATTR_ALT
, XWINT (s
, 0),
2395 ((HOST_WIDE_INT
) 1) - XWINT (s
, 1));
2398 /* Return EQ_ATTR_ALT expression representing set containing elements set
2402 mk_attr_alt (alternative_mask e
)
2404 return attr_rtx (EQ_ATTR_ALT
, (HOST_WIDE_INT
) e
, (HOST_WIDE_INT
) 0);
2407 /* Given an expression, see if it can be simplified for a particular insn
2408 code based on the values of other attributes being tested. This can
2409 eliminate nested get_attr_... calls.
2411 Note that if an endless recursion is specified in the patterns, the
2412 optimization will loop. However, it will do so in precisely the cases where
2413 an infinite recursion loop could occur during compilation. It's better that
2417 simplify_test_exp (rtx exp
, int insn_code
, int insn_index
)
2420 class attr_desc
*attr
;
2421 struct attr_value
*av
;
2422 struct insn_ent
*ie
;
2423 struct attr_value_list
*iv
;
2426 bool left_alt
, right_alt
;
2428 /* Don't re-simplify something we already simplified. */
2429 if (ATTR_IND_SIMPLIFIED_P (exp
) || ATTR_CURR_SIMPLIFIED_P (exp
))
2432 switch (GET_CODE (exp
))
2435 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2436 if (left
== false_rtx
)
2438 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2439 if (right
== false_rtx
)
2442 if (GET_CODE (left
) == EQ_ATTR_ALT
2443 && GET_CODE (right
) == EQ_ATTR_ALT
)
2445 exp
= attr_alt_intersection (left
, right
);
2446 return simplify_test_exp (exp
, insn_code
, insn_index
);
2449 /* If either side is an IOR and we have (eq_attr "alternative" ..")
2450 present on both sides, apply the distributive law since this will
2451 yield simplifications. */
2452 if ((GET_CODE (left
) == IOR
|| GET_CODE (right
) == IOR
)
2453 && compute_alternative_mask (left
, IOR
)
2454 && compute_alternative_mask (right
, IOR
))
2456 if (GET_CODE (left
) == IOR
)
2457 std::swap (left
, right
);
2459 newexp
= attr_rtx (IOR
,
2460 attr_rtx (AND
, left
, XEXP (right
, 0)),
2461 attr_rtx (AND
, left
, XEXP (right
, 1)));
2463 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2466 /* Try with the term on both sides. */
2467 right
= simplify_and_tree (right
, &left
, insn_code
, insn_index
);
2468 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2469 left
= simplify_and_tree (left
, &right
, insn_code
, insn_index
);
2471 if (left
== false_rtx
|| right
== false_rtx
)
2473 else if (left
== true_rtx
)
2477 else if (right
== true_rtx
)
2481 /* See if all or all but one of the insn's alternatives are specified
2482 in this tree. Optimize if so. */
2484 if (GET_CODE (left
) == NOT
)
2485 left_alt
= (GET_CODE (XEXP (left
, 0)) == EQ_ATTR
2486 && XSTR (XEXP (left
, 0), 0) == alternative_name
);
2488 left_alt
= (GET_CODE (left
) == EQ_ATTR_ALT
2489 && XWINT (left
, 1));
2491 if (GET_CODE (right
) == NOT
)
2492 right_alt
= (GET_CODE (XEXP (right
, 0)) == EQ_ATTR
2493 && XSTR (XEXP (right
, 0), 0) == alternative_name
);
2495 right_alt
= (GET_CODE (right
) == EQ_ATTR_ALT
2496 && XWINT (right
, 1));
2499 && (GET_CODE (left
) == AND
2501 || GET_CODE (right
) == AND
2504 i
= compute_alternative_mask (exp
, AND
);
2505 if (i
& ~insn_alternatives
[insn_code
])
2506 fatal ("invalid alternative specified for pattern number %d",
2509 /* If all alternatives are excluded, this is false. */
2510 i
^= insn_alternatives
[insn_code
];
2513 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2515 /* If just one excluded, AND a comparison with that one to the
2516 front of the tree. The others will be eliminated by
2517 optimization. We do not want to do this if the insn has one
2518 alternative and we have tested none of them! */
2519 left
= make_alternative_compare (i
);
2520 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2521 newexp
= attr_rtx (AND
, left
, right
);
2523 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2527 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2529 newexp
= attr_rtx (AND
, left
, right
);
2530 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2535 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2536 if (left
== true_rtx
)
2538 right
= SIMPLIFY_TEST_EXP (XEXP (exp
, 1), insn_code
, insn_index
);
2539 if (right
== true_rtx
)
2542 if (GET_CODE (left
) == EQ_ATTR_ALT
2543 && GET_CODE (right
) == EQ_ATTR_ALT
)
2545 exp
= attr_alt_union (left
, right
);
2546 return simplify_test_exp (exp
, insn_code
, insn_index
);
2549 right
= simplify_or_tree (right
, &left
, insn_code
, insn_index
);
2550 if (left
== XEXP (exp
, 0) && right
== XEXP (exp
, 1))
2551 left
= simplify_or_tree (left
, &right
, insn_code
, insn_index
);
2553 if (right
== true_rtx
|| left
== true_rtx
)
2555 else if (left
== false_rtx
)
2559 else if (right
== false_rtx
)
2564 /* Test for simple cases where the distributive law is useful. I.e.,
2565 convert (ior (and (x) (y))
2571 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2572 && attr_equal_p (XEXP (left
, 0), XEXP (right
, 0)))
2574 newexp
= attr_rtx (IOR
, XEXP (left
, 1), XEXP (right
, 1));
2576 left
= XEXP (left
, 0);
2578 newexp
= attr_rtx (AND
, left
, right
);
2579 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2583 convert (ior (and (y) (x))
2585 to (and (ior (y) (z))
2587 Note that we want the common term to stay at the end.
2590 else if (GET_CODE (left
) == AND
&& GET_CODE (right
) == AND
2591 && attr_equal_p (XEXP (left
, 1), XEXP (right
, 1)))
2593 newexp
= attr_rtx (IOR
, XEXP (left
, 0), XEXP (right
, 0));
2596 right
= XEXP (right
, 1);
2597 newexp
= attr_rtx (AND
, left
, right
);
2598 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2601 /* See if all or all but one of the insn's alternatives are specified
2602 in this tree. Optimize if so. */
2604 else if (insn_code
>= 0
2605 && (GET_CODE (left
) == IOR
2606 || (GET_CODE (left
) == EQ_ATTR_ALT
2607 && !XWINT (left
, 1))
2608 || (GET_CODE (left
) == EQ_ATTR
2609 && XSTR (left
, 0) == alternative_name
)
2610 || GET_CODE (right
) == IOR
2611 || (GET_CODE (right
) == EQ_ATTR_ALT
2612 && !XWINT (right
, 1))
2613 || (GET_CODE (right
) == EQ_ATTR
2614 && XSTR (right
, 0) == alternative_name
)))
2616 i
= compute_alternative_mask (exp
, IOR
);
2617 if (i
& ~insn_alternatives
[insn_code
])
2618 fatal ("invalid alternative specified for pattern number %d",
2621 /* If all alternatives are included, this is true. */
2622 i
^= insn_alternatives
[insn_code
];
2625 else if ((i
& (i
- 1)) == 0 && insn_alternatives
[insn_code
] > 1)
2627 /* If just one excluded, IOR a comparison with that one to the
2628 front of the tree. The others will be eliminated by
2629 optimization. We do not want to do this if the insn has one
2630 alternative and we have tested none of them! */
2631 left
= make_alternative_compare (i
);
2632 right
= simplify_and_tree (exp
, &left
, insn_code
, insn_index
);
2633 newexp
= attr_rtx (IOR
, attr_rtx (NOT
, left
), right
);
2635 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2639 if (left
!= XEXP (exp
, 0) || right
!= XEXP (exp
, 1))
2641 newexp
= attr_rtx (IOR
, left
, right
);
2642 return SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2647 if (GET_CODE (XEXP (exp
, 0)) == NOT
)
2649 left
= SIMPLIFY_TEST_EXP (XEXP (XEXP (exp
, 0), 0),
2650 insn_code
, insn_index
);
2654 left
= SIMPLIFY_TEST_EXP (XEXP (exp
, 0), insn_code
, insn_index
);
2655 if (GET_CODE (left
) == NOT
)
2656 return XEXP (left
, 0);
2658 if (left
== false_rtx
)
2660 if (left
== true_rtx
)
2663 if (GET_CODE (left
) == EQ_ATTR_ALT
)
2665 exp
= attr_alt_complement (left
);
2666 return simplify_test_exp (exp
, insn_code
, insn_index
);
2669 /* Try to apply De`Morgan's laws. */
2670 if (GET_CODE (left
) == IOR
)
2672 newexp
= attr_rtx (AND
,
2673 attr_rtx (NOT
, XEXP (left
, 0)),
2674 attr_rtx (NOT
, XEXP (left
, 1)));
2676 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2678 else if (GET_CODE (left
) == AND
)
2680 newexp
= attr_rtx (IOR
,
2681 attr_rtx (NOT
, XEXP (left
, 0)),
2682 attr_rtx (NOT
, XEXP (left
, 1)));
2684 newexp
= SIMPLIFY_TEST_EXP (newexp
, insn_code
, insn_index
);
2686 else if (left
!= XEXP (exp
, 0))
2688 newexp
= attr_rtx (NOT
, left
);
2693 if (!XWINT (exp
, 0))
2694 return XWINT (exp
, 1) ? true_rtx
: false_rtx
;
2698 if (XSTR (exp
, 0) == alternative_name
)
2700 newexp
= mk_attr_alt (((alternative_mask
) 1)
2701 << atoi (XSTR (exp
, 1)));
2705 /* Look at the value for this insn code in the specified attribute.
2706 We normally can replace this comparison with the condition that
2707 would give this insn the values being tested for. */
2709 && (attr
= find_attr (&XSTR (exp
, 0), 0)) != NULL
)
2714 if (insn_code_values
)
2716 for (iv
= insn_code_values
[insn_code
]; iv
; iv
= iv
->next
)
2717 if (iv
->attr
== attr
)
2725 for (av
= attr
->first_value
; av
; av
= av
->next
)
2726 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2727 if (ie
->def
->insn_code
== insn_code
)
2734 x
= evaluate_eq_attr (exp
, attr
, av
->value
,
2735 insn_code
, insn_index
);
2736 x
= SIMPLIFY_TEST_EXP (x
, insn_code
, insn_index
);
2737 if (attr_rtx_cost (x
) < 7)
2747 /* We have already simplified this expression. Simplifying it again
2748 won't buy anything unless we weren't given a valid insn code
2749 to process (i.e., we are canonicalizing something.). */
2751 && ! ATTR_IND_SIMPLIFIED_P (newexp
))
2752 return copy_rtx_unchanging (newexp
);
2757 /* Return 1 if any EQ_ATTR subexpression of P refers to ATTR,
2758 otherwise return 0. */
2761 tests_attr_p (rtx p
, class attr_desc
*attr
)
2766 if (GET_CODE (p
) == EQ_ATTR
)
2768 if (XSTR (p
, 0) != attr
->name
)
2773 fmt
= GET_RTX_FORMAT (GET_CODE (p
));
2774 ie
= GET_RTX_LENGTH (GET_CODE (p
));
2775 for (i
= 0; i
< ie
; i
++)
2780 if (tests_attr_p (XEXP (p
, i
), attr
))
2785 je
= XVECLEN (p
, i
);
2786 for (j
= 0; j
< je
; ++j
)
2787 if (tests_attr_p (XVECEXP (p
, i
, j
), attr
))
2796 /* Calculate a topological sorting of all attributes so that
2797 all attributes only depend on attributes in front of it.
2798 Place the result in *RET (which is a pointer to an array of
2799 attr_desc pointers), and return the size of that array. */
2802 get_attr_order (class attr_desc
***ret
)
2806 class attr_desc
*attr
;
2807 class attr_desc
**all
, **sorted
;
2809 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2810 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2812 all
= XNEWVEC (class attr_desc
*, num
);
2813 sorted
= XNEWVEC (class attr_desc
*, num
);
2814 handled
= XCNEWVEC (char, num
);
2816 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
2817 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
2821 for (i
= 0; i
< num
; i
++)
2822 if (all
[i
]->is_const
)
2823 handled
[i
] = 1, sorted
[j
++] = all
[i
];
2825 /* We have only few attributes hence we can live with the inner
2826 loop being O(n^2), unlike the normal fast variants of topological
2830 for (i
= 0; i
< num
; i
++)
2833 /* Let's see if I depends on anything interesting. */
2835 for (k
= 0; k
< num
; k
++)
2838 struct attr_value
*av
;
2839 for (av
= all
[i
]->first_value
; av
; av
= av
->next
)
2840 if (av
->num_insns
!= 0)
2841 if (tests_attr_p (av
->value
, all
[k
]))
2845 /* Something in I depends on K. */
2850 /* Nothing in I depended on anything intersting, so
2853 sorted
[j
++] = all
[i
];
2859 for (j
= 0; j
< num
; j
++)
2861 class attr_desc
*attr2
;
2862 struct attr_value
*av
;
2865 fprintf (stderr
, "%s depends on: ", attr
->name
);
2866 for (i
= 0; i
< MAX_ATTRS_INDEX
; ++i
)
2867 for (attr2
= attrs
[i
]; attr2
; attr2
= attr2
->next
)
2868 if (!attr2
->is_const
)
2869 for (av
= attr
->first_value
; av
; av
= av
->next
)
2870 if (av
->num_insns
!= 0)
2871 if (tests_attr_p (av
->value
, attr2
))
2873 fprintf (stderr
, "%s, ", attr2
->name
);
2876 fprintf (stderr
, "\n");
2884 /* Optimize the attribute lists by seeing if we can determine conditional
2885 values from the known values of other attributes. This will save subroutine
2886 calls during the compilation. NUM_INSN_CODES is the number of unique
2887 instruction codes. */
2890 optimize_attrs (int num_insn_codes
)
2892 class attr_desc
*attr
;
2893 struct attr_value
*av
;
2894 struct insn_ent
*ie
;
2897 struct attr_value_list
*ivbuf
;
2898 struct attr_value_list
*iv
;
2899 class attr_desc
**topsort
;
2902 /* For each insn code, make a list of all the insn_ent's for it,
2903 for all values for all attributes. */
2905 if (num_insn_ents
== 0)
2908 /* Make 2 extra elements, for "code" values -2 and -1. */
2909 insn_code_values
= XCNEWVEC (struct attr_value_list
*, num_insn_codes
+ 2);
2911 /* Offset the table address so we can index by -2 or -1. */
2912 insn_code_values
+= 2;
2914 iv
= ivbuf
= XNEWVEC (struct attr_value_list
, num_insn_ents
);
2916 /* Create the chain of insn*attr values such that we see dependend
2917 attributes after their dependencies. As we use a stack via the
2918 next pointers start from the end of the topological order. */
2919 topnum
= get_attr_order (&topsort
);
2920 for (i
= topnum
- 1; i
>= 0; i
--)
2921 for (av
= topsort
[i
]->first_value
; av
; av
= av
->next
)
2922 for (ie
= av
->first_insn
; ie
; ie
= ie
->next
)
2924 iv
->attr
= topsort
[i
];
2927 iv
->next
= insn_code_values
[ie
->def
->insn_code
];
2928 insn_code_values
[ie
->def
->insn_code
] = iv
;
2933 /* Sanity check on num_insn_ents. */
2934 gcc_assert (iv
== ivbuf
+ num_insn_ents
);
2936 /* Process one insn code at a time. */
2937 for (i
= -2; i
< num_insn_codes
; i
++)
2939 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant.
2940 We use it to mean "already simplified for this insn". */
2941 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2942 clear_struct_flag (iv
->av
->value
);
2944 for (iv
= insn_code_values
[i
]; iv
; iv
= iv
->next
)
2946 struct obstack
*old
= rtl_obstack
;
2951 if (GET_CODE (av
->value
) != COND
)
2954 rtl_obstack
= temp_obstack
;
2956 while (GET_CODE (newexp
) == COND
)
2958 rtx newexp2
= simplify_cond (newexp
, ie
->def
->insn_code
,
2959 ie
->def
->insn_index
);
2960 if (newexp2
== newexp
)
2966 /* If we created a new value for this instruction, and it's
2967 cheaper than the old value, and overall cheap, use that
2968 one as specific value for the current instruction.
2969 The last test is to avoid exploding the get_attr_ function
2970 sizes for no much gain. */
2971 if (newexp
!= av
->value
2972 && attr_rtx_cost (newexp
) < attr_rtx_cost (av
->value
)
2973 && attr_rtx_cost (newexp
) < 26
2976 remove_insn_ent (av
, ie
);
2977 av
= get_attr_value (ie
->def
->loc
, newexp
, attr
,
2978 ie
->def
->insn_code
);
2980 insert_insn_ent (av
, ie
);
2986 free (insn_code_values
- 2);
2987 insn_code_values
= NULL
;
2990 /* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */
2993 clear_struct_flag (rtx x
)
3000 ATTR_CURR_SIMPLIFIED_P (x
) = 0;
3001 if (ATTR_IND_SIMPLIFIED_P (x
))
3004 code
= GET_CODE (x
);
3023 /* Compare the elements. If any pair of corresponding elements
3024 fail to match, return 0 for the whole things. */
3026 fmt
= GET_RTX_FORMAT (code
);
3027 for (i
= GET_RTX_LENGTH (code
) - 1; i
>= 0; i
--)
3033 for (j
= 0; j
< XVECLEN (x
, i
); j
++)
3034 clear_struct_flag (XVECEXP (x
, i
, j
));
3038 clear_struct_flag (XEXP (x
, i
));
3044 /* Add attribute value NAME to the beginning of ATTR's list. */
3047 add_attr_value (class attr_desc
*attr
, const char *name
)
3049 struct attr_value
*av
;
3051 av
= oballoc (struct attr_value
);
3052 av
->value
= attr_rtx (CONST_STRING
, name
);
3053 av
->next
= attr
->first_value
;
3054 attr
->first_value
= av
;
3055 av
->first_insn
= NULL
;
3057 av
->has_asm_insn
= 0;
3060 /* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */
3063 gen_attr (md_rtx_info
*info
)
3065 struct enum_type
*et
;
3066 struct enum_value
*ev
;
3067 class attr_desc
*attr
;
3068 const char *name_ptr
;
3070 rtx def
= info
->def
;
3072 /* Make a new attribute structure. Check for duplicate by looking at
3073 attr->default_val, since it is initialized by this routine. */
3074 attr
= find_attr (&XSTR (def
, 0), 1);
3075 if (attr
->default_val
)
3077 error_at (info
->loc
, "duplicate definition for attribute %s",
3079 message_at (attr
->loc
, "previous definition");
3082 attr
->loc
= info
->loc
;
3084 if (GET_CODE (def
) == DEFINE_ENUM_ATTR
)
3086 attr
->enum_name
= XSTR (def
, 1);
3087 et
= rtx_reader_ptr
->lookup_enum_type (XSTR (def
, 1));
3088 if (!et
|| !et
->md_p
)
3089 error_at (info
->loc
, "No define_enum called `%s' defined",
3092 for (ev
= et
->values
; ev
; ev
= ev
->next
)
3093 add_attr_value (attr
, ev
->name
);
3095 else if (*XSTR (def
, 1) == '\0')
3096 attr
->is_numeric
= 1;
3099 name_ptr
= XSTR (def
, 1);
3100 while ((p
= next_comma_elt (&name_ptr
)) != NULL
)
3101 add_attr_value (attr
, p
);
3104 if (GET_CODE (XEXP (def
, 2)) == CONST
)
3107 if (attr
->is_numeric
)
3108 error_at (info
->loc
,
3109 "constant attributes may not take numeric values");
3111 /* Get rid of the CONST node. It is allowed only at top-level. */
3112 XEXP (def
, 2) = XEXP (XEXP (def
, 2), 0);
3115 if (! strcmp_check (attr
->name
, length_str
) && ! attr
->is_numeric
)
3116 error_at (info
->loc
, "`length' attribute must take numeric values");
3118 /* Set up the default value. */
3119 XEXP (def
, 2) = check_attr_value (info
->loc
, XEXP (def
, 2), attr
);
3120 attr
->default_val
= get_attr_value (info
->loc
, XEXP (def
, 2), attr
, -2);
3123 /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
3124 alternatives in the constraints. Assume all MATCH_OPERANDs have the same
3125 number of alternatives as this should be checked elsewhere. */
3128 count_alternatives (rtx exp
)
3133 if (GET_CODE (exp
) == MATCH_OPERAND
)
3134 return n_comma_elts (XSTR (exp
, 2));
3136 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3137 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3142 n
= count_alternatives (XEXP (exp
, i
));
3149 if (XVEC (exp
, i
) != NULL
)
3150 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3152 n
= count_alternatives (XVECEXP (exp
, i
, j
));
3161 /* Returns nonzero if the given expression contains an EQ_ATTR with the
3162 `alternative' attribute. */
3165 compares_alternatives_p (rtx exp
)
3170 if (GET_CODE (exp
) == EQ_ATTR
&& XSTR (exp
, 0) == alternative_name
)
3173 for (i
= 0, fmt
= GET_RTX_FORMAT (GET_CODE (exp
));
3174 i
< GET_RTX_LENGTH (GET_CODE (exp
)); i
++)
3179 if (compares_alternatives_p (XEXP (exp
, i
)))
3184 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
3185 if (compares_alternatives_p (XVECEXP (exp
, i
, j
)))
3193 /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */
3196 gen_insn (md_rtx_info
*info
)
3199 rtx def
= info
->def
;
3201 id
= oballoc (class insn_def
);
3205 id
->loc
= info
->loc
;
3207 switch (GET_CODE (def
))
3210 id
->insn_code
= info
->index
;
3211 id
->insn_index
= insn_index_number
;
3212 id
->num_alternatives
= count_alternatives (def
);
3213 if (id
->num_alternatives
== 0)
3214 id
->num_alternatives
= 1;
3218 case DEFINE_PEEPHOLE
:
3219 id
->insn_code
= info
->index
;
3220 id
->insn_index
= insn_index_number
;
3221 id
->num_alternatives
= count_alternatives (def
);
3222 if (id
->num_alternatives
== 0)
3223 id
->num_alternatives
= 1;
3227 case DEFINE_ASM_ATTRIBUTES
:
3229 id
->insn_index
= -1;
3230 id
->num_alternatives
= 1;
3232 got_define_asm_attributes
= 1;
3240 /* Process a DEFINE_DELAY. Validate the vector length, check if annul
3241 true or annul false is specified, and make a `struct delay_desc'. */
3244 gen_delay (md_rtx_info
*info
)
3246 class delay_desc
*delay
;
3249 rtx def
= info
->def
;
3250 if (XVECLEN (def
, 1) % 3 != 0)
3252 error_at (info
->loc
, "number of elements in DEFINE_DELAY must"
3253 " be multiple of three");
3257 for (i
= 0; i
< XVECLEN (def
, 1); i
+= 3)
3259 if (XVECEXP (def
, 1, i
+ 1))
3260 have_annul_true
= 1;
3261 if (XVECEXP (def
, 1, i
+ 2))
3262 have_annul_false
= 1;
3265 delay
= oballoc (class delay_desc
);
3267 delay
->num
= ++num_delays
;
3268 delay
->next
= delays
;
3269 delay
->loc
= info
->loc
;
3273 /* Names of attributes that could be possibly cached. */
3274 static const char *cached_attrs
[32];
3275 /* Number of such attributes. */
3276 static int cached_attr_count
;
3277 /* Bitmasks of possibly cached attributes. */
3278 static unsigned int attrs_seen_once
, attrs_seen_more_than_once
;
3279 static unsigned int attrs_to_cache
;
3280 static unsigned int attrs_cached_inside
, attrs_cached_after
;
3282 /* Finds non-const attributes that could be possibly cached.
3283 When create is TRUE, fills in cached_attrs array.
3284 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE
3288 find_attrs_to_cache (rtx exp
, bool create
)
3292 class attr_desc
*attr
;
3297 switch (GET_CODE (exp
))
3300 if (GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3301 find_attrs_to_cache (XEXP (exp
, 0), create
);
3305 name
= XSTR (exp
, 0);
3306 if (name
== alternative_name
)
3308 for (i
= 0; i
< cached_attr_count
; i
++)
3309 if (name
== cached_attrs
[i
])
3311 if ((attrs_seen_once
& (1U << i
)) != 0)
3312 attrs_seen_more_than_once
|= (1U << i
);
3314 attrs_seen_once
|= (1U << i
);
3319 attr
= find_attr (&name
, 0);
3323 if (cached_attr_count
== 32)
3325 cached_attrs
[cached_attr_count
] = XSTR (exp
, 0);
3326 attrs_seen_once
|= (1U << cached_attr_count
);
3327 cached_attr_count
++;
3332 find_attrs_to_cache (XEXP (exp
, 0), create
);
3333 find_attrs_to_cache (XEXP (exp
, 1), create
);
3337 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3338 find_attrs_to_cache (XVECEXP (exp
, 0, i
), create
);
3346 /* Given a piece of RTX, print a C expression to test its truth value to OUTF.
3347 We use AND and IOR both for logical and bit-wise operations, so
3348 interpret them as logical unless they are inside a comparison expression.
3350 An outermost pair of parentheses is emitted around this C expression unless
3351 EMIT_PARENS is false. */
3353 /* Interpret AND/IOR as bit-wise operations instead of logical. */
3354 #define FLG_BITWISE 1
3355 /* Set if cached attribute will be known initialized in else block after
3356 this condition. This is true for LHS of toplevel && and || and
3357 even for RHS of ||, but not for RHS of &&. */
3359 /* Set if cached attribute will be known initialized in then block after
3360 this condition. This is true for LHS of toplevel && and || and
3361 even for RHS of &&, but not for RHS of ||. */
3362 #define FLG_INSIDE 4
3363 /* Cleared when an operand of &&. */
3364 #define FLG_OUTSIDE_AND 8
3367 write_test_expr (FILE *outf
, rtx exp
, unsigned int attrs_cached
, int flags
,
3368 bool emit_parens
= true)
3370 int comparison_operator
= 0;
3372 class attr_desc
*attr
;
3375 fprintf (outf
, "(");
3377 code
= GET_CODE (exp
);
3380 /* Binary operators. */
3383 fprintf (outf
, "(unsigned) ");
3389 comparison_operator
= FLG_BITWISE
;
3392 case PLUS
: case MINUS
: case MULT
: case DIV
: case MOD
:
3393 case AND
: case IOR
: case XOR
:
3394 case ASHIFT
: case LSHIFTRT
: case ASHIFTRT
:
3395 if ((code
!= AND
&& code
!= IOR
) || (flags
& FLG_BITWISE
))
3397 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3398 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
,
3399 flags
| comparison_operator
);
3404 flags
&= ~FLG_OUTSIDE_AND
;
3405 if (GET_CODE (XEXP (exp
, 0)) == code
3406 || GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
3407 || (GET_CODE (XEXP (exp
, 0)) == NOT
3408 && GET_CODE (XEXP (XEXP (exp
, 0), 0)) == EQ_ATTR
))
3410 = write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3412 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3417 fprintf (outf
, " == ");
3420 fprintf (outf
, " != ");
3423 fprintf (outf
, " >= ");
3426 fprintf (outf
, " > ");
3429 fprintf (outf
, " >= (unsigned) ");
3432 fprintf (outf
, " > (unsigned) ");
3435 fprintf (outf
, " <= ");
3438 fprintf (outf
, " < ");
3441 fprintf (outf
, " <= (unsigned) ");
3444 fprintf (outf
, " < (unsigned) ");
3447 fprintf (outf
, " + ");
3450 fprintf (outf
, " - ");
3453 fprintf (outf
, " * ");
3456 fprintf (outf
, " / ");
3459 fprintf (outf
, " %% ");
3462 if (flags
& FLG_BITWISE
)
3463 fprintf (outf
, " & ");
3465 fprintf (outf
, " && ");
3468 if (flags
& FLG_BITWISE
)
3469 fprintf (outf
, " | ");
3471 fprintf (outf
, " || ");
3474 fprintf (outf
, " ^ ");
3477 fprintf (outf
, " << ");
3481 fprintf (outf
, " >> ");
3489 /* For if (something && (cached_x = get_attr_x (insn)) == X)
3490 cached_x is only known to be initialized in then block. */
3491 flags
&= ~FLG_AFTER
;
3493 else if (code
== IOR
)
3495 if (flags
& FLG_OUTSIDE_AND
)
3496 /* For if (something || (cached_x = get_attr_x (insn)) == X)
3497 cached_x is only known to be initialized in else block
3498 and else if conditions. */
3499 flags
&= ~FLG_INSIDE
;
3501 /* For if ((something || (cached_x = get_attr_x (insn)) == X)
3503 cached_x is not know to be initialized anywhere. */
3504 flags
&= ~(FLG_AFTER
| FLG_INSIDE
);
3506 if ((code
== AND
|| code
== IOR
)
3507 && (GET_CODE (XEXP (exp
, 1)) == code
3508 || GET_CODE (XEXP (exp
, 1)) == EQ_ATTR
3509 || (GET_CODE (XEXP (exp
, 1)) == NOT
3510 && GET_CODE (XEXP (XEXP (exp
, 1), 0)) == EQ_ATTR
)))
3512 bool need_parens
= true;
3514 /* No need to emit parentheses around the right-hand operand if we are
3515 continuing a chain of && or || (or & or |). */
3516 if (GET_CODE (XEXP (exp
, 1)) == code
)
3517 need_parens
= false;
3520 = write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, flags
,
3524 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
,
3525 flags
| comparison_operator
);
3529 /* Special-case (not (eq_attrq "alternative" "x")) */
3530 if (! (flags
& FLG_BITWISE
) && GET_CODE (XEXP (exp
, 0)) == EQ_ATTR
)
3532 if (XSTR (XEXP (exp
, 0), 0) == alternative_name
)
3534 fprintf (outf
, "which_alternative != %s",
3535 XSTR (XEXP (exp
, 0), 1));
3539 fprintf (outf
, "! ");
3541 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3545 /* Otherwise, fall through to normal unary operator. */
3548 /* Unary operators. */
3553 if (flags
& FLG_BITWISE
)
3554 fprintf (outf
, "~ ");
3556 fprintf (outf
, "! ");
3559 fprintf (outf
, "abs ");
3562 fprintf (outf
, "-");
3568 flags
&= ~(FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
);
3569 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, flags
);
3574 alternative_mask set
= XWINT (exp
, 0);
3577 if (flags
& FLG_BITWISE
)
3578 fatal ("EQ_ATTR_ALT not valid inside comparison");
3581 fatal ("Empty EQ_ATTR_ALT should be optimized out");
3583 if (!(set
& (set
- 1)))
3585 if (!(set
& 0xffffffff))
3590 if (!(set
& 0xffff))
3613 fprintf (outf
, "which_alternative %s= %d",
3614 XWINT (exp
, 1) ? "!" : "=", bit
);
3618 fprintf (outf
, "%s((1ULL << which_alternative) & %#" PRIx64
3620 XWINT (exp
, 1) ? "!" : "", set
);
3625 /* Comparison test of an attribute with a value. Most of these will
3626 have been removed by optimization. Handle "alternative"
3627 specially and give error if EQ_ATTR present inside a comparison. */
3629 if (flags
& FLG_BITWISE
)
3630 fatal ("EQ_ATTR not valid inside comparison");
3632 if (XSTR (exp
, 0) == alternative_name
)
3634 fprintf (outf
, "which_alternative == %s", XSTR (exp
, 1));
3638 attr
= find_attr (&XSTR (exp
, 0), 0);
3641 /* Now is the time to expand the value of a constant attribute. */
3644 write_test_expr (outf
,
3645 evaluate_eq_attr (exp
, attr
,
3646 attr
->default_val
->value
,
3653 for (i
= 0; i
< cached_attr_count
; i
++)
3654 if (attr
->name
== cached_attrs
[i
])
3656 if (i
< cached_attr_count
&& (attrs_cached
& (1U << i
)) != 0)
3657 fprintf (outf
, "cached_%s", attr
->name
);
3658 else if (i
< cached_attr_count
&& (attrs_to_cache
& (1U << i
)) != 0)
3660 fprintf (outf
, "(cached_%s = get_attr_%s (insn))",
3661 attr
->name
, attr
->name
);
3662 if (flags
& FLG_AFTER
)
3663 attrs_cached_after
|= (1U << i
);
3664 if (flags
& FLG_INSIDE
)
3665 attrs_cached_inside
|= (1U << i
);
3666 attrs_cached
|= (1U << i
);
3669 fprintf (outf
, "get_attr_%s (insn)", attr
->name
);
3670 fprintf (outf
, " == ");
3671 write_attr_valueq (outf
, attr
, XSTR (exp
, 1));
3675 /* Comparison test of flags for define_delays. */
3677 if (flags
& FLG_BITWISE
)
3678 fatal ("ATTR_FLAG not valid inside comparison");
3679 fprintf (outf
, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp
, 0));
3682 /* See if an operand matches a predicate. */
3684 /* If only a mode is given, just ensure the mode matches the operand.
3685 If neither a mode nor predicate is given, error. */
3686 if (XSTR (exp
, 1) == NULL
|| *XSTR (exp
, 1) == '\0')
3688 if (GET_MODE (exp
) == VOIDmode
)
3689 fatal ("null MATCH_OPERAND specified as test");
3691 fprintf (outf
, "GET_MODE (operands[%d]) == %smode",
3692 XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3695 fprintf (outf
, "%s (operands[%d], %smode)",
3696 XSTR (exp
, 1), XINT (exp
, 0), GET_MODE_NAME (GET_MODE (exp
)));
3699 /* Constant integer. */
3701 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, XWINT (exp
, 0));
3705 rtx_reader_ptr
->fprint_c_condition (outf
, XSTR (exp
, 0));
3706 if (flags
& FLG_BITWISE
)
3707 fprintf (outf
, " != 0");
3710 /* A random C expression. */
3712 rtx_reader_ptr
->fprint_c_condition (outf
, XSTR (exp
, 0));
3715 /* The address of the branch target. */
3718 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0",
3719 XINT (exp
, 0), XINT (exp
, 0), XINT (exp
, 0));
3723 /* The address of the current insn. We implement this actually as the
3724 address of the current insn for backward branches, but the last
3725 address of the next insn for forward branches, and both with
3726 adjustments that account for the worst-case possible stretching of
3727 intervening alignments between this insn and its destination. */
3728 fprintf (outf
, "insn_current_reference_address (insn)");
3732 fprintf (outf
, "%s", XSTR (exp
, 0));
3736 write_test_expr (outf
, XEXP (exp
, 0), attrs_cached
, 0);
3737 fprintf (outf
, " ? ");
3738 write_test_expr (outf
, XEXP (exp
, 1), attrs_cached
, FLG_BITWISE
);
3739 fprintf (outf
, " : ");
3740 write_test_expr (outf
, XEXP (exp
, 2), attrs_cached
, FLG_BITWISE
);
3744 fatal ("bad RTX code `%s' in attribute calculation\n",
3745 GET_RTX_NAME (code
));
3749 fprintf (outf
, ")");
3751 return attrs_cached
;
3754 /* Given an attribute value expression, return the maximum value that
3755 might be evaluated. Return INT_MAX if the value can't be
3756 calculated by this function. */
3759 max_attr_value (rtx exp
)
3764 switch (GET_CODE (exp
))
3767 current_max
= atoi (XSTR (exp
, 0));
3771 current_max
= INTVAL (exp
);
3775 current_max
= max_attr_value (XEXP (exp
, 0));
3776 if (current_max
!= INT_MAX
)
3779 current_max
= max_attr_value (XEXP (exp
, 1));
3780 if (current_max
!= INT_MAX
)
3786 current_max
= max_attr_value (XEXP (exp
, 0));
3787 if (current_max
!= INT_MAX
)
3790 current_max
= min_attr_value (XEXP (exp
, 1));
3791 if (current_max
!= INT_MAX
)
3792 current_max
= n
- current_max
;
3797 current_max
= max_attr_value (XEXP (exp
, 0));
3798 if (current_max
!= INT_MAX
)
3801 current_max
= max_attr_value (XEXP (exp
, 1));
3802 if (current_max
!= INT_MAX
)
3808 current_max
= max_attr_value (XEXP (exp
, 1));
3809 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3811 n
= max_attr_value (XVECEXP (exp
, 0, i
+ 1));
3812 if (n
> current_max
)
3818 current_max
= max_attr_value (XEXP (exp
, 1));
3819 n
= max_attr_value (XEXP (exp
, 2));
3820 if (n
> current_max
)
3825 current_max
= INT_MAX
;
3832 /* Given an attribute value expression, return the minimum value that
3833 might be evaluated. Return INT_MAX if the value can't be
3834 calculated by this function. Note that when this function can
3835 calculate one value inside IF_THEN_ELSE or some but not all values
3836 inside COND, then it returns the minimum among those values it can
3840 min_attr_value (rtx exp
)
3845 switch (GET_CODE (exp
))
3848 current_min
= atoi (XSTR (exp
, 0));
3852 current_min
= INTVAL (exp
);
3856 current_min
= min_attr_value (XEXP (exp
, 0));
3857 if (current_min
!= INT_MAX
)
3860 current_min
= min_attr_value (XEXP (exp
, 1));
3861 if (current_min
!= INT_MAX
)
3867 current_min
= min_attr_value (XEXP (exp
, 0));
3868 if (current_min
!= INT_MAX
)
3871 current_min
= max_attr_value (XEXP (exp
, 1));
3872 if (current_min
!= INT_MAX
)
3873 current_min
= n
- current_min
;
3878 current_min
= min_attr_value (XEXP (exp
, 0));
3879 if (current_min
!= INT_MAX
)
3882 current_min
= min_attr_value (XEXP (exp
, 1));
3883 if (current_min
!= INT_MAX
)
3889 current_min
= min_attr_value (XEXP (exp
, 1));
3890 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3892 n
= min_attr_value (XVECEXP (exp
, 0, i
+ 1));
3893 if (n
< current_min
)
3899 current_min
= min_attr_value (XEXP (exp
, 1));
3900 n
= min_attr_value (XEXP (exp
, 2));
3901 if (n
< current_min
)
3906 current_min
= INT_MAX
;
3913 /* Given an attribute value expression, return the alignment of values.
3914 Return 0 if EXP is known to be zero, and 1 if the value can't be
3915 calculated by this function. */
3918 attr_value_alignment (rtx exp
)
3920 unsigned int current_or
;
3923 switch (GET_CODE (exp
))
3926 current_or
= atoi (XSTR (exp
, 0));
3930 current_or
= INTVAL (exp
);
3935 current_or
= attr_value_alignment (XEXP (exp
, 0));
3936 current_or
|= attr_value_alignment (XEXP (exp
, 1));
3940 current_or
= attr_value_alignment (XEXP (exp
, 0));
3941 current_or
*= attr_value_alignment (XEXP (exp
, 1));
3945 current_or
= attr_value_alignment (XEXP (exp
, 1));
3946 for (i
= 0; i
< XVECLEN (exp
, 0); i
+= 2)
3947 current_or
|= attr_value_alignment (XVECEXP (exp
, 0, i
+ 1));
3951 current_or
= attr_value_alignment (XEXP (exp
, 1));
3952 current_or
|= attr_value_alignment (XEXP (exp
, 2));
3960 return current_or
& -current_or
;
3963 /* Scan an attribute value, possibly a conditional, and record what actions
3964 will be required to do any conditional tests in it.
3967 `must_extract' if we need to extract the insn operands
3968 `must_constrain' if we must compute `which_alternative'
3969 `address_used' if an address expression was used
3970 `length_used' if an (eq_attr "length" ...) was used
3974 walk_attr_value (rtx exp
)
3983 code
= GET_CODE (exp
);
3987 if (! ATTR_IND_SIMPLIFIED_P (exp
))
3988 /* Since this is an arbitrary expression, it can look at anything.
3989 However, constant expressions do not depend on any particular
3991 must_extract
= must_constrain
= 1;
4000 must_extract
= must_constrain
= 1;
4004 if (XSTR (exp
, 0) == alternative_name
)
4005 must_extract
= must_constrain
= 1;
4006 else if (strcmp_check (XSTR (exp
, 0), length_str
) == 0)
4026 for (i
= 0, fmt
= GET_RTX_FORMAT (code
); i
< GET_RTX_LENGTH (code
); i
++)
4031 walk_attr_value (XEXP (exp
, i
));
4035 if (XVEC (exp
, i
) != NULL
)
4036 for (j
= 0; j
< XVECLEN (exp
, i
); j
++)
4037 walk_attr_value (XVECEXP (exp
, i
, j
));
4042 /* Write out a function to obtain the attribute for a given INSN. */
4045 write_attr_get (FILE *outf
, class attr_desc
*attr
)
4047 struct attr_value
*av
, *common_av
;
4050 /* Find the most used attribute value. Handle that as the `default' of the
4051 switch we will generate. */
4052 common_av
= find_most_used (attr
);
4054 /* Write out start of function, then all values with explicit `case' lines,
4055 then a `default', then the value with the most uses. */
4056 if (attr
->enum_name
)
4057 fprintf (outf
, "enum %s\n", attr
->enum_name
);
4058 else if (!attr
->is_numeric
)
4059 fprintf (outf
, "enum attr_%s\n", attr
->name
);
4061 fprintf (outf
, "int\n");
4063 /* If the attribute name starts with a star, the remainder is the name of
4064 the subroutine to use, instead of `get_attr_...'. */
4065 if (attr
->name
[0] == '*')
4066 fprintf (outf
, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr
->name
[1]);
4067 else if (attr
->is_const
== 0)
4068 fprintf (outf
, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr
->name
);
4071 fprintf (outf
, "get_attr_%s (void)\n", attr
->name
);
4072 fprintf (outf
, "{\n");
4074 for (av
= attr
->first_value
; av
; av
= av
->next
)
4075 if (av
->num_insns
== 1)
4076 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4077 true_rtx
, av
->first_insn
->def
->insn_code
,
4078 av
->first_insn
->def
->insn_index
, 0);
4079 else if (av
->num_insns
!= 0)
4080 write_attr_set (outf
, attr
, 2, av
->value
, "return", ";",
4081 true_rtx
, -2, 0, 0);
4083 fprintf (outf
, "}\n\n");
4087 fprintf (outf
, "{\n");
4089 /* Find attributes that are worth caching in the conditions. */
4090 cached_attr_count
= 0;
4091 attrs_seen_more_than_once
= 0;
4092 for (av
= attr
->first_value
; av
; av
= av
->next
)
4094 attrs_seen_once
= 0;
4095 find_attrs_to_cache (av
->value
, true);
4097 /* Remove those that aren't worth caching from the array. */
4098 for (i
= 0, j
= 0; i
< cached_attr_count
; i
++)
4099 if ((attrs_seen_more_than_once
& (1U << i
)) != 0)
4101 const char *name
= cached_attrs
[i
];
4102 class attr_desc
*cached_attr
;
4104 cached_attrs
[j
] = name
;
4105 cached_attr
= find_attr (&name
, 0);
4106 gcc_assert (cached_attr
&& cached_attr
->is_const
== 0);
4107 if (cached_attr
->enum_name
)
4108 fprintf (outf
, " enum %s", cached_attr
->enum_name
);
4109 else if (!cached_attr
->is_numeric
)
4110 fprintf (outf
, " enum attr_%s", cached_attr
->name
);
4112 fprintf (outf
, " int");
4113 fprintf (outf
, " cached_%s ATTRIBUTE_UNUSED;\n", name
);
4116 cached_attr_count
= j
;
4117 if (cached_attr_count
)
4118 fprintf (outf
, "\n");
4120 fprintf (outf
, " switch (recog_memoized (insn))\n");
4121 fprintf (outf
, " {\n");
4123 for (av
= attr
->first_value
; av
; av
= av
->next
)
4124 if (av
!= common_av
)
4125 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4127 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4128 fprintf (outf
, " }\n}\n\n");
4129 cached_attr_count
= 0;
4132 /* Given an AND tree of known true terms (because we are inside an `if' with
4133 that as the condition or are in an `else' clause) and an expression,
4134 replace any known true terms with TRUE. Use `simplify_and_tree' to do
4135 the bulk of the work. */
4138 eliminate_known_true (rtx known_true
, rtx exp
, int insn_code
, int insn_index
)
4142 known_true
= SIMPLIFY_TEST_EXP (known_true
, insn_code
, insn_index
);
4144 if (GET_CODE (known_true
) == AND
)
4146 exp
= eliminate_known_true (XEXP (known_true
, 0), exp
,
4147 insn_code
, insn_index
);
4148 exp
= eliminate_known_true (XEXP (known_true
, 1), exp
,
4149 insn_code
, insn_index
);
4154 exp
= simplify_and_tree (exp
, &term
, insn_code
, insn_index
);
4160 /* Write out a series of tests and assignment statements to perform tests and
4161 sets of an attribute value. We are passed an indentation amount and prefix
4162 and suffix strings to write around each attribute value (e.g., "return"
4166 write_attr_set (FILE *outf
, class attr_desc
*attr
, int indent
, rtx value
,
4167 const char *prefix
, const char *suffix
, rtx known_true
,
4168 int insn_code
, int insn_index
, unsigned int attrs_cached
)
4170 if (GET_CODE (value
) == COND
)
4172 /* Assume the default value will be the default of the COND unless we
4173 find an always true expression. */
4174 rtx default_val
= XEXP (value
, 1);
4175 rtx our_known_true
= known_true
;
4180 if (cached_attr_count
)
4182 attrs_seen_once
= 0;
4183 attrs_seen_more_than_once
= 0;
4184 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4185 find_attrs_to_cache (XVECEXP (value
, 0, i
), false);
4186 attrs_to_cache
|= attrs_seen_more_than_once
;
4189 for (i
= 0; i
< XVECLEN (value
, 0); i
+= 2)
4194 /* Reset our_known_true after some time to not accumulate
4195 too much cruft (slowing down genattrtab). */
4197 our_known_true
= known_true
;
4198 testexp
= eliminate_known_true (our_known_true
,
4199 XVECEXP (value
, 0, i
),
4200 insn_code
, insn_index
);
4201 newexp
= attr_rtx (NOT
, testexp
);
4202 newexp
= insert_right_side (AND
, our_known_true
, newexp
,
4203 insn_code
, insn_index
);
4205 /* If the test expression is always true or if the next `known_true'
4206 expression is always false, this is the last case, so break
4207 out and let this value be the `else' case. */
4208 if (testexp
== true_rtx
|| newexp
== false_rtx
)
4210 default_val
= XVECEXP (value
, 0, i
+ 1);
4214 /* Compute the expression to pass to our recursive call as being
4216 inner_true
= insert_right_side (AND
, our_known_true
,
4217 testexp
, insn_code
, insn_index
);
4219 /* If this is always false, skip it. */
4220 if (inner_true
== false_rtx
)
4223 attrs_cached_inside
= attrs_cached
;
4224 attrs_cached_after
= attrs_cached
;
4225 write_indent (outf
, indent
);
4226 fprintf (outf
, "%sif ", first_if
? "" : "else ");
4228 write_test_expr (outf
, testexp
, attrs_cached
,
4229 (FLG_AFTER
| FLG_INSIDE
| FLG_OUTSIDE_AND
));
4230 attrs_cached
= attrs_cached_after
;
4231 fprintf (outf
, "\n");
4232 write_indent (outf
, indent
+ 2);
4233 fprintf (outf
, "{\n");
4235 write_attr_set (outf
, attr
, indent
+ 4,
4236 XVECEXP (value
, 0, i
+ 1), prefix
, suffix
,
4237 inner_true
, insn_code
, insn_index
,
4238 attrs_cached_inside
);
4239 write_indent (outf
, indent
+ 2);
4240 fprintf (outf
, "}\n");
4241 our_known_true
= newexp
;
4246 write_indent (outf
, indent
);
4247 fprintf (outf
, "else\n");
4248 write_indent (outf
, indent
+ 2);
4249 fprintf (outf
, "{\n");
4252 write_attr_set (outf
, attr
, first_if
? indent
: indent
+ 4, default_val
,
4253 prefix
, suffix
, our_known_true
, insn_code
, insn_index
,
4258 write_indent (outf
, indent
+ 2);
4259 fprintf (outf
, "}\n");
4264 write_indent (outf
, indent
);
4265 fprintf (outf
, "%s ", prefix
);
4266 write_attr_value (outf
, attr
, value
);
4267 fprintf (outf
, "%s\n", suffix
);
4271 /* Write a series of case statements for every instruction in list IE.
4272 INDENT is the amount of indentation to write before each case. */
4275 write_insn_cases (FILE *outf
, struct insn_ent
*ie
, int indent
)
4277 for (; ie
!= 0; ie
= ie
->next
)
4278 if (ie
->def
->insn_code
!= -1)
4280 write_indent (outf
, indent
);
4281 if (GET_CODE (ie
->def
->def
) == DEFINE_PEEPHOLE
)
4282 fprintf (outf
, "case %d: /* define_peephole, %s:%d */\n",
4283 ie
->def
->insn_code
, ie
->def
->loc
.filename
,
4284 ie
->def
->loc
.lineno
);
4286 fprintf (outf
, "case %d: /* %s */\n",
4287 ie
->def
->insn_code
, XSTR (ie
->def
->def
, 0));
4291 /* Write out the computation for one attribute value. */
4294 write_attr_case (FILE *outf
, class attr_desc
*attr
, struct attr_value
*av
,
4295 int write_case_lines
, const char *prefix
, const char *suffix
,
4296 int indent
, rtx known_true
)
4298 if (av
->num_insns
== 0)
4301 if (av
->has_asm_insn
)
4303 write_indent (outf
, indent
);
4304 fprintf (outf
, "case -1:\n");
4305 write_indent (outf
, indent
+ 2);
4306 fprintf (outf
, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
4307 write_indent (outf
, indent
+ 2);
4308 fprintf (outf
, " && asm_noperands (PATTERN (insn)) < 0)\n");
4309 write_indent (outf
, indent
+ 2);
4310 fprintf (outf
, " fatal_insn_not_found (insn);\n");
4311 write_indent (outf
, indent
+ 2);
4312 fprintf (outf
, "/* FALLTHRU */\n");
4315 if (write_case_lines
)
4316 write_insn_cases (outf
, av
->first_insn
, indent
);
4319 write_indent (outf
, indent
);
4320 fprintf (outf
, "default:\n");
4323 /* See what we have to do to output this value. */
4324 must_extract
= must_constrain
= address_used
= 0;
4325 walk_attr_value (av
->value
);
4329 write_indent (outf
, indent
+ 2);
4330 fprintf (outf
, "extract_constrain_insn_cached (insn);\n");
4332 else if (must_extract
)
4334 write_indent (outf
, indent
+ 2);
4335 fprintf (outf
, "extract_insn_cached (insn);\n");
4339 if (av
->num_insns
== 1)
4340 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4341 known_true
, av
->first_insn
->def
->insn_code
,
4342 av
->first_insn
->def
->insn_index
, 0);
4344 write_attr_set (outf
, attr
, indent
+ 2, av
->value
, prefix
, suffix
,
4345 known_true
, -2, 0, 0);
4347 if (strncmp (prefix
, "return", 6))
4349 write_indent (outf
, indent
+ 2);
4350 fprintf (outf
, "break;\n");
4352 fprintf (outf
, "\n");
4355 /* Utilities to write in various forms. */
4358 write_attr_valueq (FILE *outf
, class attr_desc
*attr
, const char *s
)
4360 if (attr
->is_numeric
)
4364 fprintf (outf
, "%d", num
);
4366 if (num
> 9 || num
< 0)
4367 fprintf (outf
, " /* %#x */", num
);
4371 write_upcase (outf
, attr
->enum_name
? attr
->enum_name
: attr
->name
);
4372 fprintf (outf
, "_");
4373 write_upcase (outf
, s
);
4378 write_attr_value (FILE *outf
, class attr_desc
*attr
, rtx value
)
4382 switch (GET_CODE (value
))
4385 write_attr_valueq (outf
, attr
, XSTR (value
, 0));
4389 fprintf (outf
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (value
));
4393 rtx_reader_ptr
->fprint_c_condition (outf
, XSTR (value
, 0));
4398 class attr_desc
*attr2
= find_attr (&XSTR (value
, 0), 0);
4399 if (attr
->enum_name
)
4400 fprintf (outf
, "(enum %s)", attr
->enum_name
);
4401 else if (!attr
->is_numeric
)
4402 fprintf (outf
, "(enum attr_%s)", attr
->name
);
4403 else if (!attr2
->is_numeric
)
4404 fprintf (outf
, "(int)");
4406 fprintf (outf
, "get_attr_%s (%s)", attr2
->name
,
4407 (attr2
->is_const
? "" : "insn"));
4428 fprintf (outf
, "(");
4429 write_attr_value (outf
, attr
, XEXP (value
, 0));
4430 fprintf (outf
, " %c ", op
);
4431 write_attr_value (outf
, attr
, XEXP (value
, 1));
4432 fprintf (outf
, ")");
4436 fprintf (outf
, "(");
4437 write_test_expr (outf
, XEXP (value
, 0), 0, 0, false);
4438 fprintf (outf
, " ? ");
4439 write_attr_value (outf
, attr
, XEXP (value
, 1));
4440 fprintf (outf
, " : ");
4441 write_attr_value (outf
, attr
, XEXP (value
, 2));
4442 fprintf (outf
, ")");
4451 write_upcase (FILE *outf
, const char *str
)
4455 /* The argument of TOUPPER should not have side effects. */
4456 fputc (TOUPPER (*str
), outf
);
4462 write_indent (FILE *outf
, int indent
)
4464 for (; indent
> 8; indent
-= 8)
4465 fprintf (outf
, "\t");
4467 for (; indent
; indent
--)
4468 fprintf (outf
, " ");
4471 /* If the target does not have annul-true or annul-false delay slots, this
4472 function will create a dummy eligible_for function on OUTF which always
4473 returns false. KIND will be annul_true or annul_false. */
4476 write_dummy_eligible_delay (FILE *outf
, const char *kind
)
4478 /* Write function prelude. */
4480 fprintf (outf
, "int\n");
4481 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED,\n"
4482 " int slot ATTRIBUTE_UNUSED,\n"
4483 " rtx_insn *candidate_insn ATTRIBUTE_UNUSED,\n"
4484 " int flags ATTRIBUTE_UNUSED)\n",
4486 fprintf (outf
, "{\n");
4487 fprintf (outf
, " return 0;\n");
4488 fprintf (outf
, "}\n\n");
4491 /* Write a subroutine that is given an insn that requires a delay slot, a
4492 delay slot ordinal, and a candidate insn. It returns nonzero if the
4493 candidate can be placed in the specified delay slot of the insn.
4495 We can write as many as three subroutines. `eligible_for_delay'
4496 handles normal delay slots, `eligible_for_annul_true' indicates that
4497 the specified insn can be annulled if the branch is true, and likewise
4498 for `eligible_for_annul_false'.
4500 KIND is a string distinguishing these three cases ("delay", "annul_true",
4501 or "annul_false"). */
4504 write_eligible_delay (FILE *outf
, const char *kind
)
4506 class delay_desc
*delay
;
4510 class attr_desc
*attr
;
4511 struct attr_value
*av
, *common_av
;
4514 /* Compute the maximum number of delay slots required. We use the delay
4515 ordinal times this number plus one, plus the slot number as an index into
4516 the appropriate predicate to test. */
4518 for (delay
= delays
, max_slots
= 0; delay
; delay
= delay
->next
)
4519 if (XVECLEN (delay
->def
, 1) / 3 > max_slots
)
4520 max_slots
= XVECLEN (delay
->def
, 1) / 3;
4522 /* Write function prelude. */
4524 fprintf (outf
, "int\n");
4525 fprintf (outf
, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n"
4526 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n",
4528 fprintf (outf
, "{\n");
4529 fprintf (outf
, " rtx_insn *insn ATTRIBUTE_UNUSED;\n");
4530 fprintf (outf
, "\n");
4531 fprintf (outf
, " if (num_delay_slots (delay_insn) == 0)\n");
4532 fprintf (outf
, " return 0;");
4533 fprintf (outf
, "\n");
4534 fprintf (outf
, " gcc_assert (slot < %d);\n", max_slots
);
4535 fprintf (outf
, "\n");
4536 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split
4537 converts a compound instruction into a loop. */
4538 fprintf (outf
, " if (!INSN_P (candidate_insn))\n");
4539 fprintf (outf
, " return 0;\n");
4540 fprintf (outf
, "\n");
4542 /* If more than one delay type, find out which type the delay insn is. */
4546 attr
= find_attr (&delay_type_str
, 0);
4548 common_av
= find_most_used (attr
);
4550 fprintf (outf
, " insn = delay_insn;\n");
4551 fprintf (outf
, " switch (recog_memoized (insn))\n");
4552 fprintf (outf
, " {\n");
4554 sprintf (str
, " * %d;\n break;", max_slots
);
4555 for (av
= attr
->first_value
; av
; av
= av
->next
)
4556 if (av
!= common_av
)
4557 write_attr_case (outf
, attr
, av
, 1, "slot +=", str
, 4, true_rtx
);
4559 write_attr_case (outf
, attr
, common_av
, 0, "slot +=", str
, 4, true_rtx
);
4560 fprintf (outf
, " }\n\n");
4562 /* Ensure matched. Otherwise, shouldn't have been called. */
4563 fprintf (outf
, " gcc_assert (slot >= %d);\n\n", max_slots
);
4566 /* If just one type of delay slot, write simple switch. */
4567 if (num_delays
== 1 && max_slots
== 1)
4569 fprintf (outf
, " insn = candidate_insn;\n");
4570 fprintf (outf
, " switch (recog_memoized (insn))\n");
4571 fprintf (outf
, " {\n");
4573 attr
= find_attr (&delay_1_0_str
, 0);
4575 common_av
= find_most_used (attr
);
4577 for (av
= attr
->first_value
; av
; av
= av
->next
)
4578 if (av
!= common_av
)
4579 write_attr_case (outf
, attr
, av
, 1, "return", ";", 4, true_rtx
);
4581 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 4, true_rtx
);
4582 fprintf (outf
, " }\n");
4587 /* Write a nested CASE. The first indicates which condition we need to
4588 test, and the inner CASE tests the condition. */
4589 fprintf (outf
, " insn = candidate_insn;\n");
4590 fprintf (outf
, " switch (slot)\n");
4591 fprintf (outf
, " {\n");
4593 for (delay
= delays
; delay
; delay
= delay
->next
)
4594 for (i
= 0; i
< XVECLEN (delay
->def
, 1); i
+= 3)
4596 fprintf (outf
, " case %d:\n",
4597 (i
/ 3) + (num_delays
== 1 ? 0 : delay
->num
* max_slots
));
4598 fprintf (outf
, " switch (recog_memoized (insn))\n");
4599 fprintf (outf
, "\t{\n");
4601 sprintf (str
, "*%s_%d_%d", kind
, delay
->num
, i
/ 3);
4603 attr
= find_attr (&pstr
, 0);
4605 common_av
= find_most_used (attr
);
4607 for (av
= attr
->first_value
; av
; av
= av
->next
)
4608 if (av
!= common_av
)
4609 write_attr_case (outf
, attr
, av
, 1, "return", ";", 8, true_rtx
);
4611 write_attr_case (outf
, attr
, common_av
, 0, "return", ";", 8, true_rtx
);
4612 fprintf (outf
, " }\n");
4615 fprintf (outf
, " default:\n");
4616 fprintf (outf
, " gcc_unreachable ();\n");
4617 fprintf (outf
, " }\n");
4620 fprintf (outf
, "}\n\n");
4623 /* This page contains miscellaneous utility routines. */
4625 /* Given a pointer to a (char *), return a malloc'ed string containing the
4626 next comma-separated element. Advance the pointer to after the string
4627 scanned, or the end-of-string. Return NULL if at end of string. */
4630 next_comma_elt (const char **pstr
)
4634 start
= scan_comma_elt (pstr
);
4639 return attr_string (start
, *pstr
- start
);
4642 /* Return a `class attr_desc' pointer for a given named attribute. If CREATE
4643 is nonzero, build a new attribute, if one does not exist. *NAME_P is
4644 replaced by a pointer to a canonical copy of the string. */
4646 static class attr_desc
*
4647 find_attr (const char **name_p
, int create
)
4649 class attr_desc
*attr
;
4651 const char *name
= *name_p
;
4653 /* Before we resort to using `strcmp', see if the string address matches
4654 anywhere. In most cases, it should have been canonicalized to do so. */
4655 if (name
== alternative_name
)
4658 index
= name
[0] & (MAX_ATTRS_INDEX
- 1);
4659 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4660 if (name
== attr
->name
)
4663 /* Otherwise, do it the slow way. */
4664 for (attr
= attrs
[index
]; attr
; attr
= attr
->next
)
4665 if (name
[0] == attr
->name
[0] && ! strcmp (name
, attr
->name
))
4667 *name_p
= attr
->name
;
4674 attr
= oballoc (class attr_desc
);
4675 attr
->name
= DEF_ATTR_STRING (name
);
4676 attr
->enum_name
= 0;
4677 attr
->first_value
= attr
->default_val
= NULL
;
4678 attr
->is_numeric
= attr
->is_const
= attr
->is_special
= 0;
4679 attr
->next
= attrs
[index
];
4680 attrs
[index
] = attr
;
4682 *name_p
= attr
->name
;
4687 /* Create internal attribute with the given default value. */
4690 make_internal_attr (const char *name
, rtx value
, int special
)
4692 class attr_desc
*attr
;
4694 attr
= find_attr (&name
, 1);
4695 gcc_assert (!attr
->default_val
);
4697 attr
->is_numeric
= 1;
4699 attr
->is_special
= (special
& ATTR_SPECIAL
) != 0;
4700 attr
->default_val
= get_attr_value (file_location ("<internal>", 0, 0),
4704 /* Find the most used value of an attribute. */
4706 static struct attr_value
*
4707 find_most_used (class attr_desc
*attr
)
4709 struct attr_value
*av
;
4710 struct attr_value
*most_used
;
4716 for (av
= attr
->first_value
; av
; av
= av
->next
)
4717 if (av
->num_insns
> nuses
)
4718 nuses
= av
->num_insns
, most_used
= av
;
4723 /* Return (attr_value "n") */
4726 make_numeric_value (int n
)
4728 static rtx int_values
[20];
4732 gcc_assert (n
>= 0);
4734 if (n
< 20 && int_values
[n
])
4735 return int_values
[n
];
4737 p
= attr_printf (MAX_DIGITS
, "%d", n
);
4738 exp
= attr_rtx (CONST_STRING
, p
);
4741 int_values
[n
] = exp
;
4747 copy_rtx_unchanging (rtx orig
)
4749 if (ATTR_IND_SIMPLIFIED_P (orig
) || ATTR_CURR_SIMPLIFIED_P (orig
))
4752 ATTR_CURR_SIMPLIFIED_P (orig
) = 1;
4756 /* Determine if an insn has a constant number of delay slots, i.e., the
4757 number of delay slots is not a function of the length of the insn. */
4760 write_const_num_delay_slots (FILE *outf
)
4762 class attr_desc
*attr
= find_attr (&num_delay_slots_str
, 0);
4763 struct attr_value
*av
;
4767 fprintf (outf
, "int\nconst_num_delay_slots (rtx_insn *insn)\n");
4768 fprintf (outf
, "{\n");
4769 fprintf (outf
, " switch (recog_memoized (insn))\n");
4770 fprintf (outf
, " {\n");
4772 for (av
= attr
->first_value
; av
; av
= av
->next
)
4775 walk_attr_value (av
->value
);
4777 write_insn_cases (outf
, av
->first_insn
, 4);
4780 fprintf (outf
, " default:\n");
4781 fprintf (outf
, " return 1;\n");
4782 fprintf (outf
, " }\n}\n\n");
4786 /* Synthetic attributes used by insn-automata.c and the scheduler.
4787 These are primarily concerned with (define_insn_reservation)
4792 struct insn_reserv
*next
;
4795 int default_latency
;
4798 /* Sequence number of this insn. */
4801 /* Whether a (define_bypass) construct names this insn in its
4806 static struct insn_reserv
*all_insn_reservs
= 0;
4807 static struct insn_reserv
**last_insn_reserv_p
= &all_insn_reservs
;
4808 static size_t n_insn_reservs
;
4810 /* Store information from a DEFINE_INSN_RESERVATION for future
4811 attribute generation. */
4813 gen_insn_reserv (md_rtx_info
*info
)
4815 struct insn_reserv
*decl
= oballoc (struct insn_reserv
);
4816 rtx def
= info
->def
;
4818 class attr_desc attr
= { };
4820 attr
.name
= DEF_ATTR_STRING (XSTR (def
, 0));
4821 attr
.loc
= info
->loc
;
4823 decl
->name
= DEF_ATTR_STRING (XSTR (def
, 0));
4824 decl
->default_latency
= XINT (def
, 1);
4825 decl
->condexp
= check_attr_test (info
->loc
, XEXP (def
, 2), &attr
);
4826 decl
->insn_num
= n_insn_reservs
;
4827 decl
->bypassed
= false;
4830 *last_insn_reserv_p
= decl
;
4831 last_insn_reserv_p
= &decl
->next
;
4835 /* Store information from a DEFINE_BYPASS for future attribute
4836 generation. The only thing we care about is the list of output
4837 insns, which will later be used to tag reservation structures with
4838 a 'bypassed' bit. */
4842 struct bypass_list
*next
;
4843 const char *pattern
;
4846 static struct bypass_list
*all_bypasses
;
4847 static size_t n_bypasses
;
4848 static size_t n_bypassed
;
4851 gen_bypass_1 (const char *s
, size_t len
)
4853 struct bypass_list
*b
;
4858 s
= attr_string (s
, len
);
4859 for (b
= all_bypasses
; b
; b
= b
->next
)
4860 if (s
== b
->pattern
)
4861 return; /* already got that one */
4863 b
= oballoc (struct bypass_list
);
4865 b
->next
= all_bypasses
;
4871 gen_bypass (md_rtx_info
*info
)
4873 const char *p
, *base
;
4875 rtx def
= info
->def
;
4876 for (p
= base
= XSTR (def
, 1); *p
; p
++)
4879 gen_bypass_1 (base
, p
- base
);
4882 while (ISSPACE (*p
));
4885 gen_bypass_1 (base
, p
- base
);
4888 /* Find and mark all of the bypassed insns. */
4890 process_bypasses (void)
4892 struct bypass_list
*b
;
4893 struct insn_reserv
*r
;
4897 /* The reservation list is likely to be much longer than the bypass
4899 for (r
= all_insn_reservs
; r
; r
= r
->next
)
4900 for (b
= all_bypasses
; b
; b
= b
->next
)
4901 if (fnmatch (b
->pattern
, r
->name
, 0) == 0)
4909 /* Check that attribute NAME is used in define_insn_reservation condition
4910 EXP. Return true if it is. */
4912 check_tune_attr (const char *name
, rtx exp
)
4914 switch (GET_CODE (exp
))
4917 if (check_tune_attr (name
, XEXP (exp
, 0)))
4919 return check_tune_attr (name
, XEXP (exp
, 1));
4922 return (check_tune_attr (name
, XEXP (exp
, 0))
4923 && check_tune_attr (name
, XEXP (exp
, 1)));
4926 return XSTR (exp
, 0) == name
;
4933 /* Try to find a const attribute (usually cpu or tune) that is used
4934 in all define_insn_reservation conditions. */
4935 static class attr_desc
*
4936 find_tune_attr (rtx exp
)
4938 class attr_desc
*attr
;
4940 switch (GET_CODE (exp
))
4944 attr
= find_tune_attr (XEXP (exp
, 0));
4947 return find_tune_attr (XEXP (exp
, 1));
4950 if (XSTR (exp
, 0) == alternative_name
)
4953 attr
= find_attr (&XSTR (exp
, 0), 0);
4956 if (attr
->is_const
&& !attr
->is_special
)
4958 struct insn_reserv
*decl
;
4960 for (decl
= all_insn_reservs
; decl
; decl
= decl
->next
)
4961 if (! check_tune_attr (attr
->name
, decl
->condexp
))
4972 /* Create all of the attributes that describe automaton properties.
4973 Write the DFA and latency function prototypes to the files that
4974 need to have them, and write the init_sched_attrs(). */
4977 make_automaton_attrs (void)
4980 struct insn_reserv
*decl
;
4981 rtx code_exp
, lats_exp
, byps_exp
;
4982 class attr_desc
*tune_attr
;
4984 if (n_insn_reservs
== 0)
4987 tune_attr
= find_tune_attr (all_insn_reservs
->condexp
);
4988 if (tune_attr
!= NULL
)
4990 rtx
*condexps
= XNEWVEC (rtx
, n_insn_reservs
* 3);
4991 struct attr_value
*val
;
4994 gcc_assert (tune_attr
->is_const
4995 && !tune_attr
->is_special
4996 && !tune_attr
->is_numeric
);
4998 /* Write the prototypes for all DFA functions. */
4999 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
5001 if (val
== tune_attr
->default_val
)
5003 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
5005 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n",
5006 XSTR (val
->value
, 0));
5008 fprintf (dfa_file
, "\n");
5010 /* Write the prototypes for all latency functions. */
5011 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
5013 if (val
== tune_attr
->default_val
)
5015 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
5016 fprintf (latency_file
,
5017 "extern int insn_default_latency_%s (rtx_insn *);\n",
5018 XSTR (val
->value
, 0));
5020 fprintf (latency_file
, "\n");
5022 /* Write the prototypes for all automaton functions. */
5023 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
5025 if (val
== tune_attr
->default_val
)
5027 gcc_assert (GET_CODE (val
->value
) == CONST_STRING
);
5029 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n"
5030 "extern int insn_default_latency_%s (rtx_insn *);\n",
5031 XSTR (val
->value
, 0), XSTR (val
->value
, 0));
5033 fprintf (attr_file
, "\n");
5034 fprintf (attr_file
, "int (*internal_dfa_insn_code) (rtx_insn *);\n");
5035 fprintf (attr_file
, "int (*insn_default_latency) (rtx_insn *);\n");
5036 fprintf (attr_file
, "\n");
5037 fprintf (attr_file
, "void\n");
5038 fprintf (attr_file
, "init_sched_attrs (void)\n");
5039 fprintf (attr_file
, "{\n");
5041 for (val
= tune_attr
->first_value
; val
; val
= val
->next
)
5045 rtx test
= attr_eq (tune_attr
->name
, XSTR (val
->value
, 0));
5047 if (val
== tune_attr
->default_val
)
5049 for (decl
= all_insn_reservs
, i
= 0;
5055 = simplify_and_tree (decl
->condexp
, &ctest
, -2, 0);
5056 if (condexp
== false_rtx
)
5058 if (condexp
== true_rtx
)
5060 condexps
[i
] = condexp
;
5061 condexps
[i
+ 1] = make_numeric_value (decl
->insn_num
);
5062 condexps
[i
+ 2] = make_numeric_value (decl
->default_latency
);
5066 code_exp
= rtx_alloc (COND
);
5067 lats_exp
= rtx_alloc (COND
);
5070 XVEC (code_exp
, 0) = rtvec_alloc (j
);
5071 XVEC (lats_exp
, 0) = rtvec_alloc (j
);
5075 XEXP (code_exp
, 1) = make_numeric_value (decl
->insn_num
);
5076 XEXP (lats_exp
, 1) = make_numeric_value (decl
->default_latency
);
5080 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5081 XEXP (lats_exp
, 1) = make_numeric_value (0);
5088 XVECEXP (code_exp
, 0, j
) = condexps
[i
];
5089 XVECEXP (lats_exp
, 0, j
) = condexps
[i
];
5091 XVECEXP (code_exp
, 0, j
+ 1) = condexps
[i
+ 1];
5092 XVECEXP (lats_exp
, 0, j
+ 1) = condexps
[i
+ 2];
5095 name
= XNEWVEC (char,
5096 sizeof ("*internal_dfa_insn_code_")
5097 + strlen (XSTR (val
->value
, 0)));
5098 strcpy (name
, "*internal_dfa_insn_code_");
5099 strcat (name
, XSTR (val
->value
, 0));
5100 make_internal_attr (name
, code_exp
, ATTR_NONE
);
5101 strcpy (name
, "*insn_default_latency_");
5102 strcat (name
, XSTR (val
->value
, 0));
5103 make_internal_attr (name
, lats_exp
, ATTR_NONE
);
5108 fprintf (attr_file
, " if (");
5112 fprintf (attr_file
, " else if (");
5113 write_test_expr (attr_file
, test
, 0, 0);
5114 fprintf (attr_file
, ")\n");
5115 fprintf (attr_file
, " {\n");
5116 fprintf (attr_file
, " internal_dfa_insn_code\n");
5117 fprintf (attr_file
, " = internal_dfa_insn_code_%s;\n",
5118 XSTR (val
->value
, 0));
5119 fprintf (attr_file
, " insn_default_latency\n");
5120 fprintf (attr_file
, " = insn_default_latency_%s;\n",
5121 XSTR (val
->value
, 0));
5122 fprintf (attr_file
, " }\n");
5125 fprintf (attr_file
, " else\n");
5126 fprintf (attr_file
, " gcc_unreachable ();\n");
5127 fprintf (attr_file
, "}\n");
5128 fprintf (attr_file
, "\n");
5130 XDELETEVEC (condexps
);
5134 code_exp
= rtx_alloc (COND
);
5135 lats_exp
= rtx_alloc (COND
);
5137 XVEC (code_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5138 XVEC (lats_exp
, 0) = rtvec_alloc (n_insn_reservs
* 2);
5140 XEXP (code_exp
, 1) = make_numeric_value (n_insn_reservs
+ 1);
5141 XEXP (lats_exp
, 1) = make_numeric_value (0);
5143 for (decl
= all_insn_reservs
, i
= 0;
5145 decl
= decl
->next
, i
+= 2)
5147 XVECEXP (code_exp
, 0, i
) = decl
->condexp
;
5148 XVECEXP (lats_exp
, 0, i
) = decl
->condexp
;
5150 XVECEXP (code_exp
, 0, i
+1) = make_numeric_value (decl
->insn_num
);
5151 XVECEXP (lats_exp
, 0, i
+1)
5152 = make_numeric_value (decl
->default_latency
);
5154 make_internal_attr ("*internal_dfa_insn_code", code_exp
, ATTR_NONE
);
5155 make_internal_attr ("*insn_default_latency", lats_exp
, ATTR_NONE
);
5158 if (n_bypasses
== 0)
5159 byps_exp
= make_numeric_value (0);
5162 process_bypasses ();
5164 byps_exp
= rtx_alloc (COND
);
5165 XVEC (byps_exp
, 0) = rtvec_alloc (n_bypassed
* 2);
5166 XEXP (byps_exp
, 1) = make_numeric_value (0);
5167 for (decl
= all_insn_reservs
, i
= 0;
5172 XVECEXP (byps_exp
, 0, i
) = decl
->condexp
;
5173 XVECEXP (byps_exp
, 0, i
+1) = make_numeric_value (1);
5178 make_internal_attr ("*bypass_p", byps_exp
, ATTR_NONE
);
5182 write_header (FILE *outf
)
5184 fprintf (outf
, "/* Generated automatically by the program `genattrtab'\n"
5185 " from the machine description file `md'. */\n\n");
5187 fprintf (outf
, "#define IN_TARGET_CODE 1\n");
5188 fprintf (outf
, "#include \"config.h\"\n");
5189 fprintf (outf
, "#include \"system.h\"\n");
5190 fprintf (outf
, "#include \"coretypes.h\"\n");
5191 fprintf (outf
, "#include \"backend.h\"\n");
5192 fprintf (outf
, "#include \"predict.h\"\n");
5193 fprintf (outf
, "#include \"tree.h\"\n");
5194 fprintf (outf
, "#include \"rtl.h\"\n");
5195 fprintf (outf
, "#include \"alias.h\"\n");
5196 fprintf (outf
, "#include \"options.h\"\n");
5197 fprintf (outf
, "#include \"varasm.h\"\n");
5198 fprintf (outf
, "#include \"stor-layout.h\"\n");
5199 fprintf (outf
, "#include \"calls.h\"\n");
5200 fprintf (outf
, "#include \"insn-attr.h\"\n");
5201 fprintf (outf
, "#include \"memmodel.h\"\n");
5202 fprintf (outf
, "#include \"tm_p.h\"\n");
5203 fprintf (outf
, "#include \"insn-config.h\"\n");
5204 fprintf (outf
, "#include \"recog.h\"\n");
5205 fprintf (outf
, "#include \"regs.h\"\n");
5206 fprintf (outf
, "#include \"real.h\"\n");
5207 fprintf (outf
, "#include \"output.h\"\n");
5208 fprintf (outf
, "#include \"toplev.h\"\n");
5209 fprintf (outf
, "#include \"flags.h\"\n");
5210 fprintf (outf
, "#include \"emit-rtl.h\"\n");
5211 fprintf (outf
, "\n");
5212 fprintf (outf
, "#define operands recog_data.operand\n\n");
5216 open_outfile (const char *file_name
)
5219 outf
= fopen (file_name
, "w");
5221 fatal ("cannot open file %s: %s", file_name
, xstrerror (errno
));
5222 write_header (outf
);
5227 handle_arg (const char *arg
)
5232 attr_file_name
= &arg
[2];
5235 dfa_file_name
= &arg
[2];
5238 latency_file_name
= &arg
[2];
5246 main (int argc
, const char **argv
)
5248 class attr_desc
*attr
;
5252 progname
= "genattrtab";
5254 if (!init_rtx_reader_args_cb (argc
, argv
, handle_arg
))
5255 return FATAL_EXIT_CODE
;
5257 attr_file
= open_outfile (attr_file_name
);
5258 dfa_file
= open_outfile (dfa_file_name
);
5259 latency_file
= open_outfile (latency_file_name
);
5261 obstack_init (hash_obstack
);
5262 obstack_init (temp_obstack
);
5264 /* Set up true and false rtx's */
5265 true_rtx
= rtx_alloc (CONST_INT
);
5266 XWINT (true_rtx
, 0) = 1;
5267 false_rtx
= rtx_alloc (CONST_INT
);
5268 XWINT (false_rtx
, 0) = 0;
5269 ATTR_IND_SIMPLIFIED_P (true_rtx
) = ATTR_IND_SIMPLIFIED_P (false_rtx
) = 1;
5270 ATTR_PERMANENT_P (true_rtx
) = ATTR_PERMANENT_P (false_rtx
) = 1;
5272 alternative_name
= DEF_ATTR_STRING ("alternative");
5273 length_str
= DEF_ATTR_STRING ("length");
5274 delay_type_str
= DEF_ATTR_STRING ("*delay_type");
5275 delay_1_0_str
= DEF_ATTR_STRING ("*delay_1_0");
5276 num_delay_slots_str
= DEF_ATTR_STRING ("*num_delay_slots");
5278 /* Read the machine description. */
5281 while (read_md_rtx (&info
))
5283 switch (GET_CODE (info
.def
))
5286 case DEFINE_PEEPHOLE
:
5287 case DEFINE_ASM_ATTRIBUTES
:
5292 case DEFINE_ENUM_ATTR
:
5300 case DEFINE_INSN_RESERVATION
:
5301 gen_insn_reserv (&info
);
5311 if (GET_CODE (info
.def
) != DEFINE_ASM_ATTRIBUTES
)
5312 insn_index_number
++;
5316 return FATAL_EXIT_CODE
;
5318 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */
5319 if (! got_define_asm_attributes
)
5322 info
.def
= rtx_alloc (DEFINE_ASM_ATTRIBUTES
);
5323 XVEC (info
.def
, 0) = rtvec_alloc (0);
5324 info
.loc
= file_location ("<internal>", 0, 0);
5329 /* Expand DEFINE_DELAY information into new attribute. */
5332 /* Make `insn_alternatives'. */
5333 int num_insn_codes
= get_num_insn_codes ();
5334 insn_alternatives
= oballocvec (alternative_mask
, num_insn_codes
);
5335 for (id
= defs
; id
; id
= id
->next
)
5336 if (id
->insn_code
>= 0)
5337 insn_alternatives
[id
->insn_code
]
5338 = (((alternative_mask
) 1) << id
->num_alternatives
) - 1;
5340 /* Make `insn_n_alternatives'. */
5341 insn_n_alternatives
= oballocvec (int, num_insn_codes
);
5342 for (id
= defs
; id
; id
= id
->next
)
5343 if (id
->insn_code
>= 0)
5344 insn_n_alternatives
[id
->insn_code
] = id
->num_alternatives
;
5346 /* Construct extra attributes for automata. */
5347 make_automaton_attrs ();
5349 /* Prepare to write out attribute subroutines by checking everything stored
5350 away and building the attribute cases. */
5354 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5355 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5356 attr
->default_val
->value
5357 = check_attr_value (attr
->loc
, attr
->default_val
->value
, attr
);
5360 return FATAL_EXIT_CODE
;
5362 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5363 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5366 /* Construct extra attributes for `length'. */
5367 make_length_attrs ();
5369 /* Perform any possible optimizations to speed up compilation. */
5370 optimize_attrs (num_insn_codes
);
5372 /* Now write out all the `gen_attr_...' routines. Do these before the
5373 special routines so that they get defined before they are used. */
5375 for (i
= 0; i
< MAX_ATTRS_INDEX
; i
++)
5376 for (attr
= attrs
[i
]; attr
; attr
= attr
->next
)
5380 #define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X)))
5381 if (IS_ATTR_GROUP ("*internal_dfa_insn_code"))
5383 else if (IS_ATTR_GROUP ("*insn_default_latency"))
5384 outf
= latency_file
;
5387 #undef IS_ATTR_GROUP
5389 if (! attr
->is_special
&& ! attr
->is_const
)
5390 write_attr_get (outf
, attr
);
5393 /* Write out delay eligibility information, if DEFINE_DELAY present.
5394 (The function to compute the number of delay slots will be written
5396 write_eligible_delay (attr_file
, "delay");
5397 if (have_annul_true
)
5398 write_eligible_delay (attr_file
, "annul_true");
5400 write_dummy_eligible_delay (attr_file
, "annul_true");
5401 if (have_annul_false
)
5402 write_eligible_delay (attr_file
, "annul_false");
5404 write_dummy_eligible_delay (attr_file
, "annul_false");
5406 /* Write out constant delay slot info. */
5407 write_const_num_delay_slots (attr_file
);
5409 write_length_unit_log (attr_file
);
5411 if (fclose (attr_file
) != 0)
5412 fatal ("cannot close file %s: %s", attr_file_name
, xstrerror (errno
));
5413 if (fclose (dfa_file
) != 0)
5414 fatal ("cannot close file %s: %s", dfa_file_name
, xstrerror (errno
));
5415 if (fclose (latency_file
) != 0)
5416 fatal ("cannot close file %s: %s", latency_file_name
, xstrerror (errno
));
5418 return SUCCESS_EXIT_CODE
;